找到了解决方案。在 web.xml 中,我添加了处理 /api/api-docs/* 请求的过滤器。
它设置在处理 /api/* 请求的过滤器之前。
<filter>
<filter-name>SwaggerDocRequestFilter</filter-name>
<filter-class>my.package.filters.SwaggerDocRequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SwaggerDocRequestFilter</filter-name>
<url-pattern>/api/api-docs/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
SwaggerDocRequestFilter 看起来像这样:
public class SwaggerDocRequestFilter implements Filter {
@Override
public void init(FilterConfig fc) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
String path = ((HttpServletRequest) request).getRequestURI();
if (path.contains("/api-docs")) {
String forwardPath = ((HttpServletRequest) request).getServletPath() +
StringUtils.defaultString(((HttpServletRequest)request).getPathInfo());
request.getRequestDispatcher(forwardPath).
forward(request, response);
} else {
chain.doFilter(request, response);
}
}
@Override
public void destroy() {}
}
这会覆盖所有 javax.servlet.Filter 实现。
对于覆盖 JAX RS 过滤器,需要提供自己的 javax.ws.rs.container.DynamicFeature 接口实现。此实现仅在对特定资源的请求发生时才应用过滤器,在我的例子中是针对特定包中的资源。
public class MyDynamicFiltersRegister implements DynamicFeature {
@Override
public void configure(final ResourceInfo resourceInfo, final FeatureContext context) {
if (resourceInfo.getResourceClass().getPackage().getName().equals("my.package.resources)) {
//register filters on FeatureContext objec only if resource in specific package.
...
}
}
}
在这种情况下,Swagger UI 可以正常工作。
在对特定资源的请求中,应用 JAX RS 过滤器。