如何在Spring Boot中处理RequestParam中的花括号

时间:2019-01-02 11:29:52

标签: java spring spring-boot url character-encoding

我有一个带有GET服务的Spring Boot应用程序。

@RequestMapping(value = "/abc/track/{type}", method = RequestMethod.GET)

    public void DummFunc(                            
          @RequestParam(value="subs", required = false) String sub,
,  HttpServletResponse response) {}
subs

值是一个编码值。

如果我将以下作为值传递给参数subs

{%22endpoint%22:%22https://def.abc.com/tyu/send/eD3vpGNQW28:APA91bHOo8rYrV0xccdQz3okjZJG-QGrJX8LG6ahJnEUpMNfGedqi3hJxQsJx_8BMbH6oDjaSPPEXqzNWchWrGSkhuTkSdemikkys1U22Ipd7MsRw0owWbw89V2fslIVAJ6G5lkyvYuQ%22,%22expirationTime%22:null,%22keys%22:{%22p256dh%22:%22BK0pktn50CMsTQtqwdPlKlJtdFs0LFeXX14T1zgoz6QWnvSTp5dxtChnUP5P1JX0TsjcopbdPKyN31HfABMUyic%22,%22auth%22:%22qbO_z0vGao9wD-E5g8VU-A%22}}

它无法捕获请求,并且控件不在函数内部。

如果我们改为将值作为值传递给参数subs:

%7B%22endpoint%22:%22https://def.abc.com/tyu/send/dX5q5eV7hFQ:APA91bHib-0QXrMzjatcvTR_uaIeeJK8lf6GmXUC9Jxv0Oxth-BzD4GmWnd4-YpDZv8qSFZ0eSg9mB2YkRvkc5ezdXW5KeaHjuQZfdyDxyBXjJgE-25Xbtlk37pdm8vfLk20k0k_VxW9%22,%22expirationTime%22:null,%22keys%22:%7B%22p256dh%22:%22BCCvcBLpRqp4u0auP688_MUJLsAiwWlQSn5kpyl8YVsEo_J-KpSdnhCmVIE_BhDXBcFYflPK52hqhYf3EaOCyuY%22,%22auth%22:%22iKuW_ESkCZnubWcQu_JK8w%22%7D%7D

它工作正常。

  1. 为什么会这样?第一次编码有什么问题?

  2. 由于服务器无法处理该请求,因此它返回400。我需要捕获此类请求,然后通过对它们进行正确的编码来处理它们。前进的方向是什么?

我是Spring Boot / Spring和Java本身的新手。如果我能获得一些见识,那就太好了。

此外,我可以在此处在线解码两个文件,而不会出现任何问题-https://www.urldecoder.org/

编辑:基本上,遇到问题的请求具有{}而不是%7B%7D

我的问题不是使用400错误请求而不是应用程序失败,而是如何在我的应用程序中捕获此类请求,对其进行正确编码然后进行处理。

3 个答案:

答案 0 :(得分:2)

这与Java或Spring本身无关,但与HTML URL编码参考无关。 URL只能使用ASCII字符集通过Internet发送。

不安全字符定义在RFC-1738的开头,这是列表:

  

“ <>#%{} | \ ^〜[]`包括空格/空白。

除了这些以外,还有保留字符,它们属于以下字符,用于区分参数,键值表示形式,端口等。

  

; /? :@ =&

您使用的不安全字符是{},它们等于%7B%7D


从本质上讲,您应该不要担心客户端以您描述的方式发送给您的数据。服务器必须要求传递正确的格式和URL。尽管浏览器和REST客户端会自动对这些字符进行编码,但是以编程方式发送它们可能会导致错误。我知道,Spring中仅有的两个可用解决方案是通过注册CharacterEncodingFilter bean(已经是answered)或Spring-Boot配置:

spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true

您需要先启用编码,然后对HTTP请求和响应强制执行。

答案 1 :(得分:0)

spring-boot非常关心安全性。我猜添加双引号/单引号或转义将不起作用。

请通过:https://tools.ietf.org/html/rfc1738

我认为您应该尝试将{手动编码为%7B,将}手动编码为%7D

  

不安全:

     

出于多种原因,字符可能是不安全的。空间
  字符是不安全的,因为重要的空格可能会消失并且
  转录URL时可能会引入无关紧要的空格或
  排版或经受文字处理程序的处理。
  字符“ <”和“>”是不安全的,因为它们被用作
  自由文本网址周围的分隔符;引号(“”“)用于
  在某些系统中分隔URL。字符“#”不安全,应   总是被编码,因为它被用于万维网和其他
  系统从片段/锚标识符中分隔URL,这可能   跟着它。字符“%”不安全,因为它用于
  其他字符的编码。其他字符不安全,因为
  已知网关和其他传输代理有时会修改
  这样的字符。这些字符是“ {”,“}”,“ |”,“ \”,“ ^”,“〜”,
  “ [”,“]”和“`”。

     

所有不安全字符必须始终在URL中编码。对于
  例如,即使在
中,字符“#”也必须在URL中编码   通常不处理片段或锚点的系统
  标识符,以便将URL复制到另一个系统中,
  确实使用它们,则无需更改URL编码。

答案 2 :(得分:0)

由于 Tomcat 升级了他们在 URL 参数中的安全性。 请找到可能的解决方案 https://github.com/bohnman/squiggly/issues/42#issuecomment-386658525