Bragolgirith
Bragolgirith

Reputation: 2238

Spring - Returning JSON-formatted error messages from a filter

I'm working on a Spring Boot REST application.

I've registered a custom AuthenticationEntryPoint that returns a '401 Unauthorized' error if a user doesn't provide credentials.

@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {

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

This works great and returns the JSON-formatted DefaultErrorAttributes that look like this:

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

Now I've added a Filter to the application with the following doFilter() override:

@ 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);
}

However instead of the JSON-formatted DefaultErrorAttributes shown above, this code returns the default Tomcat 'Error report' HTML page.

Why does this happen and what would be the best way to make both error messages consistent (JSON-formatted) in both cases?

Upvotes: 4

Views: 5731

Answers (1)

取一个好的名字
取一个好的名字

Reputation: 1823

Original link 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();
    }  
}

Upvotes: 6

Related Questions