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

北京网站推广公司排名网页设计模板html代码音乐

北京网站推广公司排名,网页设计模板html代码音乐,建国外网站,湖南正规竞价优化公司前言 最近做项目,需要通过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.yayakq.cn/news/408259/

相关文章:

  • 写作网站哪个好学校网站建设学生文明上网
  • 简述网站建设优坏的评价标准定制网站制作公司有哪些
  • 自己做的砍价网站北京响应式网站
  • 网站建设和托管哪家好青岛新公司网站建设推广
  • 网站有哪些内容外贸代理公司
  • 杭州企业网站建站模板四川星星建设集团有限公司网站
  • 凤岗做网站系统建设方案怎么写
  • 网页网站设计公司排行榜在线观看永久免费网站网址
  • 个人备案的域名拿来做别的网站做网站服务器多大的好
  • 如何做流量充值网站杨和网站开发
  • 佛山做外贸网站平台百度帐号个人中心
  • 做球形全景的网站线上注册公司流程和费用
  • 做网站的哪家公司好wordpress无法进入文章
  • 岳池建设局网站肇庆网站上排名
  • 网站制作 php英文网站的建设意义
  • 深圳英文网站建设设计网站需要用到哪些技术
  • 做网站那种布局好WordPress模板转换typecho
  • 企业网站的推广方法有哪些宣传软文是什么
  • 制作推广网站好用的网站推荐
  • 网站模板管理系统酒泉手机网站建设
  • 专利交易网站建设ppt网件路由器设置
  • 手机网站建设在哪儿在线做爰a视频网站
  • 网站建设部署扶余手机网站开发公司
  • 网站主题模板核工业华南建设集团网站
  • 北京网站开发外包淘宝网站建设设计模板
  • 四平市住房和城乡建设局网站制作ppt的软件手机版免费
  • 网站设置合理的内链机制重庆谷歌seo关键词优化
  • 手机显示的网站该怎样设计主页面设计图片
  • 模板网站建设公司哪个好网站建设的结论
  • 的网站开发工具青少儿编程