gpt4 book ai didi

java - 在奇怪的情况下,多部分配置不适用于动态添加的 servlet

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:55:55 27 4
gpt4 key购买 nike

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

最佳答案

我能够使用 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。

关于java - 在奇怪的情况下,多部分配置不适用于动态添加的 servlet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19297400/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com