【发布时间】:2015-12-11 15:09:06
【问题描述】:
我有这个javax.servlet.Filter 来检查是否允许客户端访问 API REST 资源。
@Component
public class AuthorizationRequestFilter implements Filter {
public static final String AUTHORIZATION_TOKEN = "X-Access-Token";
@Autowired
@Qualifier("loginService")
private ILoginService loginService;
private void throwUnauthorized(ServletResponse res) throws IOException {
HttpServletResponse response = (HttpServletResponse) res;
response.reset();
response.setHeader("Content-Type", "application/json;charset=UTF-8");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
}
private void throwForbidden(ServletResponse res) throws IOException {
HttpServletResponse response = (HttpServletResponse) res;
response.reset();
response.setHeader("Content-Type", "application/json;charset=UTF-8");
response.sendError(HttpServletResponse.SC_FORBIDDEN);
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String accessToken = request.getHeader(AUTHORIZATION_TOKEN);
if (StringUtils.isEmpty(accessToken)) {
throwUnauthorized(res);
} else {
AccountLoginData account = loginService.find(accessToken);
if (account == null) {
throwForbidden(res);
}
}
chain.doFilter(req, res);
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
它有效,但我想在这两个throw*() 方法中使用适当的信息写入客户端 JSON。在这个应用程序的另一部分,我使用这些响应消息对象来通知客户端发生了什么。
例如,当没有找到记录时:
public class NotFoundResponseMessage extends ResponseMessage {
public NotFoundResponseMessage(String message) {
super(HttpStatus.NOT_FOUND, 1, message);
}
}
和
public class ResponseMessage {
private int status;
private int code;
private String message;
private String reason;
public ResponseMessage(int status, int code, String message, String reason) {
Assert.notNull(reason, "Reason must not be null.");
Assert.isTrue(status > 0, "Status must not be empty.");
this.status = status;
this.code = code;
this.message = message;
this.reason = reason;
}
}
我的问题
我想在我的javax.servlet.Filter 授权/身份验证过滤器中返回带有序列化对象(UnauthorizedResponseMessage 和ForbiddenResponseMessage)的 JSON。我使用 Spring Boot 和 Jackson 库。
- 如何手动将
ResponseMessage序列化为 JSON 表示形式? - 如何在我的过滤器类中将此 JSON 写回客户端?
编辑 1:
private void throwUnauthorized(ServletResponse res) throws IOException {
HttpServletResponse response = (HttpServletResponse) res;
response.reset();
response.setHeader("Content-Type", "application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("{\"foo\":\"boo\"}");
}
现在我可以写出 JSON 但返回 HTTP 500,因为:
java.lang.IllegalStateException: getWriter() has already been called for this response
at org.apache.catalina.connector.Response.getOutputStream(Response.java:544)
【问题讨论】:
-
afaik 你只会在经过身份验证的情况下使用
chain.doFilter(req, res);。否则,链下的事情会尝试添加常规(重复)响应:stackoverflow.com/a/8445927/995891