【问题标题】:Why do some characters like brackets cause a 400 BAD REQUEST error in a Spring REST endpoint?为什么某些字符(如括号)会在 Spring REST 端点中导致 400 BAD REQUEST 错误?
【发布时间】:2021-01-25 10:42:00
【问题描述】:

我正在尝试在 Spring 应用程序中调用通过 GET 方法公开的 REST API。发送请求时,我注意到控制器不支持某些字符,并在控制器代码执行之前立即返回 400 BAD_REQUEST 错误。

重现错误的字符:

[]{}|\

以下所有其他字符都不会重现该错误:

&+<>$?!@°*~#"'/

工作请求示例:

http://localhost:8888/api?a=&b=Hello&c=&d=&e=0&f=1

非工作请求示例:

http://localhost:8888/api?a=&b=%5BHello&c=&d=&e=0&f=1

字符串中字符的位置对这个错误没有任何影响。 当上述六个字符之一出现在任何字符串参数中时,就会出现此错误。

这是控制器代码:

@GetMapping
public ResponseEntity<Object> getEmails(
        @RequestParam(required = false, name = "a") String a,
        @RequestParam(required = false, name = "b") String b,
        @RequestParam(required = false, name = "c") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime c,
        @RequestParam(required = false, name = "d") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime d,
        @RequestParam(name = "e") Integer e,
        @RequestParam(name = "f") Integer f
) {
    return new ResponseEntity<>(myService.doSomeStuff(a, b, c, d, e, f), HttpStatus.OK);
}

我们使用 Spring 以及以下 Jackson 依赖项:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.3</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.9.3</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.9.3</version>
    </dependency>

【问题讨论】:

    标签: spring rest get jackson


    【解决方案1】:

    您需要在客户端对 URL 进行编码。

    http://localhost:8083?a=asd[

    你应该得到这个

    http://localhost:8083?a=asd%5B

    客户端通常会提供 URL 编码的功能,请查看其文档。如果您使用 Postman 之类的客户端进行测试,那么您可以在地址栏中右键单击,然后您可以选择对 URL 进行编码。

    [ 等一些字符被认为是允许但不安全的字符,这就是需要编码的原因。

    稍后编辑

    我已经测试了您的代码和请求,一切正常。我所做的唯一更改是在控制器方法中返回字符串而不是响应实体。

    @RestController
    class Ctrl {
        @GetMapping
        public String getEmails(
                @RequestParam(required = false, name = "a") String a,
                @RequestParam(required = false, name = "b") String b,
                @RequestParam(required = false, name = "c") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime c,
                @RequestParam(required = false, name = "d") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime d,
                @RequestParam(name = "e") Integer e,
                @RequestParam(name = "f") Integer f
        ) {
            return "";
        }
    }
    

    curl --location --request GET 'http://localhost:8083?a=&amp;b=%5BHello&amp;c=&amp;d=&amp;e=0&amp;f=1'

    您可以启用 spring 调试/跟踪日志并查看发生了什么。

    【讨论】:

    • 您好,感谢您的回答。我已经发送了一个编码字符串,就像你引用的那样。这是我的客户(邮递员和角度)发送到 API 的编码字符串: /api?a=&b=%5BHello&c=&d=&e=0&f=1 (注意 b 参数的 %5BHello 值)。我在编码中遗漏了什么吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 2015-10-07
    • 2016-05-06
    • 2017-09-26
    • 1970-01-01
    • 2014-05-14
    • 1970-01-01
    相关资源
    最近更新 更多