如何在Tomcat上运行的servlet过滤器中使用HttpServletRequest#getParts()?

Nir*_*oon 10 tomcat servlets file-upload servlet-filters

我想在我的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);
    }
Run Code Online (Sandbox Code Playgroud)

但是,getParts()返回一个空集合.如何multipart/form-data在Tomcat 7.0.8中的servlet过滤器中启用解析?

Bal*_*usC 29

为了得到HttpServletRequest#getParts()一个工作Filter在Tomcat中,您需要设置allowCasualMultipartParsing="true"在webapp的<Context>元素Webapp/META-INF/context.xml或Tomcat/conf/server.xml.

<Context ... allowCasualMultipartParsing="true">
Run Code Online (Sandbox Code Playgroud)

因为根据servlet 3.0规范,HttpServletRequest#getParts()只应在HttpServlet带有@MultipartConfig注释的a中使用.另请参阅<Context>元素的文档:

allowCasualMultipartParsing

设置为true如果Tomcat应该自动解析multipart/form-data请求时机构HttpServletRequest.getPart*或HttpServletRequest.getParameter*被调用时,即使当目标servlet不是标有@MultipartConfig注解(参见Servlet规范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)});
Run Code Online (Sandbox Code Playgroud)

首先,您不尊重客户端指定的字符编码 - 如果有的话.其次,二进制文件会失败.