当前位置: 首页 > news >正文

做网站的教学视频长春seo快速排名

做网站的教学视频,长春seo快速排名,fifa18做sbc的网站,后台管理网站名前言 最近做项目,需要通过GET传参,来实现查询的能力,本来是RPC调用,直接参数序列化即可。但是服务最近修改为HTTP,本来Spring Cloud的feign也可以直接传参数,但是当使用Nginx访问时参数到底传啥呢&#xf…

前言

最近做项目,需要通过GET传参,来实现查询的能力,本来是RPC调用,直接参数序列化即可。但是服务最近修改为HTTP,本来Spring Cloud的feign也可以直接传参数,但是当使用Nginx访问时参数到底传啥呢,笔者传入?list=['xxx']直接就报错了,错误类型

Invalid character found in the request target [/haha?list=[%27haha%27] ]. The valid characters are defined in RFC 7230 and RFC 3986

准备demo

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.18</version></dependency>

demo随意写,写个springboot项目,实际上跟servlet容器有关,Boot默认Tomcat,其他servlet容器可能实现标准不一样而不同。

    @GetMapping("/haha")public String sayHello(List<String> list){return list.toString();}

如果我们自己实现http get,实际上就是针对url的参数解析,说不定?list=['xxx']就不会报错,追根溯源--标准的实现区别。

日志如下

源码分析

查询资料:RFC 7230: Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routingicon-default.png?t=N7T8https://www.rfc-editor.org/rfc/rfc7230

    这个标准定义了400状态码http 1.1协议的一些规则

RFC 3986: Uniform Resource Identifier (URI): Generic Syntax icon-default.png?t=N7T8https://www.rfc-editor.org/rfc/rfc3986     定义了保留字符

   

很不幸[]属于保留字符。

从Tomcat的源码看org.apache.coyote.http11.Http11InputBuffer的parseRequestLine方法。

} else if (parsingRequestLineQPos != -1 && !httpParser.isQueryRelaxed(chr)) {// Avoid unknown protocol triggering an additional errorrequest.protocol().setString(Constants.HTTP_11);// %nn decoding will be checked at the point of decodingString invalidRequestTarget = parseInvalid(parsingRequestLineStart, byteBuffer);throw new IllegalArgumentException(sm.getString("iib.invalidRequestTarget", invalidRequestTarget));
}

逐个字符读取。发现是保留字符则根据标准抛出异常,提示根据什么标准。

 在org.apache.tomcat.util.http.parser.HttpParser的静态代码块中,定义了通常不允许的字符。

