Filter Chain throws getWriter() has already been called for this response

Viewed 163

I was trying to add a filter chain for all requests. I completed this task but in somehow in local environment it throws getWriter() as already been called for this response exception. I have followed the stack trace and the only custom filter is this. I am pretty sure that if block is not executing, code continue to else block

public class PaymentRequiredFilter extends OncePerRequestFilter {
    private final ObjectMapper mapper;
    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        if (ExpiryConfiguration.appExpiryDate.before(new Date())) {
            Map<String, Object> errorDetails = new HashMap<>();
            errorDetails.put("message", "Application has expired.");
            httpServletResponse.setStatus(HttpStatus.PAYMENT_REQUIRED.value());
            httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
            mapper.writeValue(httpServletResponse.getWriter(), errorDetails);
        } else {
            filterChain.doFilter(httpServletRequest, httpServletResponse); // this code is executing all the time and throws exception in the continued filters.
        }
    }
}

In this code it throws the exception. But on the other hand if I change like below, nothing throws anything. Also nothing prints in console.

public class PaymentRequiredFilter extends OncePerRequestFilter {
    private final ObjectMapper mapper;
    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        if (ExpiryConfiguration.appExpiryDate.before(new Date())) {
            Map<String, Object> errorDetails = new HashMap<>();
            errorDetails.put("message", "Application has expired.");
            httpServletResponse.setStatus(HttpStatus.PAYMENT_REQUIRED.value());
            httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
            mapper.writeValue(httpServletResponse.getWriter(), errorDetails);
        } else {
            try{
                filterChain.doFilter(httpServletRequest, httpServletResponse); // this does not throw anything and does not print any stack trace and my code works correctly.
            }catch (Exception ex){
                ex.printStackTrace();
            }

        }
    }
}

Also I found that

public class PaymentRequiredFilter extends OncePerRequestFilter {
    private final ObjectMapper mapper;
    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        if (ExpiryConfiguration.appExpiryDate.before(new Date())) {
            Map<String, Object> errorDetails = new HashMap<>();
            errorDetails.put("message", "Application has expired.");
            httpServletResponse.setStatus(HttpStatus.PAYMENT_REQUIRED.value());
            httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
            // mapper.writeValue(httpServletResponse.getWriter(), errorDetails); // if I remove this line everything works correctly.
        } else {
            filterChain.doFilter(httpServletRequest, httpServletResponse); // this code is executing all the time
        }
    }
}
  • The problem is this how some method usage without executing throws an exception ?
  • How try catch never catches exception in debug mode also ?
  • Why getWriter() method is used when code not enter the if block ?
0 Answers
Related