我有一个javax.servlet.Filter,用于检查客户端是否被允许访问API REST资源。
现在我可以写出JSON,但是返回HTTP 500,因为:
@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
授权/认证过滤器中,使用Spring Boot和Jackson库返回已序列化的对象(UnauthorizedResponseMessage
和ForbiddenResponseMessage
)的JSON。
- 如何手动将
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)
chain.doFilter(req, res);
。否则,链中的其他事物会尝试添加常规(重复)响应:https://dev59.com/gWoy5IYBdhLWcg3wl_Ix#8445927 - zapl