Как использовать 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?

2 ответа

Решение

Чтобы получить HttpServletRequest#getParts() работать в Filter в Tomcat нужно установить allowCasualMultipartParsing="true" в веб-приложении <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)});

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

Также попробуйте фильтр 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>
Другие вопросы по тегам