Jetty和Dropwizard:如何返回总是200而不是404,500等

时间:2015-05-13 17:06:29

标签: java jersey jetty servlet-filters dropwizard

我正在使用Jetty-Jersey-Jackson堆栈附带的Dropwizard 0.8.0 出于安全原因,我想添加一个过滤器,使得通过Jersey定义的特定路由的每个请求总是返回200,即使出现错误(4xx,5xx等)。

这可能与Jetty / Servlet过滤器有关吗?我可以在通过Jersey资源(控制器)之后拦截请求,但在它返回客户端之前,为了修改http状态代码吗?

更新

我正在尝试使用ServletFilter执行此操作,但似乎在执行代码之前将响应发送到客户端。
我用这种方式编写过滤器:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
    if (response instanceof HttpServletResponse) {
        /* No pre-processing */

        chain.doFilter(request, response);

        /* Post-processing: */

        HttpServletResponse modifiedResponse = (HttpServletResponse) response;

        if (modifiedResponse.getStatus() != 200) {
            modifiedResponse.setStatus(200);
        }
    }
}

有了这个,在Dropwizard注册:

environment.servlets().addFilter("MyCustomFilter", new MyCustomFilter())
           .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/mypath/*");

执行过滤器,在access.log中,我看到状态码为200的所有请求;但客户端始终获得“真实”状态代码(例如,404或“不允许的方法”) 似乎在执行过滤器的最后一部分之前将响应发送到客户端。而且,我无法修改响应体。我也尝试使用HttpServletResponseWrapper,但没有运气。

2 个答案:

答案 0 :(得分:2)

您可以创建自定义javax.ws.rs.ext.ExceptionMapper<RuntimeException>。在这种情况下,您从服务器获得的每个例外都可以将其解析为200。

检查此guy。它应该很容易与您需要的东西集成。

而不是教程向您展示的内容,例如:

 if (webAppException.getResponse().getStatus() == 401) {
      return Response
        .status(Response.Status.UNAUTHORIZED)
        .entity(new PublicFreemarkerView("error/401.ftl"))
        .build();
 }

您的代码将是

 if (webAppException.getResponse().getStatus() == 401) {
      return Response
        .status(Response.Status.OK)
        .build();
 }

答案 1 :(得分:0)

我使用最终有效的解决方案更新问题:我使用了Jersey过滤器而不是Jetty http过滤,以便直接管理来自Jersey的Response对象。

显然,这只适用于你使用Jetty + Jersey而不是Jetty独立使用。

以下是我使用的过滤器:

/**
 * When active, this filter transforms all responses for specified basePath to 200, even in case of error.
 */
@Provider
public class DiscardErrors implements ContainerResponseFilter
{
    private String basePath;

    public DiscardErrors(String basePath)
    {
        this.basePath = basePath;
    }

    @Override
    public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) throws IOException
    {
        if containerRequestContext.getUriInfo().getPath().startsWith(this.basePath) {
            if (containerResponseContext.getStatus() != 200) { // Check if response code is different from 200
                containerResponseContext.setStatus(200); // Force 200 status code
                containerResponseContext.setEntity(""); // Empty body
            }
        }
    }

}

在Dropwizard中注册:

environment.jersey().register(new DiscardErrors("/"));