2011-09-16 8 views
6

TEMPORAL resuelto:InputStream closed in Apache FileUpload API¿Cómo puedo leer el contenido del encabezado de disposición de contenido?


quiero leer el contenido de la cabecera Content-Disposition pero request.getHeader ("content-disposition") siempre vuelven nulos y request.getHeader ("content-type") sólo se devuelve la primera línea, como este multipart/form-data; boundary=AaB03x.

supose recibo el siguiente encabezado:

Content-Type: multipart/form-data; boundary=AaB03x 

--AaB03x 
Content-Disposition: form-data; name="submit-name" 

Larry 
--AaB03x 
Content-Disposition: form-data; name="files"; filename="file1.txt" 
Content-Type: text/plain 

... contents of file1.txt ... 
--AaB03x-- 

quiero leer todas las cabeceras Content-Disposition. ¿Cómo?

Gracias.


EDIT1: Lo que realmente deseo de resolver el problema es cuando el cliente envía un archivo que supera el tamaño máximo, ya que cuando se llama a request.getPart ("algo") no importa qué parte nombre que le pasa porque siempre lanzará una IllegalStateException incluso si la solicitud no contiene este nombre de parámetro.

Ejemplo:

Part part = request.getPart ("param"); 
String value = getValue (part); 
if (value.equals ("1")){ 
    doSomethingWithFile1 (request.getPart ("file1")) 
}else if (value.equals (2)){ 
    doSomethingWithFile2 (request.getPart ("file2")) 
} 

private String getValue (Part part) throws IOException{ 
    if (part == null) return null; 

    BufferedReader in = null; 
    try{ 
     in = new BufferedReader (new InputStreamReader (part.getInputStream(), request.getCharacterEncoding())); 
    }catch (UnsupportedEncodingException e){} 

    StringBuilder value = new StringBuilder(); 
    char[] buffer = new char[1024]; 
    for (int bytesRead; (bytesRead = in.read (buffer)) != -1;) { 
     value.append (buffer, 0, bytesRead); 
    } 

    return value.toString(); 
} 

no puedo hacer esto porque si el cliente envía un archivo que supera el tamaño máximo de la primera llamada a getPart lanzará la excepción (ver getPart() Javadoc), por lo que no puede saber qué archivo he recibido

Es por eso que quiero leer los encabezados de disposición de contenido. Quiero leer el parámetro "param" para saber qué archivo ha arrojado la excepción.


Edit2: Bueno, con la API que publica la especificación Servlet 3.0 que no puede controlar el caso anterior, porque si un archivo se produce una excepción no se puede leer el nombre del campo de archivos. Esta es la parte negativa del uso de un contenedor porque muchas funcionalidades desaparecen ... También con FileUpload puede establecer dinámicamente la anotación MultipartConfig.

Si el archivo excede el tamaño máximo de archivo, la API arroja una excepción FileSizeLimitExceededException. La excepción proporciona 2 métodos para obtener el nombre del campo y el nombre del archivo.

Pero !! mi problema aún no está resuelto porque Quiero leer el valor de otro parámetro enviado junto con el archivo en la misma forma. (el valor de "parámetro" en el ejemplo anterior)


Edit3: Estoy trabajando en esto. ¡Tan pronto como escriba el código lo publicaré aquí!

+0

No es un duplicado. –

Respuesta

5

request.getHeader ("content-disposition") devolverá nulo en su caso, ya que los encabezados Content-Disposition aparecen en el cuerpo HTTP POST, lo que requiere que se traten por separado. De hecho, Content-Disposition es solo un encabezado de respuesta HTTP válido. Como parte de una solicitud, nunca se tratará como un encabezado.

Será mejor que utilice una biblioteca de carga de archivos como Commons FileUpload o las funciones integradas de carga de archivos del Servlet Spec 3.0 para leer el encabezado Content-Disposition (indirectamente). Los contenedores Java EE 6 que se requieren para implementar la funcionalidad de carga de archivos requerida de Servlet Spec 3.0, a menudo usan Apache Commons FileUpload bajo el capó.

Si desea ignorar estas bibliotecas, por alguna razón válida y en lugar de leer los encabezados de ti mismo, entonces recomiendo mirar los parseHeaderLine y getParsedHeaders métodos de la clase FileUploadBase de Apache Commons FileUpload. Tenga en cuenta que estos métodos realmente leen desde InputStream asociado con HttpServletRequest, y no puede leer la secuencia dos veces. Si primero desea leer el encabezado Content-Disposition en su código y luego utilizar Apache Commons FileUpload para analizar la solicitud, deberá pasar un ServletRequestWrapper que envuelve una copia si la solicitud original a la API de FileUpload. La secuencia inversa también requiere que cree una copia de la solicitud original y pase un ServletRequestWrapper envolviendo esta copia en la API FileUpload. En general, este es un diseño pobre, ya que no tiene sentido replicar un flujo completo en la memoria (o en el disco) solo para leer el cuerpo de la solicitud dos veces.

+0

He editado la pregunta con una explicación completa. –

1

intenta utilizar part.getName()

Este es un ejemplo.

archivo HTML:

<form action="UploadServlet" method="post" enctype="multipart/form-data"> 
    <input type="text" value="phu" name="info"> 
    <input type="file" name="file1"/> <input type="submit"/> 
</form> 

Servlet:

String field; 

for (Part part : request.getParts()) { 
    field = part.getName(); 
    if (field.equals("info")) { 
     // Your code here 
    } else if (field.equals("file1")) { 
     // Your code here 
    } 
} 
+0

Advertencia: Esto solo funciona para un contenedor que cumpla con las especificaciones de Servlet 3.0 (p. Ej., No ciertas versiones de Jetty incrustado). –

Cuestiones relacionadas