【问题标题】:Desserialization of + (plus) in Spring Request ParamSpring Requestparam中+(加号)的反序列化
【发布时间】:2019-04-21 01:12:19
【问题描述】:

我有一个简单的 HTTP GET 请求,如下所示:

http://localhost:8080/search?page=0&size=20&sort=id,asc&description=1+3

还有一个 RestController:

@RequestMapping(value = "/search", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<TestEntity>> search(Pageable pageable, @RequestParam("description") String description) {

    Page<TestEntity> page = service.search(pageable, description);
    HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page);
    return ResponseEntity
            .ok()
            .headers(headers)
            .body(page.getContent());

}

但是@RequestParam“description”的值是“1 3”。

我做错了什么?

或者我应该怎么做才能在Spring@RequestParam中将“+”之类的信号反序列化为“+”?

这是我的 pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
    <project.http.version>1.23.0</project.http.version>
    <project.oauth.version>1.23.0</project.oauth.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>

    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-core</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.8.1</version>
    </dependency>

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

【问题讨论】:

  • 如何发送请求?在浏览器中还是使用工具/命令?
  • 我正在使用 Angular 7 (HttpClient)。
  • 更新我的答案,用于角度使用HttpUrlEncodingCodec.encodeValue("1 3")

标签: java spring rest spring-boot spring-data-rest


【解决方案1】:

一切都如预期的那样。根据 URL 编码中的RFC3986 + 是解码为空格的保留字符。要将+ 用作值,您需要将其编码为%2B,如Percent-encoding reserved characters 中所述。这将使您的网址:

http://localhost:8080/search?page=0&size=20&sort=id,asc&description=1%2B3

请注意,有时 Spring 在处理 + 时会不一致,例如SPR-16860 Spring is inconsistent in the encoding/decoding of URLs 错误。

【讨论】:

  • RFC3986 未指定将+ 解码为空格。相反,它指出,“如果在 URI 组件中找到保留字符,并且该字符没有已知的定界角色,则必须将其解释为表示对应于 US-ASCII 中该字符编码的数据八位字节。”
【解决方案2】:

您缺少与反序列化无关的URL Encoding

+ 由 %2B 编码

当您发送 HTTP 请求时,您应该对参数值进行编码,在您的情况下,+ 应该替换为 %2B

http://localhost:8080/search?page=0&size=20&sort=id,asc&description=1%2B3

角度使用HttpUrlEncodingCodecencodeValue(value: string)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 2018-10-06
    • 1970-01-01
    相关资源
    最近更新 更多