【问题标题】:Spring - Returning JSON-formatted error messages from a filterSpring - 从过滤器返回 JSON 格式的错误消息
【发布时间】:2016-10-06 09:08:22
【问题描述】:

我正在开发一个 Spring Boot REST 应用程序。

我注册了一个自定义 AuthenticationEntryPoint,如果用户不提供凭据,它会返回“401 Unauthorized”错误。

@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    }
}

这很好用,并返回 JSON 格式的 DefaultErrorAttributes,如下所示:

{
  "timestamp": 1465230610451,
  "status": 401,
  "error": "Unauthorized",
  "exception": "org.springframework.security.authentication.BadCredentialsException",
  "message": "Unauthorized",
  "path": "/webapp/login"
}

现在我已经使用以下doFilter() 覆盖向应用程序添加了Filter

@ Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
    try {
        // Here be some code that fails.
    } catch (Exception e) {
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
    }

    chain.doFilter(request, response);
}

但是,此代码不是上面显示的 JSON 格式的 DefaultErrorAttributes,而是返回默认的 Tomcat“错误报告”HTML 页面。

为什么会发生这种情况?在这两种情况下使两个错误消息保持一致(JSON 格式)的最佳方法是什么?

【问题讨论】:

  • chain.doFilter(request, response);移动到try块中。

标签: json spring spring-boot httpresponse servlet-filters


【解决方案1】:

原文链接http://teknosrc.com/java-break-filter-chain-return-custom-pojo-response-servlet/

public class TestFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

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

        if(ANY CONDITION){
            //ANY POJO CLASS
            // ErrorResponse is a public return object that you define yourself
            ErrorResponse errorResponse = new ErrorResponse();
            errorResponse.setCode(401);
            errorResponse.setMessage("Unauthorized Access");
   
            byte[] responseToSend = restResponseBytes(errorResponse);
            ((HttpServletResponse) response).setHeader("Content-Type", "application/json");
            ((HttpServletResponse) response).setStatus(401);
            response.getOutputStream().write(responseToSend);
            return;
        }

        //ANY OTHER BUSINESS LOGIC
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }

    private byte[] restResponseBytes(ErrorResponse eErrorResponse) throws IOException {
        String serialized = new ObjectMapper().writeValueAsString(eErrorResponse);
        return serialized.getBytes();
    }  
}

【讨论】:

  • 我想知道为什么 response.sendError() 不一样。我碰巧陷入了同样的问题。感谢您的回答。
猜你喜欢
  • 2021-01-28
  • 2020-06-12
  • 1970-01-01
  • 2015-08-31
  • 2021-04-08
  • 2013-07-11
  • 1970-01-01
  • 1970-01-01
  • 2016-01-21
相关资源
最近更新 更多