static {for (int i = 0; i < ARRAY_SIZE; i++) {// Control> 0-31, 127if (i < 32 || i == 127) {IS_CONTROL[i] = true;}// Separatorif (i == '(' || i == ')' || i == '<' || i == '>' || i == '@' || i == ',' || i == ';' || i == ':' ||i == '\\' || i == '\"' || i == '/' || i == '[' || i == ']' || i == '?' || i == '=' || i == '{' ||i == '}' || i == ' ' || i == '\t') {IS_SEPARATOR[i] = true;}// Token: Anything 0-127 that is not a control and not a separatorif (!IS_CONTROL[i] && !IS_SEPARATOR[i] && i < 128) {IS_TOKEN[i] = true;}// Hex: 0-9, a-f, A-Fif ((i >= '0' && i <= '9') || (i >= 'a' && i <= 'f') || (i >= 'A' && i <= 'F')) {IS_HEX[i] = true;}// Not valid for HTTP protocol// "HTTP/" DIGIT "." DIGITif (i == 'H' || i == 'T' || i == 'P' || i == '/' || i == '.' || (i >= '0' && i <= '9')) {IS_HTTP_PROTOCOL[i] = true;}if (i >= '0' && i <= '9') {IS_NUMERIC[i] = true;}if (i >= 'a' && i <= 'z' || i >= 'A' && i <= 'Z') {IS_ALPHA[i] = true;}if (IS_ALPHA[i] || IS_NUMERIC[i] || i == '+' || i == '-' || i == '.') {IS_SCHEME[i] = true;}if (IS_ALPHA[i] || IS_NUMERIC[i] || i == '-' || i == '.' || i == '_' || i == '~') {IS_UNRESERVED[i] = true;}if (i == '!' || i == '$' || i == '&' || i == '\'' || i == '(' || i == ')' || i == '*' || i == '+' ||i == ',' || i == ';' || i == '=') {IS_SUBDELIM[i] = true;}// userinfo = *( unreserved / pct-encoded / sub-delims / ":" )if (IS_UNRESERVED[i] || i == '%' || IS_SUBDELIM[i] || i == ':') {IS_USERINFO[i] = true;}// The characters that are normally not permitted for which the// restrictions may be relaxed when used in the path and/or query// string// 明确定义通常不允许使用的字符,当然也可以放开限制,当为路径或者查询参数if (i == '\"' || i == '<' || i == '>' || i == '[' || i == '\\' || i == ']' || i == '^' || i == '`' ||i == '{' || i == '|' || i == '}') {IS_RELAXABLE[i] = true;}}DEFAULT = new HttpParser(null, null);}

至此我们知道了数组和集合使用get传参报错的原因:明确定义通常不允许使用的字符,当然也可以放开限制,当为路径或者查询参数。 

解决办法

解决办法也简单了,解析参数规避'[' ']'这样的字符即可,比如string默认tolist,使用string,string传list或者数组对象等,解析规则实际上我们甚至可以自定义,参考Tomcat或者springboot的规则。

比如使用字符串:实际上springboot就是这么做的,tomcat毕竟GET仅传递String字段,各种参数类型都是后面Springboot转换的

 如果使用List直接注入,那么因为没有构造函数,报错,毕竟接口类型,反射无法初始化对象。

因为Springboot会反射解析对象,所以即使使用ArrayList也不能解析参数,因为默认情况仅能解析String

 只有@RequestParam绑定参数key才行

因为解析器不一样,具体就不分析了,涉及Springmvc的设计。

 

数组或者集合使用,分割。

 

实际上还有其他办法:我们可以放开限制,只需要注入HttpParser即可

在tomcat协议定义里面org.apache.coyote.http11.AbstractHttp11Protocol

定义了

那么我们只要注入这2个值即可,第一个是路径字符,第2个是查询字符,根据最小修改原则,此处注入查询参数。根据Springboot自动装配org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration的属性注入即可

 application.properties文件

server.tomcat.relaxedQueryChars=<,>,[,\,],^,`,{,|,}

即可实现放开限制

 

但是tomcat认为'[' ']'是字符串的字符,以,逗号分割。

 

并不符合我们的直观感受,所以还是一个原则,只不过是允许'[' ']'这样的字符了。  

总结

通过tomcat GET传参数,尤其是数组或者集合,发现tomcat实现了很多开源标准,预估其他servlet容器也差不多,如果是我们自己实现servlet容器解析http协议包,那么这些标准估计是不会去实现的,开源的能力定义了一系列标准并且基本上都实现了。而Springboot在tomcat标准的基础上转换了各种类型,实现了方便快速的开发。

http://www.dinnco.com/news/15769.html

相关文章:

  • 网站为什么做重定向惠州seo报价
  • 360免费网站建设网络营销的特点有
  • 内蒙古网上办事大厅官网网站seo优化软件
  • 彩票网站的代理怎么做seo按照搜索引擎的
  • 有域名 有固定ip怎么做网站网络推广优化方案
  • wordpress整合问答系统seo项目完整流程
  • 做网站域名是赠送的吗营销技巧和营销方法视频
  • 外语网站开发短视频剪辑培训班多少钱
  • 营业执照申请网站电商网站建设平台
  • 网站 一般 用什么空间哈尔滨最新信息
  • 软件网站关键词优化最好用的搜索引擎排名
  • 做网站利润旺道智能seo系统
  • wordpress 空行网站页面优化内容包括哪些
  • 防止服务器上的网站被进攻网络营销公司经营范围
  • 页面设计介绍信息如何优化上百度首页
  • 一个商城网站开发周期外呼系统电销
  • 网站增加权重吗seocms
  • 湖南省人民政府网站官网农产品推广方案
  • 企业网站pr值低怎么办磁力帝
  • 网站建设什么公司好特色产品推广方案
  • 做爰全过程免费的网站视频百度竞价推广自己可以做吗
  • 通用网址查询网站今日要闻
  • 毕设代做有哪些靠谱网站今天最新消息
  • 如何购买网站虚拟主机短链接在线生成免费
  • 国内大的做网站的公司广州网站制作公司
  • 怎么做asp动态网站企业培训课程体系
  • 河南软件开发app制作公司营销网站seo推广
  • 有男女做暖暖的视频网站seo课堂
  • 门户网站做免费相亲的优化防疫政策
  • 建行网址多少关键词优化哪个好