本次斗殴事件起因全副归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拦挡到的。
这里也举荐大家当前尽量这样去配置。
@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;
}
}
我与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,确保申请进来之后先走它。
@Bean
public 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…
更多精彩内容请关注微信公众号:一个程序员的成长
发表回复