关键词:
本次斗殴事件起因全部归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...
更多精彩内容请关注微信公众号:一个程序员的成长
Azure 逻辑应用 HTTP 请求 500
...序的新手,所以这个示例可能看起来没什么用,但它只是为了学习一些基本的Azure逻辑。我有一个简单的HTTP监听器(当收到一个HTTP请求时)比它应该向某个服务发送另一个HTTPGET请求并向第一个调用者发送响应。它看起来像这样... 查看详情
因为一个跨域请求,我差点丢了饭碗(代码片段)
浏览器基本原理我叫小风,是Windows帝国一个普通的上班族。今天,我入职了一家浏览器公司,公司的主营业务是为人类提供Internet上网服务,我的岗位是负责执行JavaScript代码。上午的晨会上,认识了负责网络连接的老白,所有... 查看详情
因为一个跨域请求,我差点丢了饭碗(代码片段)
浏览器基本原理我叫小风,是Windows帝国一个普通的上班族。今天,我入职了一家浏览器公司,公司的主营业务是为人类提供Internet上网服务,我的岗位是负责执行JavaScript代码。上午的晨会上,认识了负责网络连接的老白,所有... 查看详情
http协议
...有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法Http协议的组成Http协议由Http请求和Http响应组成,当在浏览器中输入网址访问某个网站时,你的浏览器会将你的请求封装成一个Http请... 查看详情
http2.0一篇就够了(代码片段)
...览器能够出现这么丰富多彩的内容,最初的设定,仅仅是为了发布和共享文件,根本不会考虑"交互"的体验问题,压根想象不到当今的浏览器客户端一个页面下来,会产生这么多的请求。当初的设定很简单:只是为了让欧洲的学... 查看详情
http2.0一篇就够了(代码片段)
...览器能够出现这么丰富多彩的内容,最初的设定,仅仅是为了发布和共享文件,根本不会考虑"交互"的体验问题,压根想象不到当今的浏览器客户端一个页面下来,会产生这么多的请求。当初的设定很简单:只是为了让欧洲的学... 查看详情
http2.0一篇就够了(代码片段)
...览器能够出现这么丰富多彩的内容,最初的设定,仅仅是为了发布和共享文件,根本不会考虑"交互"的体验问题,压根想象不到当今的浏览器客户端一个页面下来,会产生这么多的请求。当初的设定很简单:只是为了让欧洲的学... 查看详情
http2.0一篇就够了(代码片段)
...览器能够出现这么丰富多彩的内容,最初的设定,仅仅是为了发布和共享文件,根本不会考虑"交互"的体验问题,压根想象不到当今的浏览器客户端一个页面下来,会产生这么多的请求。当初的设定很简单:只是为了让欧洲的学... 查看详情
一个http连接是包含两部分的,请求报文和响应报文这俩组合起来才是一次完整的http请求,并不会单独显示请求报文或者响应报文
一个HTTP连接是包含两部分的,请求报文和响应报文这俩组合起来才是一次完整的HTTP请求,并不会单独显示请求报文或者响应报文。 2.注意看,一次HTTP请求,是包括这两部分的 查看详情
http基础(代码片段)
...挂(trailer)部分的首部集合。Transfer-Encoding:告知接收端为了保 查看详情
图解http(代码片段)
...1.0:GET,POST和HEAD方法。缺点是连接后只能发送一个请求。为了复用连接,使用一个非标准字段:Connection:keep-alive,但这样并不保险。HTTP/1.0为每一次HTTP的请求/响应建立一条新的TCP链接,因此一个包含HTML内容和图片的页面将需要... 查看详情
以http和https协议发布请求(代码片段)
...提供任何信息答案HTTP请求和HTTPS请求之间的唯一区别是第一个是通过普通TCP连接发送而另一个是通过TLS连接发送,即:使用HTTP建立TCP连接并通过此连接发送请求使用HTTPS建立TCP连接,将此连接升级到TLS(包括正确的证书验证等等... 查看详情
纯粹为了使用http请求正文而发布(代码片段)
...真)。这绝对感觉像是对我的GET请求,但我考虑POST只是为了我可以利用请求体的使用来躲避URL长度限制的任何限制。绕过这种限制的宁静方式是什么?答案在这种情况下,你绝对可以使用POST。你的两个假设都是正确的。GET中的... 查看详情
全干工程师神器-jmeter05-jmeter配置元件(代码片段)
...P请求默认值设定一些缺省值、默认值假如,我们创建一个测试计划有很多个HTTP请求,且都是发送到相同的server& 查看详情
http的发展史及其核心问题
...问题。http最初的版本是http0.9,如它的名字定义,主要是为了解决超文本(Html)内容传输问题协议定义了客户端发起请求、服务端响应请求的通信模式。随着浏览器和互联网的发展,单文本类型的传输已经无法满足通信的需求,... 查看详情
因为一个跨域请求,我差点丢了饭碗!
...Storage,SessionStorage之类的都归他管。哦,差点忘了,还有一个妹子小雪,她负责网页渲染。随后主管安排了我的工作:老白从网络取回网页之后交 查看详情
http传输编码增加了传输量,只为解决这一个问题|实用http(代码片段)
...实际问题出发,来分析这些HTTP协议的使用方式,到底是为了解决什么问题?同时讲解它是如 查看详情
http传输编码增加了传输量,只为解决这一个问题|实用http(代码片段)
...实际问题出发,来分析这些HTTP协议的使用方式,到底是为了解决什么 查看详情