8

jsp:

<!DOCTYPE html>
<form action="/{insert your context here}/p/hello" method="post" enctype="multipart/form-data">
  <input type="file" name="data">
  <button>Go</button>
</form>

小服务程序:

@WebServlet
public class HelloServlet extends HttpServlet {
    private static final long serialVersionUID = 1;
    @Override
    protected void doPost( HttpServletRequest request, HttpServletResponse response )
    throws IOException, ServletException {
        if ( request.getPart( "data" ) != null ) {
            response.getWriter().print( "It worked\n\n" );
        } else {
            response.getWriter().print( "IT IS NOT WORKING!\n\n" );
        }
    }
}

筛选

@WebFilter( filterName = "hello" )
public class HelloFilter implements Filter {
    @Override
    public void init( FilterConfig config ) throws ServletException {}

    @Override
    public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain )
    throws IOException, ServletException {
        request
            .getRequestDispatcher( "/hello" )
            .include( request, response );

        request
            .getRequestDispatcher( "/hello.jsp" )
            .include( request, response );
    }

    @Override
    public void destroy() {}
}

听众

@WebListener
public class HelloListener implements ServletContextListener {
    @Override
    public void contextInitialized( ServletContextEvent event ) {
        ServletContext context = event.getServletContext();
        Dynamic hello = context.addServlet( "hello", HelloServlet.class );
        hello.addMapping( "/hello" );
        hello.setMultipartConfig( getMultiPartConfig() );
    }
    @Override
    public void contextDestroyed( ServletContextEvent event ) {}

    private MultipartConfigElement getMultiPartConfig() {
        String location = "";
        long maxFileSize = -1;
        long maxRequestSize = -1;
        int fileSizeThreshold = 0;
        return new MultipartConfigElement(
            location,
            maxFileSize,
            maxRequestSize,
            fileSizeThreshold
        );
    }
}

我的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>{insert the context here}</display-name>
  <jsp-config>
    <jsp-property-group>
      <url-pattern>*.jsp</url-pattern>
      <page-encoding>UTF-8</page-encoding>
    </jsp-property-group>
  </jsp-config>
  <filter-mapping>
    <filter-name>hello</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

当我提交表单时,我收到输出“它不工作!” 在响应的第一行。如果我将请求的路径从更改为/{insert your context here}/p/hello有效/{insert your context here}/hello,为什么?

使用:
JBoss EAP 6.1

4

2 回答 2

2

我能够重现 Tomcat 7.0.30 的问题。@MultipartConfig无论我使用注释动态或静态配置“HelloServlet”,都存在相同的问题。

我还在 Jetty 版本 8.1.13.v20130916 上进行了测试,在这两种情况下都运行良好;/{context}/p/hello并且/{context}/hello,没有任何修改。

如果您要这样修改HelloListener

Dynamic hello = context.addServlet( "hello", HelloServlet.class );
hello.addMapping( "/hello" );
hello.addMapping( "/p/hello" );
hello.setMultipartConfig( getMultiPartConfig() );

它会起作用,但我怀疑这会违背你想要做的事情的目的。另一种选择是修改您的过滤器以根据需要动态添加新映射:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {

    // dynamically add mappings
    ServletContext context = request.getServletContext();
    ServletRegistration registration = context.getServletRegistration("hello");
    registration.addMapping("/<dynamic path>/hello");

    request.getRequestDispatcher("/hello").include(request, response);
    request.getRequestDispatcher("/hello.jsp").include(request, response);
}

似乎 tomcat/jboss 仅根据原始请求路径是否与为多部分支持配置的 servlet 之一匹配来启用对请求的多部分支持,而它应该根据当前正在处理的请求的路径启用支持(可能已被 RequestDispatcher “包含”。

它看起来确实像一个 tomcat/jboss 错误,但您必须仔细阅读 servlet 规范才能找到答案,否则您可以使用 Jetty 代替。

于 2013-10-18T10:20:09.440 回答
0

我随机遇到了这个问题,同时你的困境可能是什么答案。鉴于提供的注释,该页面将通过 {insert your context here}/hello 而不是 {insert your context here}/p/hello 访问。查看Java EE 6 网页中的多个文件夹。它非常相似,BalusC 提供了一些很好的信息。希望有帮助。

于 2013-10-16T21:06:49.037 回答