Apache TomEE Plus 1.7.2中CORS过滤器启用失败求助
解决Apache TomEE Plus 1.7.2中的CORS配置问题
我来帮你排查下这个CORS配置失效的问题,TomEE 1.7.2基于Tomcat 7,但它的类加载机制和JAX-RS集成(默认用Apache CXF)有一些特殊点,咱们一步步来解决:
一、先排查全局Tomcat CorsFilter不生效的原因
你在Tomcat全局conf/web.xml里配置的CorsFilter可能没被TomEE正确加载——TomEE有自己的类加载层级,全局配置也容易被应用自身的WEB-INF/web.xml覆盖。试试把这个过滤器配置移到你的应用的WEB-INF/web.xml中,而不是放在全局的conf目录下。
另外,确认TomEE的lib目录里存在catalina.jar(里面包含org.apache.catalina.filters.CorsFilter类),TomEE 1.7.2应该自带这个文件,但如果有缺失的话需要补上。
二、修复JAX-RS手动过滤器的问题
你的手动过滤器没执行,大概率是两个原因导致的:
- OPTIONS预请求没被拦截:CORS预请求(OPTIONS)是关键环节,JAX-RS默认会自动处理OPTIONS请求,导致你的过滤器没机会执行。需要在
ContainerRequestFilter实现里手动拦截并处理OPTIONS请求:
@Override public void filter(ContainerRequestContext reqContext) throws IOException { System.out.println("-- req info --: " + reqContext); // 拦截OPTIONS预请求,直接返回空响应避免JAX-RS默认处理 if ("OPTIONS".equalsIgnoreCase(reqContext.getMethod())) { reqContext.abortWith(Response.ok().build()); } }
- 过滤器注册不彻底:虽然你在
ApplicationConfig的getClasses()里添加了过滤器,但TomEE的CXF实现可能需要额外配置。可以试试把过滤器直接放到addRestResourceClasses方法里,或者检查该方法有没有覆盖掉过滤器的注册。
修改后的完整过滤器代码:
package com.mycompany.webservicetest.two.rest.service; import java.io.IOException; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.core.Response; import javax.ws.rs.ext.Provider; @Provider public class CorsFilter implements ContainerResponseFilter, ContainerRequestFilter { @Override public void filter(ContainerRequestContext reqContext, ContainerResponseContext resContext) throws IOException { System.out.println("-- res info --"); System.out.println("!!!!!!!!!!!! ----------- Filter called!! "); resContext.getHeaders().add("Access-Control-Allow-Origin", "*"); resContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization, X-Requested-With, Access-Control-Request-Method, Access-Control-Request-Headers"); resContext.getHeaders().add("Access-Control-Allow-Credentials", "true"); resContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); resContext.getHeaders().add("Access-Control-Max-Age", "1209600"); } @Override public void filter(ContainerRequestContext reqContext) throws IOException { System.out.println("-- req info --: " + reqContext); // 处理OPTIONS预请求,确保过滤器能生效 if ("OPTIONS".equalsIgnoreCase(reqContext.getMethod())) { reqContext.abortWith(Response.ok().build()); } } }
三、TomEE CXF专属的CORS配置(推荐方案)
因为TomEE 1.7.2默认用Apache CXF作为JAX-RS实现,直接用CXF的原生CORS配置会更可靠:
- 在应用的
WEB-INF/web.xml里添加CXF的CORS过滤器:
<filter> <filter-name>CorsFilter</filter-name> <filter-class>org.apache.cxf.transport.servlet.CXFServlet</filter-class> <init-param> <param-name>cors.allowed.origins</param-name> <param-value>*</param-value> </init-param> <init-param> <param-name>cors.allowed.methods</param-name> <param-value>GET,POST,PUT,DELETE,OPTIONS,HEAD</param-value> </init-param> <init-param> <param-name>cors.allowed.headers</param-name> <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value> </init-param> <init-param> <param-name>cors.exposed.headers</param-name> <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value> </init-param> <init-param> <param-name>cors.support.credentials</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>cors.preflight.maxage</param-name> <param-value>1209600</param-value> </init-param> </filter> <filter-mapping> <filter-name>CorsFilter</filter-name> <url-pattern>/webresources/*</url-pattern> </filter-mapping>
- 确保你的CXFServlet配置正确,
WEB-INF/web.xml里应该有类似配置:
<servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/webresources/*</url-pattern> </servlet-mapping>
最后验证步骤
- 重启TomEE,清除浏览器缓存或者用Postman测试OPTIONS请求,查看响应头是否包含
Access-Control-Allow-Origin。 - 查看TomEE的日志,确认过滤器是否被加载(比如你的手动过滤器的打印日志是否出现)。
内容的提问来源于stack exchange,提问作者Creature
相关产品推荐
相关产品推荐

