简体   繁体   English

spring启动时如何处理RequestParam中的大括号

[英]How to handle curly braces in RequestParam in spring boot

I have a spring boot application with a GET service.我有一个带有 GET 服务的 spring 启动应用程序。

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

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

value for subs is an encoded value. subs的值是一个编码值。

If I pass following as value to parameter 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}}

It fails to capture the request and control does not come inside of the function.它无法捕获请求,并且控制不会进入 function 内部。

If we instead pass as value to parameter subs:如果我们改为将值传递给参数 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

It works fine.它工作正常。

  1. Why is this happening?为什么会这样? What's wrong with first encoding?第一次编码有什么问题?

  2. Since server is not able to handle the request, it returns 400. I need to capture such requests and then handle them by encoding them properly.由于服务器无法处理请求,它返回 400。我需要捕获此类请求,然后通过正确编码来处理它们。 What can be way forward?什么可以前进?

I am new to Spring boot/Spring and Java itself.我是 Spring boot/Spring 和 Java 本身的新手。 Would be great if I can get some insight.如果我能获得一些见解,那就太好了。

Also, I can decode both of them online here without any issues- https://www.urldecoder.org/另外,我可以在这里在线解码它们,没有任何问题- https://www.urldecoder.org/

Edit: Basically, the request that has issue getting through has { and } instead of %7B and %7D .编辑:基本上,通过问题的请求有{}而不是%7B%7D

My question is instead of application failing with 400 bad request,how do I capture such requests in my app, encode them properly and then process them.我的问题不是应用程序因 400 个错误请求而失败,而是如何在我的应用程序中捕获此类请求,正确编码然后处理它们。

This is not related to Java nor the Spring itself but the HTML URL Encoding Reference.这与 Java 或 Spring 本身无关,而是与 HTML URL 编码参考相关。 URLs can only be sent over the Internet using the ASCII character set. URL 只能使用 ASCII 字符集通过 Internet 发送。

The unsafe characters are defined in the beginning of RFC-1738 and here is the list:不安全字符在RFC-1738的开头定义,这里是列表:

" < > # % { } | \\ ^ ~ [ ] ` including the blank/empty space. " < > # % { } | \\ ^ ~ [ ] ` 包括空格。

Aside from those, there are also reserved characters where belong the following ones and are used to distinguish the parameters, the key-value representation, the port etc.除此之外,还有属于以下的保留字符,用于区分参数、键值表示、端口等。

; ; / ? / ? : @ = & :@ = &

The unsafe characters you have used are { and } which are equal to %7B and %7D .您使用的不安全字符是{} ,它们等于%7B%7D


Essentially, you should not be concerned about the data the client sends you in the way you describe.本质上,您应该担心客户端以您描述的方式发送给您的数据。 The server must demand the correct form and URL passed.服务器必须要求传递正确的表单和 URL。 Although, the browsers and REST clients encode those characters automatically, sending them programmatically might cause errors.尽管浏览器和 REST 客户端会自动对这些字符进行编码,但以编程方式发送它们可能会导致错误。 The only two available solutions in Spring I am aware of is through registering the CharacterEncodingFilter bean (already answered ) or the Spring-Boot configuration:我所知道的 Spring 中仅有的两个可用解决方案是通过注册CharacterEncodingFilter bean(已回答)或 Spring-Boot 配置:

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

You need to enable the encoding first and force on HTTP requests and responses.您需要先启用编码并强制执行 HTTP 请求和响应。

spring-boot is very much concerned about security. spring-boot 非常关注安全性。 Adding double quote / single quotes or either escaping won't work I guess.我猜添加双引号/单引号或转义都行不通。

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

I think you should try the manual encoding { to %7B and } to %7D我认为您应该尝试手动编码{%7B}%7D

Unsafe:不安全:

