Java 从tomcat中的Filter类方法响应servlet客户端时如何设置http状态码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35767502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set http status code when responding to servlet client from Filter class-method in tomcat
提问by Matthias
I am writing a webservice with spring (this question is not about spring...) that implements a (hopefully) restful api. From my understanding all response should be in xml or json format. This is not really a big deal in most cases. But in one situation this seems not possible. I am using a facility from tomcat where a servlet is involved. I have to use a filter for some reason (and this reason is authentication). As I am new to servlets my understanding is eventually not so well, but to me it looks like this
我正在用 spring 编写一个 web 服务(这个问题不是关于 spring ......),它实现了一个(希望)restful api。根据我的理解,所有响应都应该是 xml 或 json 格式。在大多数情况下,这并不是什么大问题。但在一种情况下,这似乎是不可能的。我正在使用涉及 servlet 的 tomcat 工具。由于某种原因,我必须使用过滤器(这个原因是身份验证)。由于我是 servlets 的新手,我的理解最终不是那么好,但对我来说它看起来像这样
My filter-class derives from javax.servlet.filter and I am writing my code within the doFilter method:
我的过滤器类派生自 javax.servlet.filter 并且我正在 doFilter 方法中编写我的代码:
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException { // ... }
And at some point i realize i have to respond to the client with http status code 401 and also want to give him a xml or json information about what happened. Now to me it looks as if i can either
在某些时候,我意识到我必须用 http 状态代码 401 响应客户端,并且还想给他一个关于发生了什么的 xml 或 json 信息。现在对我来说似乎我也可以
1) Use the ServletResponse: This allows me to get an OutputStream and write my xml/json out. However I cannot set the http status code at all. The final response arriving at the client does contain some http headers.
1) 使用 ServletResponse:这允许我获得一个 OutputStream 并写出我的 xml/json。但是我根本无法设置 http 状态代码。到达客户端的最终响应确实包含一些 http 标头。
2) Cast ServletResponse to HttpServletResponse: This allows me to set status code, but I don't seem to be able to set the response body, but let response body be handled from tomcat.
2)Cast ServletResponse to HttpServletResponse:这允许我设置状态码,但我似乎无法设置响应主体,而是让响应主体从tomcat处理。
Either way seems incomplete. If i use ServletResponse to write to the OutputStream and then cast to HttpServletResponse and then call sendError(401) - hoping that whatever I wrote to OutputStream reaches the client - my response does not contain an http "status line". However http headers are present like "Server: Apache-Coyote/1.1"
无论哪种方式似乎都不完整。如果我使用 ServletResponse 写入 OutputStream,然后转换为 HttpServletResponse,然后调用 sendError(401) - 希望我写入 OutputStream 的任何内容都能到达客户端 - 我的响应不包含 http“状态行”。但是,http 标头存在,如“服务器:Apache-Coyote/1.1”
any help welcome...
欢迎任何帮助...
采纳答案by JimHawkins
I've implemented a filter for authentication shortly. I've coded something similar to this:
我很快就实现了一个用于身份验证的过滤器。我已经编写了类似的代码:
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
}
}
回答by eztam
This works for me:
这对我有用:
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);
}
回答by Shamil Guseinov
Method HttpServletResponse::sendError is working for me to return from filter in SpringBoot 2.0 application:
方法 HttpServletResponse::sendError 正在帮助我从 SpringBoot 2.0 应用程序中的过滤器返回:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (authenticated)
{
chain.doFilter(req, response);
}
else
{
((HttpServletResponse) response).sendError(HttpStatus.FORBIDDEN.value(), "Authorization shall be provided");
}
chain.doFilter(request, response);
}