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>
Servlet:
@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" );
}
}
}
Filter
@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() {}
}
Listener
@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
);
}
}
My 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>
When I submit the form I receive the output "IT IS NOT WORKING!" in the first line of the response. If I change the requested path from /{insert your context here}/p/hello
to /{insert your context here}/hello
it works, why?
Using:
JBoss EAP 6.1
I was able to reproduce the problem with Tomcat 7.0.30. The same problem was present whether I configured the "HelloServlet" dynamically or statically, using a @MultipartConfig
annotation.
I also tested on Jetty version 8.1.13.v20130916, and it worked fine in both cases; /{context}/p/hello
and /{context}/hello
, without any modifications.
If you were to modify your HelloListener
like this:
Dynamic hello = context.addServlet( "hello", HelloServlet.class );
hello.addMapping( "/hello" );
hello.addMapping( "/p/hello" );
hello.setMultipartConfig( getMultiPartConfig() );
it would work, but I suspect that defeats the purpose of what you are trying to do. Another option would be to modify your filter to add new mappings dynamically as required:
@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);
}
It seems like tomcat/jboss is only enabling multipart support for the request based on whether or not the original request path matches one of the servlets configured for multipart support, whereas it should be enabling support based on the path of the request it is currently handling (which might have been "included" by the RequestDispatcher.
It does seem like a tomcat/jboss bug, but you'd have to carefully read the servlet spec to find out, otherwise you could use Jetty instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With