2010-07-26 11 views
54

¿Hay alguna manera conveniente de leer y analizar datos de la solicitud entrante.Manera conveniente de analizar los parámetros entrantes multipart/form-data en un servlet

cliente por ejemplo iniciado solicitud POST

URLConnection connection = new URL(url).openConnection(); 
connection.setDoOutput(true); 
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); 
PrintWriter writer = null; 
try { 
    OutputStream output = connection.getOutputStream(); 
    writer = new PrintWriter(new OutputStreamWriter(output, charset), true); // true = autoFlush, important! 
    // Send normal param. 
    writer.println("--" + boundary); 
    writer.println("Content-Disposition: form-data; name=\"param\""); 
    writer.println("Content-Type: text/plain; charset=" + charset); 
    writer.println(); 
    writer.println(param); 

No soy capaz de conseguir parámetro utilizando request.getParameter("paramName"). El siguiente código

BufferedReader reader = new BufferedReader(new InputStreamReader(
    request.getInputStream())); 
    StringBuilder sb = new StringBuilder(); 
    for (String line; (line = reader.readLine()) != null;) { 
    System.out.println(line); 

    } 

sin embargo muestra el contenido para mí

-----------------------------29772313742745 
Content-Disposition: form-data; name="name" 
J.Doe 
-----------------------------29772313742745 
Content-Disposition: form-data; name="email" 
[email protected] 
-----------------------------29772313742745 

¿Cuál es la mejor manera de analizar la petición entrante? No quiero escribir mi propio analizador, probablemente haya una solución lista.

Respuesta

71

multipart/form-data las solicitudes codificadas de hecho no son compatibles por defecto con la API de Servlet antes de la versión 3.0. La API de Servlet analiza los parámetros de forma predeterminada mediante la codificación application/x-www-form-urlencoded. Al usar una codificación diferente, las llamadas request.getParameter() devolverán null. Cuando ya está en Servlet 3.0 (Glassfish 3, Tomcat 7, etc.), puede usar HttpServletRequest#getParts() en su lugar. También vea this blog para ejemplos extendidos.

Antes de Servlet 3.0, un estándar de facto para analizar las solicitudes multipart/form-data usaría Apache Commons FileUpload. Simplemente lea detenidamente su Guía del usuario y Preguntas frecuentes secciones para aprender a usarlo. He publicado una respuesta con un ejemplo de código antes de here (también contiene un ejemplo que se dirige a Servlet 3.0).

+1

Cuidado. Parte de la documentación en el sitio de apache es incorrecta. Por ejemplo, dicen que puede llamar a setRepository() en un objeto FileItemFactory que es falso porque cualquier Objeto que implemente FileItemFactory tiene solo un método: createItem(). Así que asegúrese de leer los javadocs también. – Cheruvim

+1

'getParts()' siempre devuelve cero elementos. ¿Por qué es tan difícil recuperar formularios multiparte en Java y Servlet 3.0? No puedo creerlo! – basZero

+0

@basZero: la respuesta a la pregunta duplicada ya explica cuándo estaría vacía. – BalusC

16

Soluciones:

Solución A:

  1. Descargar http://www.servlets.com/cos/index.html
  2. invocación getParameters() en com.oreilly.servlet.MultipartRequest

Solución B:

  1. de Down carga http://jakarta.Apache.org/commons/fileupload/
  2. invocación readHeaders() en org.apache.commons.fileupload.MultipartStream

Solución C:

  1. Descargar http://users.boone.net/wbrameld/multipartformdata/
  2. invocación getParameter en com.bigfoot.bugar.servlet.http.MultipartFormData

Solución D:

Utilice Struts. Struts 1.1 maneja esto automáticamente.

Referencia: http://www.jguru.com/faq/view.jsp?EID=1045507

+4

Por favor, ponga algunas soluciones, ya que estos enlaces pueden quedar obsoletos en cualquier momento en el futuro. Esto atraerá una calificación negativa. –

2

No siempre hay un servlet antes de un proceso de carga (que podría utilizar un filtro, por ejemplo). O podría ser que el mismo controlador (de nuevo un filtro o también un servelt) puede servir para muchas acciones, así que creo que confío en esa configuración de servlet para usar el método getPart (solo para Servlet API> = 3.0), no lo hago Sabes, no me gusta

En general, prefiero soluciones independientes, capaz de vivir solo, y en este caso http://commons.apache.org/proper/commons-fileupload/ es uno de eso.

List<FileItem> multiparts = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request); 
    for (FileItem item : multiparts) { 
     if (!item.isFormField()) { 
      //your operations on file 
     } else { 
      String name = item.getFieldName(); 
      String value = item.getString(); 
      //you operations on paramters 
     } 
} 
Cuestiones relacionadas