Characters can be unsafe for a number of reasons.出于多种原因,字符可能不安全。 The space空间
character is unsafe because significant spaces may disappear and字符是不安全的,因为重要的空格可能会消失并且
insignificant spaces may be introduced when URLs are transcribed or转录 URL 时可能会引入无关紧要的空格或
typeset or subjected to the treatment of word-processing programs.排版或经受文字处理程序的处理。
The characters "<" and ">" are unsafe because they are used as the字符“<”和“>”是不安全的,因为它们被用作
delimiters around URLs in free text;自由文本中 URL 周围的分隔符; the quote mark (""") is used to引号 (""") 用于
delimit URLs in some systems.在某些系统中分隔 URL。 The character "#" is unsafe and should always be encoded because it is used in World Wide Web and in other字符“#”是不安全的,应该始终进行编码,因为它用于万维网和其他
systems to delimit a URL from a fragment/anchor identifier that might follow it.系统将 URL 与可能跟随它的片段/锚标识符分隔开。 The character "%" is unsafe because it is used for字符“%”是不安全的,因为它用于
encodings of other characters.其他字符的编码。 Other characters are unsafe because其他字符是不安全的,因为
gateways and other transport agents are known to sometimes modify网关和其他传输代理有时会修改
such characters.这样的字符。 These characters are "{", "}", "|", "\\", "^", "~",这些字符是“{”、“}”、“|”、“\\”、“^”、“~”、
"[", "]", and "`". “[”、“]”和“`”。

All unsafe characters must always be encoded within a URL.所有不安全的字符必须始终在 URL 中编码。 For为了
example, the character "#" must be encoded within URLs even in例如,字符“#”必须在 URL 中编码,即使是
systems that do not normally deal with fragment or anchor通常不处理片段或锚点的系统
identifiers, so that if the URL is copied into another system that标识符,以便如果 URL 被复制到另一个系统中
does use them, it will not be necessary to change the URL encoding.如果使用它们,则无需更改 URL 编码。

Generally this issue comes when the APP server like Undertow, tomcat, Jboss which is hosting your Springboot application does not allow some special characters, which can very from Server to server.通常,当托管您的 Springboot 应用程序的 APP 服务器(如 Undertow、tomcat、Jboss)不允许某些特殊字符时,会出现此问题,这些字符在服务器之间可能很不一致。 This is done to secure URLs and no one can send some special characters to the server to compromise with its functionality.这样做是为了保护 URL,没有人可以向服务器发送一些特殊字符以损害其功能。

If still want to allow special characters so that those can reach to controller in Springboot application, you need to allow this configuration in APP server.如果在Springboot应用中还想允许特殊字符到达controller,需要在APP服务器中允许这个配置。 eg this is the configuration required in Undertow server to allow special characters in URL:例如,这是 Undertow 服务器中要求的配置,以允许 URL 中的特殊字符:

@Configuration
public class HttpConfig {
    @Bean
    public UndertowServletWebServerFactory servletWebServerFactory() {
        UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
        factory.addBuilderCustomizers((UndertowBuilderCustomizer) builder ->
                builder.setServerOption(UndertowOptions.ALLOW_UNESCAPED_CHARACTERS_IN_URL, Boolean.TRUE));
        return factory;
    }
}

In order to make springboot work well with UTF-8 encoding/decoding of rest URLs, add this configuration in application.properties file, for springboot version 2.6:为了使springboot能够很好的对rest url进行UTF-8编码/解码,在application.properties文件中添加如下配置,对于springboot 2.6版本:

server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
server.servlet.encoding.force-request=true
server.servlet.encoding.force-response=true

Best approach is to encode special characters in the client application which is calling this rest URL to comply with security principles最好的方法是在调用此 rest URL 的客户端应用程序中对特殊字符进行编码以符合安全原则

Due to Tomcat upgraded their security in URL param.由于 Tomcat 升级了他们在 URL 参数中的安全性。 Please find possible solution https://github.com/bohnman/squiggly/issues/42#issuecomment-386658525请找到可能的解决方案https://github.com/bohnman/squiggly/issues/42#issuecomment-386658525

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Spring boot中将多维数组列表处理为@RequestParam - How to handle List of multidimensional array as @RequestParam in Spring boot 如何在Spring Boot中不解码@RequestParam设置的字符串? - How to not decode the string set by @RequestParam in Spring Boot? 初学者-Spring Boot-如何打印@RequestParam - Beginner - Spring boot - how to print @RequestParam 如何在Spring MVC中将多维数组作为@RequestParam处理? - How to handle multidimensional array as @RequestParam in Spring MVC? 如何在Spring MVC验证中禁用消息中的花括号替换 - How to disable curly braces replacement in messages in spring mvc validation Spring Boot发送RequestBody和RequestParam - Spring boot send RequestBody and RequestParam 在 Spring 引导中使用 LocalDateTime RequestParam - Use LocalDateTime RequestParam in Spring boot 如何将未知的传入 requestParam 传递给 spring boot 中的帖子? - How to pass an unknown incoming requestParam to a post in spring boot? Spring 引导 - 如何区分 @PathVariable 和查询参数 (@RequestParam) 的验证 - Spring Boot - how to differentiate between validation for @PathVariable and query params (@RequestParam) 如何在@Requestparam java spring 引导中传递加密值 - How to pass encrypted value in @Requestparam java spring boot
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM