如何避免Tomcat下CXF的JAX-RS应用抛异常时返回HTML
问题根源
Tomcat默认会拦截所有调用了HttpServletResponse.sendError()方法返回的>=400状态码的响应,替换为自带的HTML错误页面。而CXF默认处理错误状态码的响应时,会优先调用sendError()而非直接写入响应内容,导致你自定义的响应实体被覆盖。
适配CXF的解决方案
按优先级从高到低推荐:
方案1:配置CXF关闭sendError调用(最推荐)
在你的CXF JAX-RS服务配置中添加org.apache.cxf.transport.http.no_send_error属性,值设为true即可。
如果是XML格式配置(比如cxf-servlet.xml):
<jaxrs:server address="/你的服务路径"> <!-- 你原有配置的serviceBeans、providers等内容保持不变 --> <jaxrs:properties> <entry key="org.apache.cxf.transport.http.no_send_error" value="true"/> </jaxrs:properties> </jaxrs:server>
如果是Spring Boot注解配置:
@Configuration public class CxfConfig { @Bean public Server jaxRsServer(Bus bus) { JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean(); factory.setBus(bus); // 你原有配置的服务类、provider等保持不变 Map<String, Object> properties = new HashMap<>(); properties.put("org.apache.cxf.transport.http.no_send_error", true); factory.setProperties(properties); return factory.create(); } }
开启该配置后,CXF遇到错误状态码会直接调用setStatus()设置响应状态,不会触发Tomcat的错误页流程。
方案2:在ExceptionMapper中明确指定返回格式
修改你的异常处理代码,明确设置响应的Content-Type为XML,避免Tomcat识别为普通文本触发错误页:
@Component public class MyExceptionHandler implements ExceptionMapper<MyException> { @Override public Response toResponse(MyException exception) { return Response .status(500) .entity(new ExceptionBodyResponse(exception)) .type(MediaType.APPLICATION_XML) // 明确指定XML格式 .build(); } }
方案3:修改Tomcat web.xml配置关闭错误页
如果以上方案不生效,可以在应用的WEB-INF/web.xml中添加错误页配置,指定500等错误状态码返回空内容:
<error-page> <error-code>500</error-code> <location>/WEB-INF/empty.xml</location> </error-page> <!-- 如需覆盖所有4xx、5xx错误可按需添加多个error-page节点 -->
然后在WEB-INF目录下新建空的empty.xml文件即可。
内容的提问来源于stack exchange,提问作者Vivien
相关产品推荐
相关产品推荐

