如何将Java对象序列化为JSON并在servlet过滤器中返回?

时间:2015-09-15 11:21:51

标签: java json spring servlets

我有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;

    }

}

我的问题

我想在我的UnauthorizedResponseMessage授权/身份验证过滤器中返回带有序列化对象(ForbiddenResponseMessagejavax.servlet.Filter)的JSON。我使用Spring Boot和Jackson库。

  1. 如何手动ResponseMessage序列化为其JSON表示形式?
  2. 如何在我的过滤器类中将此JSON写回客户端?
  3. 修改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)
    

3 个答案:

答案 0 :(得分:1)

使用JacksonObject转换为JSON,以下是一个示例

ObjectMapper mapper = new ObjectMapper();
String Json =  mapper.writeValueAsString(object);  

答案 1 :(得分:0)

我遇到了同样的问题,完整的解决方案如下:

import webbrowser
url = 'www.google.com'
chrome_path = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s --incognito'
webbrowser.get(chrome_path).open_new(url)

结果是:

enter image description here

答案 2 :(得分:-2)

只需从过滤器中抛出异常,并使用@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "Error while trying to add the feed.") public class AddFeedException extends Exception { private static final long serialVersionUID = 290724913968202592L; public AddFeedException(Throwable throwable) { super(throwable); } } 注释抛出的异常。这样它就会自动转换为给定的http错误代码。 (您也可以定义错误消息)

代码示例:

{{1}}