如何在tomcat中的Filter class-method响应servlet客户端时设置http状态代码

Mat*_*ias 1 java tomcat servlets filter

我正在写一个带有spring的web服务(这个问题不是关于spring ...),它实现了一个(希望)安静的api.根据我的理解,所有响应都应该是xml或json格式.在大多数情况下,这并不是什么大问题.但在某种情况下,这似乎是不可能的.我正在使用tomcat中的一个设备,其中涉及servlet.我出于某种原因必须使用过滤器(这个原因是身份验证).由于我是servlets的新手,我的理解最终还不是很好,但对我而言,它看起来像这样

我的filter-class派生自javax.servlet.filter,我在doFilter方法中编写代码:

@Override
public void doFilter(ServletRequest request, ServletResponse response,
                          FilterChain chain) throws IOException, ServletException { // ... }
Run Code Online (Sandbox Code Playgroud)

在某些时候,我意识到我必须用http状态代码401响应客户端,并且还想给他一个关于发生了什么的xml或json信息.现在对我看起来好像我也可以

1)使用ServletResponse:这允许我获取OutputStream并写出我的xml/json.但是我根本无法设置http状态代码.到达客户端的最终响应确实包含一些http标头.

2)将ServletResponse转换为HttpServletResponse:这允许我设置状态代码,但我似乎无法设置响应体,但是让tomcat处理响应体.

无论哪种方式似乎都不完整 如果我使用ServletResponse写入OutputStream然后转换为HttpServletResponse然后调用sendError(401) - 希望我写给OutputStream的任何内容到达客户端 - 我的响应不包含http"状态行".但是http头文件就像"Server:Apache-Coyote/1.1"

任何帮助欢迎...

Jim*_*ins 12

我很快就实现了一个用于身份验证的过滤器.我编写了类似的东西:

public void doFilter(ServletRequest req, ServletResponse resp,
                         FilterChain chain)
{
    HttpServletResponse response=(HttpServletResponse) resp;

    boolean authenticated=false;
    // perform authentication

    if (authenticated)
    {
         chain.doFilter(req, response);
    }
    else
    {
         // don't continue the chain
         response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
         response.setHeader("WWW-Authenticate", "BASIC realm=\"Your realm\"");

         response.setContentType("what you need");
         PrintWriter writer=response.getWriter();

         // don't set content length , don't close
    }
}
Run Code Online (Sandbox Code Playgroud)


ezt*_*tam 5

这对我有用:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
    ServletException {

    response.resetBuffer();
    response.getOutputStream().write("Your content".getBytes());
    HttpServletResponse hsr = (HttpServletResponse) response;
    hsr.setStatus(401);
    chain.doFilter(request, response);
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么在设置状态 401 后继续使用过滤器链?无论如何都会执行身份验证之前的过滤器 (2认同)
  • 你是对的,当然`web.xml` 会影响过滤器执行的顺序。但一般来说,继续处理未经身份验证的请求是没有意义的。如果有要执行的任务(例如日志记录),它们应该在身份验证之前链接的过滤器中执行。 (2认同)