SpringFox Swagger在IBM Liberty 19.0.0.1上异常,请求排查原因
我帮你梳理下当前的问题和对应的解决思路——你把基于Spring Boot 2.1.3的应用从Tomcat 9迁移到Liberty 19.0.0.1后,Swagger UI出现了两个关键问题:响应体无法正常展示,执行"Try it out"还会触发401未授权错误,同时控制台抛出406错误码。先给你拆解下问题根源和解决步骤:
问题现象回顾
- Tomcat 9环境:Swagger UI的200响应体显示清晰,"Try it out"功能完全正常
- Liberty 19.0.0.1环境:
- 200响应体无法加载显示
- 执行"Try it out"后返回截断的错误页面,包含
SRVE0260E错误;控制台还输出SRVE0295E(406错误)
错误日志详情
return (<H1>Error Page Exception</H1> )return (<H4>SRVE0260E: The server cannot use the error page specified for your application to handle the Original Exception printed below.</H4> )return (<BR><H3>Original Exception: </H3> <B>Error Message: </B>Unauthorized<BR> <B>Error Code: </B>401<BR> <B>Target Servlet: </B>dispatcherServlet<BR> <B>Error Stack: </B><BR> com.ibm.ws.webcontainer.webapp.WebAppErrorReport: Unauthorized <BR> at com.ibm.ws.webcontainer.webapp.WebAppDispatcherContext.sendError(WebAppDispatcherContext.java:630) <BR> at com.ibm.ws.webcontainer.webapp.WebAppDispatcherContext.sendError(WebAppDispatcherContext.java:648) <BR> at com.ibm.ws.webcontainer.srt.SRTServletResponse.sendError(SRTServletResponse.java:1328) <BR> at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:164) <BR> at javax.servlet.http.HttpServletResponseWrapper.sendError(HttpServletResponseWrapper.java:164) <BR> at org.springframework.security.web.util.OnCommittedResponseWrapper.sendError(OnCommittedResponseWrapper.java:119) <BR> at org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint.commence(BasicAuthenticationEntryPoint.java:61) <BR> at org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint.commence(DelegatingAuthenticationEntryPoint.java:95) <BR> at org.springframework.security.web.access.ExceptionTranslationFilter.sendStartAuthentication(ExceptionTranslationFilter.java:213) <BR> at org.springframework.security.web.access.ExceptionTranslationFilter.handleSpringSecurityException(ExceptionTranslationFilter.java:185) <BR> at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:141) <BR> at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ...(更多内容) )
Liberty控制台额外报错:
Error reported: 406 [ERROR ] Error Page Exception: 0-0 Error Page Exception com.ibm.ws.webcontainer.webapp.WebAppErrorReport: SRVE0295E
当前Liberty的server.xml配置
<?xml version="1.0" encoding="UTF-8"?> <server description="new server"> <!-- Enable features --> <featureManager> <feature>webProfile-8.0</feature> <feature>springBoot-2.0</feature> <feature>servlet-4.0</feature> </featureManager> <basicRegistry/> <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" --> <httpEndpoint id="defaultHttpEndpoint" httpPort="9090" httpsPort="9443" /> <!-- Automatically expand WAR files and EAR files --> <applicationManager autoExpand="true"/> </server>
核心问题根源
从错误栈和配置来看,问题主要出在两个地方:
Spring Security与Liberty的错误响应处理冲突:
Spring Security的Basic认证触发401错误时,调用了sendError()方法,但Liberty默认返回HTML格式的错误页面,而Swagger UI期望JSON格式的响应,导致406错误(服务器无法生成客户端期望的内容类型),同时因为应用没有配置自定义错误页面,抛出SRVE0260E。Spring Boot特性版本不兼容:
你的应用用的是Spring Boot 2.1.3,但server.xml里启用的是springBoot-2.0特性,Liberty的特性版本和Spring Boot版本不匹配,会导致Servlet过滤器链、响应处理等环节出现兼容性问题,影响Swagger UI的正常渲染。
分步解决方案
1. 升级Liberty的Spring Boot特性版本
把server.xml中的springBoot-2.0替换为springBoot-2.1(Liberty 19.0.0.1支持该特性),同时移除重复的servlet-4.0(已经包含在webProfile-8.0中):
<featureManager> <feature>webProfile-8.0</feature> <feature>springBoot-2.1</feature> </featureManager>
2. 修改Spring Security返回JSON格式的401响应
自定义Basic认证的错误入口,让响应返回JSON格式,适配Swagger UI的需求:
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest().authenticated() .and() .httpBasic() .authenticationEntryPoint((request, response, authException) -> { response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.getWriter().write("{\"error\": \"Unauthorized\", \"message\": \"" + authException.getMessage() + "\"}"); }); } // 放行Swagger相关资源 @Override public void configure(WebSecurity web) throws Exception { web.ignoring() .antMatchers("/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**"); } }
3. 配置Liberty的媒体类型支持(可选)
确保Liberty能正确识别JSON类型,在server.xml中添加:
<mimeTypes> <mime-type type="application/json" extension="json"/> </mimeTypes>
4. 添加自定义错误页面(可选)
如果还是遇到SRVE0260E,可以在server.xml中配置容器级错误处理:
<webContainer errorPageOverride="true"> <errorPage errorCode="401" location="/error/401"/> </webContainer>
然后在应用中创建/error/401端点,返回JSON格式的错误响应。
完成这些步骤后,重启Liberty服务,应该就能解决Swagger UI响应体不显示和"Try it out"的异常问题了。
内容的提问来源于stack exchange,提问作者bmylavar

