本次斗殴事件起因全副归iOS,为啥这么说,http申请都不会发,瞎写的什么玩意(ps:他应该不会看到...)。

在解决本次抵触中,意外发现了另外一个存在已久的bug,咱们先说说这个玩意,再说咱们之间的恩怨。因为这是非亲非故的。

SpringBoot中的过滤器

过滤器这货色应该很常见了,然而你的过滤器真的起到拦挡的作用了,这里就算你起到拦挡的作用了,然而你的过滤器能拦挡到指定的门路吗?先看一下我原始写法。

审慎参考:

@WebFilter(filterName = "baseFilter", urlPatterns = "/*")public class BaseFilter implements Filter {    @Override    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) {        System.out.println("baseFilter 拦挡了 /*");                filterChain.doFilter(req, resp);    }}

首先这里说下,如果你这是特地单纯的加个@WebFilter就认为ok了,那我通知你,脸会被打的很疼的。

因为这个注解是servlet的,所以你肯定要记得在启动类上加@ServletComponentScan此注解,这样在利用启动的时候,过滤器才会被扫描到。

咱们写了一个Controller的接口拜访了下,能够看到拦截器的确拦挡到了咱们的申请。

你认为的只是你认为

咱们我的项目有时候大了,不晓得引入了什么货色,有时候会导致这个过滤器呢就无奈被注入,看到那行报错呢可能脑子还没反馈过去,然而CV大法曾经关上了度娘,找到了问题起因,度娘说你加个@Commponent注解好了。而后也的确好了,而后接下来他都如何操作。

@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 拦挡了 /*");                filterChain.doFilter(req, resp);    }}

然而,不巧的是加了@Component注解尽管解决了问题,然而呢urlPatterns拦挡的指定门路却没有失效。

我这里是一个pub结尾的申请,拦截器拦挡的user结尾的,而后如下:

他竟然将所有的申请给我拦挡了下来,不是我设想的那样,那咱们该如何解决这种问题呢?往下看同学。

SpringBoot如何注入过滤器

这里我就不列举泛滥的注入形式了,免得混同大家,我就间接通知你们怎么正确注入就ok了,自己曾经亲测,而且治理起来很是不便。

过滤器写法

过滤器除了实现Filter之外,不要加任何的货色,就是这么简略。

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 拦挡了 /*");                filterChain.doFilter(req, resp);    }}

过滤器注入

咱们这里间接通过配置类的形式将过滤器注入,这样呢,咱们这里也高深莫测,看到咱们所有的过滤器,以及过滤器规定。

上面的这些参数都是根本配置,根本都是必填,name你就写过滤器的类名,首字母小写就好了,order就是过滤器的执行程序,数字越小,越先执行。

这样咱们一个残缺的过滤器就配置好了。当你再拜访/pub接口时,是不会被BaseFilter拦挡到的。

这里也举荐大家当前尽量这样去配置。

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

我与iOS的一战

咱们先看报的错,再来聊聊这次的锅我是怎么甩的

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

看到没因为网址不规范,导致申请被回绝。

非说我接口有问题,原本想奋起镇压,看到对方比我身材威猛,想想还是抓到实质性证据在甩他吧。

既然说申请网址不正确,我猜想就是申请门路中是不是有什么猫腻,那咱们就抓包呗。

最初在咱们各种伎俩之下拿到了真凭实据。诸位法官请看:

他的申请门路:http://127.0.0.1:8080//user/list

他的申请门路中呈现了双斜杠,这样必定报错啊。这里须要阐明下,报错是因为引入了Security平安框架。

既然曾经确定问题,那我必须奋起镇压,找他甩锅,当他看到这个时候,对吧本人也无话可说,只能默默的把锅背上。

就这样我这次又顺利的甩锅胜利。

解决与反思

尽管锅甩出去了,然而问题还是要解决的。

其实按失常逻辑来说,不论咱们引入了什么货色,只有申请门路正确,及时门路中呈现再多的斜杠,咱们也应该做好解决,不能影响用户的拜访。所以咱们就通过过滤器就行一个解决。

public class UriFormatFilter extends OncePerRequestFilter {    @Override    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain)            throws ServletException, IOException {        // 门路隔离符号        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);    }}

最初将过滤器注入

这里order为啥写-100,如果你写1,你认为它会是第一个执行,其实不然,在执行他之前,可能框架的一些过滤器会先执行,所以为了保险起见,咱们就设置为-100,确保申请进来之后先走它。

@Beanpublic FilterRegistrationBean<UriFormatFilter> uriFormatFilter() {    FilterRegistrationBean<UriFormatFilter> filterBean = new FilterRegistrationBean<>();    filterBean.setFilter(new UriFormatFilter());    filterBean.setName("uriFormatFilter");    filterBean.addUrlPatterns("/*");    filterBean.setOrder(-100);    return filterBean;}

留神

如果你在过滤器中留神一些Mapper、Service之类的话,可能会呈现问题,调用的时候被注入的对象可能是个null,这就波及到类的加载程序,我就不在这里bibi了,真有人遇到了再说。反正我曾经解决了[Doge]。

参考文章:

https://blog.csdn.net/chenmen...
https://blog.csdn.net//qq_300...

更多精彩内容请关注微信公众号:一个程序员的成长