本次斗殴事件起因全副归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...
更多精彩内容请关注微信公众号:一个程序员的成长