Как использовать HttpServletRequest # getParts() в фильтрах сервлетов, запущенных на Tomcat?

Я хотел бы загрузить файл в моем приложении JSF. Я использую Filter и HttpServletRequestWrapper для доступа к файлу загрузки.

 public MultipartRequestWrapper(HttpServletRequest request) {
    super(request);
    System.out.println("Created multipart wrapper....");
    try {
        System.out.println("Looping parts"+getParts().size());

        for (Part p : getParts()) {
            System.out.println(String.format("Part name: %1$s, contentType : %2$s", p.getName(), p.getContentType()));
            for(String header : p.getHeaderNames()){
                System.out.println("Header name : " + header + ", value : " + p.getHeader(header));
            }
            byte[] b = new byte[(int) p.getSize()];
            p.getInputStream().read(b);
            params.put(p.getName(), new String[]{new String(b)});
        }
    } catch (IOException ex) {
        ex.printStackTrace();
        Logger.getLogger(MultipartRequestWrapper.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ServletException ex) {
         ex.printStackTrace();
        Logger.getLogger(MultipartRequestWrapper.class.getName()).log(Level.SEVERE, null, ex);
    }

Однако getParts() возвращает пустую коллекцию. Как включить синтаксический анализ multipart/form-data в сервлет-фильтре в Tomcat 7.0.8?

Ответ 1

Чтобы получить HttpServletRequest#getParts() для работы в Filter в Tomcat, вам нужно установить allowCasualMultipartParsing="true" в элемент webapp <Context> в Webapp/META-INF/context.xml или Tomcat/conf/server.xml.

<Context ... allowCasualMultipartParsing="true">

Поскольку в соответствии со спецификацией сервлета 3.0 HttpServletRequest#getParts() должен быть доступен только внутри HttpServlet с аннотацией @MultipartConfig. См. Также документацию <Context>:

allowCasualMultipartParsing

Установите true, если Tomcat должен автоматически анализировать тела multipart/form-data, когда вызываются HttpServletRequest.getPart* или HttpServletRequest.getParameter*, даже если целевой сервлет не помечен аннотацией @MultipartConfig (см. Спецификация сервлета 3.0, Раздел 3.2). Обратите внимание, что любая настройка, отличная от false, заставляет Tomcat вести себя так, что это не соответствует техническим требованиям. По умолчанию используется false.

См. также:


Несвязанный для конкретной проблемы, следующее, безусловно, неверно:

byte[] b = new byte[(int) p.getSize()];
p.getInputStream().read(b);
params.put(p.getName(), new String[]{new String(b)});

Во-первых, вы не соблюдаете кодировку символов, указанную клиентом, - если угодно. Во-вторых, это приведет к сбою двоичных файлов.

Ответ 2

Также попробуйте файл Multipart. работал на меня.

<filter>
    <filter-name>MultipartFilter</filter-name>
    <filter-class>org.eclipse.jetty.servlets.MultiPartFilter</filter-class>
</filter> 
<filter-mapping>
    <filter-name>MultipartFilter</filter-name>
    <servlet-name>CamelServlet</servlet-name> 
</filter-mapping>