This fight is all due to iOS, why do you say so, HTTP request will not be sent, what kind of crap (PS: he will not see…) .

While dealing with this conflict, we accidentally discovered another long-standing bug, which we’ll talk about first, and then the feud between us. Because it’s closely related.

Filter in SpringBoot

Filters should be very common, but your filter really plays the role of interception, here even if you play the role of interception, but can your filter intercept the specified path? So let me just write it in the original way.

Careful reference:

@WebFilter(filterName = "baseFilter", urlPatterns = "/ *")

public class BaseFilter implements Filter {



    @Override

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) {



        System.out.println("BaseFilter intercepted /*");

        

        filterChain.doFilter(req, resp);

    }

}

Copy the code

First of all, if you think it’s ok to add @webfilter, I’m telling you, it’s going to hurt your face.

Since this annotation is servlet, you must remember to annotate @ServletComponentScan on the startup class so that the filters will be scanned when the application starts.

We wrote a Controller interface to access it, and we can see that the interceptor actually intercepted our request.


What you think is what you think

Sometimes our project is too big, so WE don’t know what was introduced, sometimes the filter can’t be injected. When we see the error line, we may not have a reaction in my mind, but THE CV method has opened Baidu and found the cause of the problem. Baidu said you should add @commponent annotation. And then he did, and then he did what he did.

@Component

@WebFilter(filterName = "baseFilter", urlPatterns = "/user/*")

public class BaseFilter implements Filter {



    @Override

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) {



        HttpServletRequest request = (HttpServletRequest) req;



        String url = request.getRequestURL().toString();



        System.out.println(url);

        System.out.println("BaseFilter intercepted /*");

        

        filterChain.doFilter(req, resp);

    }

}

Copy the code

Unfortunately, however, the @Component annotation fixes the problem, but the specific path intercepted by urlPatterns doesn’t work.

Here I have a request that starts with pub, the interceptor intercepts a request that starts with user, and then follows:


He actually intercepts all the requests for me, which is not what I expected, so how do we solve this problem? Look down at the students.

How does SpringBoot inject filters

Here I will not list many injection methods, so as not to confuse you, I will directly tell you how to correct injection OK, I have tested, and management is very convenient.

Filter writing

Filters do not add anything other than implement filters, it is as simple as that.

public class BaseFilter implements Filter {





    @Override

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) {



        HttpServletRequest request = (HttpServletRequest) req;



        String url = request.getRequestURL().toString();



        System.out.println(url);

        System.out.println("BaseFilter intercepted /*");

        

        filterChain.doFilter(req, resp);

    }

}

Copy the code

Filter injection

We inject the filter directly by configuring the class so that we can see all of our filters and filter rules at a glance.

The following parameters are basic and mandatory. Name is the class name of the filter, and the first letter of the filter is lowercase. Order is the order in which the filter is executed.

Then we have a complete filter configured. BaseFilter will not intercept you when you attempt to access /pub.

Here also recommend everybody to configure as far as possible after this.

@Configuration

public class FilterConfig {



    @Bean

    public FilterRegistrationBean<BaseFilter> baseFilter() {

        FilterRegistrationBean<BaseFilter> filterBean = new FilterRegistrationBean<>();

        filterBean.setFilter(new BaseFilter());

        filterBean.setName("baseFilter");

        filterBean.addUrlPatterns("/user/*");

        filterBean.setOrder(1);

        return filterBean;

    }

}

Copy the code

My battle with iOS

Let’s look at the newspaper’s mistakes first, and then talk about how I screwed up this time

RequestRejectedException: The request was rejected because the URL was not normalized.

Copy the code

The request was rejected because the url was not standard.

Not to say my interface has a problem, originally want to rise up to resist, see the other party than I build fierce, think or catch substantial evidence in jilting him.

Since the request url is not correct, I guess is the request path is not something fishy, then we will catch the package bai.

Finally, we got the real evidence under various means. Judges:

His request path: http://127.0.0.1:8080//user/list

Copy the code

A double slash appears in his request path, which must be an error. Note that the error is caused by the introduction of the Security framework.

Since the problem has been identified, I must rise up against him and shake the pot. When he sees this time, right? He has nothing to say, but can silently carry the pot on his back.

In this way, I successfully cast the pot again.

Solution and reflection

The pot is out, but the problem has to be solved.

In fact, according to normal logic, no matter what we introduce, as long as the request path is correct, no matter how many slashes appear in the path, we should deal with it, and not affect the user’s access. So we just do one through the filter.

public class UriFormatFilter extends OncePerRequestFilter {



    @Override

    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain)

            throws ServletException, IOException {



// Path isolation symbol

        String separateSymbol = "/";



        String uri = req.getRequestURI();

        StringBuilder newUrl = new StringBuilder();



        String[] split = uri.split(separateSymbol);



        for (String s : split) {

            if (StringUtils.isNotBlank(s)) {

                newUrl.append(separateSymbol).append(s);

            }

        }



        req = new HttpServletRequestWrapper(req) {

            @Override

            public String getRequestURI() {

                return newUrl.toString();

            }

        };

        filterChain.doFilter(req, res);

    }

}

Copy the code

Finally, the filter is injected

If you write 1, you think it’s going to be executed first, but it’s not. Maybe some of the framework’s filters will execute first before it executes, so just to be on the safe side, we’ll set it to -100 to make sure the request comes in first.

@Bean

public FilterRegistrationBean<UriFormatFilter> uriFormatFilter() {

    FilterRegistrationBean<UriFormatFilter> filterBean = new FilterRegistrationBean<>();

    filterBean.setFilter(new UriFormatFilter());

    filterBean.setName("uriFormatFilter");

    filterBean.addUrlPatterns("/ *");

    filterBean.setOrder(-100);

    return filterBean;

}

Copy the code

Pay attention to

If you pay attention to some Mapper, Service, etc. in the filter, there may be a problem, when the injected object may be null, this involves the loading order of the class, I will not here bibi, real people encountered again. I took care of the Doge anyway.

Reference article:

https://blog.csdn.net/chenmengyijiu/article/details/84561302 https://blog.csdn.net//qq_30062181/article/details///84964691

For more exciting content, please follow the wechat official account: “The Growth of a Programmer”