[英]Jetty and Dropwizard: how to return always 200 instead of 404, 500, etc
我正在使用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,但是沒有運氣。
您可以創建自定義javax.ws.rs.ext.ExceptionMapper<RuntimeException>
。 在這種情況下,您從服務器獲得的每個異常都可以將其解析為200。
看看這個家伙 。 它應該很容易與您所需要的集成。
而不是本教程向您顯示的內容,例如以下示例:
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();
}
我正在使用最終可以使用的解決方案來更新問題:為了直接管理來自Jersey的Response對象,我使用了Jersey過濾器而不是Jetty http過濾器。
顯然,僅當您使用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("/"));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.