0

I use SpringBoot2.1.5 to generate a web application, and I use maven package a war to deploy in outside tomcat9. I created a filter to print request uri,but the filter execute twice time. but when I use the ide console or package of jar, it just print only once!?

Console and log file output two identical url, not /favicon.ico,just test url, and the timestamps of the two outputs are different

filter.java

@Slf4j
@Component
@WebFilter(filterName = "ApiFilter", urlPatterns = "/*")
public class RequestFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        long time = System.currentTimeMillis();
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        filterChain.doFilter(servletRequest, servletResponse);
        StringBuilder params = new StringBuilder("?");
        Map<String, String[]> parameterMap = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            params.append(entry.getKey()).append("=");
            for (String s : entry.getValue()) {
                params.append(s).append(",");
            }
            params.deleteCharAt(params.length() - 1);
            params.append("&");
        }
        params.deleteCharAt(params.length() - 1);
        System.out.println("HAHAHAHAHAHAHa");
        log.info("[{}] {}ms, {}{}", request.getMethod(),System.currentTimeMillis() - time, request.getRequestURI(), params.toString());
    }
}

output

19-09-11 19:33:39.450 [http-nio-8989-exec-1] INFO  com.proj.aftermarket.config.RequestFilter - [POST] 14ms, /Proj/web-control!checkTime.do
19-09-11 19:33:39.451 [http-nio-8989-exec-1] INFO  com.proj.aftermarket.config.RequestFilter - [POST] 15ms, /Proj/web-control!checkTime.do

I expect the print only once about that,but it print twice thx.

Paosin
  • 13
  • 4
  • have you tried to issue a request with curl? Just to eliminate the browser/client side related issues from the picture? – Mark Bramnik Sep 11 '19 at 12:16
  • looks like it's executing for request and response, please use fiterChain to separate the execution so that it will be once – prasad Sep 11 '19 at 12:34
  • Possible duplicate of [why spring boot filter call twice?](https://stackoverflow.com/questions/44775539/why-spring-boot-filter-call-twice) – Martin van Wingerden Sep 11 '19 at 15:12

1 Answers1

0

Use org.springframework.web.filter.OncePerRequestFilter instead of Filter. As the name suggest this will make sure that the filter will be executed only once per request.

Since OncePerRequestFilter is a class you need to extend it instead of implements.

From the Javadoc:

Filter base class that aims to guarantee a single execution per request dispatch, on any servlet container. It provides a doFilterInternal(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.FilterChain) method with HttpServletRequest and HttpServletResponse arguments.

seenukarthi
  • 8,241
  • 10
  • 47
  • 68