【问题标题】:Spring boot TestRestTemplate doesn't URL decode requestparam valuesSpring boot TestRestTemplate 不 URL 解码 requestparam 值
【发布时间】:2017-07-11 11:23:00
【问题描述】:

设置:

  • Spring Boot + SpringBootApplication; Spring Boot Test + TestRestTemplate 进行测试
  • 1 个端点,由方法 foo 处理。
  • 输入:1 个必需的请求参数(名为 q),必须在 URI 中进行 URL 编码。
  • 输出:(foo) 只返回字符串 (q)。 foo 没有进行任何处理。

如果我启动服务器并使用 URL 编码值卷曲端点,我会在响应中获得非 URL 编码值。

如果我使用 TestRestTemplate 查询完全相同的内容,foo 会获取一个 URL 编码的值来处理,并且在现实世界中事情开始出错...

com.example.App

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class App {

    @RequestMapping(path = "/test")
    public String foo(@RequestParam("q") String val) {
        return val;
    }

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

com.example.TestApp

package com.example;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class TestApp {

    @Autowired
    private TestRestTemplate rest;

    @Test
    public void testIt() {
        URI uri = UriComponentsBuilder.fromPath("/test")
            .queryParam("q", BIG_STR)
            .build().encode().toUri();
        System.out.println("URI: " + uri);
        ResponseEntity<String> res = rest.getForEntity(uri, String.class);
        System.out.println("resBody: " + res.getBody());
    }

    private static String BIG_STR = "[ { \"_id\": \"58ac70a1d998ec63dc004158\", \"index\": 0, \"guid\": \"68124ce4-6a65-4459-8189-f245236399a9\", \"isActive\": true, \"balance\": \"$3,415.67\", \"picture\": \"http://placehold.it/32x32\", \"age\": 36, \"eyeColor\": \"brown\", \"name\": \"Bobbi Barr\", \"gender\": \"female\", \"company\": \"ACCUPHARM\", \"email\": \"bobbibarr@accupharm.com\", \"phone\": \"+1 (938) 592-3835\", \"address\": \"551 Lester Court, Sedley, South Carolina, 3698\", \"about\": \"Dolor deserunt nostrud ipsum sunt aute elit exercitation tempor eu ipsum. Dolor magna nisi incididunt sit non mollit ut aliqua. Magna est officia veniam sit deserunt eiusmod consectetur do dolore et ea aliquip. Magna velit tempor est dolore sint voluptate. Et enim cillum voluptate nisi est non. Non enim amet ad qui cillum ipsum ipsum magna id nostrud cillum amet esse.\\r\\n\", \"registered\": \"2014-08-05T12:07:38 +07:00\", \"latitude\": -79.673386, \"longitude\": -30.821609, \"tags\": [ \"aute\", \"consequat\", \"veniam\", \"exercitation\", \"quis\", \"proident\", \"mollit\" ], \"friends\": [ { \"id\": 0, \"name\": \"Carolina Barton\" }, { \"id\": 1, \"name\": \"Glover Gibbs\" }, { \"id\": 2, \"name\": \"Simpson Hicks\" } ], \"greeting\": \"Hello, Bobbi Barr! You have 2 unread messages.\", \"favoriteFruit\": \"banana\" } ]";
}

build.gradle

apply plugin: 'java'

repositories {
  mavenCentral()
}

dependencies {
  compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.1.RELEASE'

  testCompile group: 'junit', name: 'junit', version: '4.+'
  testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '1.5.1.RELEASE'
}

服务器启动+curl的输出:

curl -i "http://localhost:8080/test?q=%5B%20%7B%20%22_id%22:%20%2258ac70a1d998ec63dc004158%22,%20%22index%22:%200,%20%22guid%22:%20%2268124ce4-6a65-4459-8189-f245236399a9%22,%20%22isActive%22:%20true,%20%22balance%22:%20%22$3,415.67%22,%20%22picture%22:%20%22http://placehold.it/32x32%22,%20%22age%22:%2036,%20%22eyeColor%22:%20%22brown%22,%20%22name%22:%20%22Bobbi%20Barr%22,%20%22gender%22:%20%22female%22,%20%22company%22:%20%22ACCUPHARM%22,%20%22email%22:%20%22bobbibarr@accupharm.com%22,%20%22phone%22:%20%22%2B1%20(938)%20592-3835%22,%20%22address%22:%20%22551%20Lester%20Court,%20Sedley,%20South%20Carolina,%203698%22,%20%22about%22:%20%22Dolor%20deserunt%20nostrud%20ipsum%20sunt%20aute%20elit%20exercitation%20tempor%20eu%20ipsum.%20Dolor%20magna%20nisi%20incididunt%20sit%20non%20mollit%20ut%20aliqua.%20Magna%20est%20officia%20veniam%20sit%20deserunt%20eiusmod%20consectetur%20do%20dolore%20et%20ea%20aliquip.%20Magna%20velit%20tempor%20est%20dolore%20sint%20voluptate.%20Et%20enim%20cillum%20voluptate%20nisi%20est%20non.%20Non%20enim%20amet%20ad%20qui%20cillum%20ipsum%20ipsum%20magna%20id%20nostrud%20cillum%20amet%20esse.%5Cr%5Cn%22,%20%22registered%22:%20%222014-08-05T12:07:38%20%2B07:00%22,%20%22latitude%22:%20-79.673386,%20%22longitude%22:%20-30.821609,%20%22tags%22:%20%5B%20%22aute%22,%20%22consequat%22,%20%22veniam%22,%20%22exercitation%22,%20%22quis%22,%20%22proident%22,%20%22mollit%22%20%5D,%20%22friends%22:%20%5B%20%7B%20%22id%22:%200,%20%22name%22:%20%22Carolina%20Barton%22%20%7D,%20%7B%20%22id%22:%201,%20%22name%22:%20%22Glover%20Gibbs%22%20%7D,%20%7B%20%22id%22:%202,%20%22name%22:%20%22Simpson%20Hicks%22%20%7D%20%5D,%20%22greeting%22:%20%22Hello,%20Bobbi%20Barr20You%20have%202%20unread%20messages.%22,%20%22favoriteFruit%22:%20%22banana%22%20%7D%20%5D"
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 1194
Date: Tue, 21 Feb 2017 17:19:26 GMT

[ { "_id": "58ac70a1d998ec63dc004158", "index": 0, "guid": "68124ce4-6a65-4459-8189-f245236399a9", "isActive": true, "balance": ",415.67", "picture": "http://placehold.it/32x32", "age": 36, "eyeColor": "brown", "name": "Bobbi Barr", "gender": "female", "company": "ACCUPHARM", "email": "bobbibarr@accupharm.com", "phone": "+1 (938) 592-3835", "address": "551 Lester Court, Sedley, South Carolina, 3698", "about": "Dolor deserunt nostrud ipsum sunt aute elit exercitation tempor eu ipsum. Dolor magna nisi incididunt sit non mollit ut aliqua. Magna est officia veniam sit deserunt eiusmod consectetur do dolore et ea aliquip. Magna velit tempor est dolore sint voluptate. Et enim cillum voluptate nisi est non. Non enim amet ad qui cillum ipsum ipsum magna id nostrud cillum amet esse.\r\n", "registered": "2014-08-05T12:07:38 +07:00", "latitude": -79.673386, "longitude": -30.821609, "tags": [ "aute", "consequat", "veniam", "exercitation", "quis", "proident", "mollit" ], "friends": [ { "id": 0, "name": "Carolina Barton" }, { "id": 1, "name": "Glover Gibbs" }, { "id": 2, "name": "Simpson Hicks" } ], "greeting": "Hello, Bobbi Barr20You have 2 unread messages.", "favoriteFruit": "banana" } ]

集成测试的日志输出:

2017-02-21 09:28:17.912  INFO 51360 --- [           main] com.example.TestApp                      : Started TestApp in 2.016 seconds (JVM running for 2.598)
URI: /test?q=%5B%20%7B%20%22_id%22:%20%2258ac70a1d998ec63dc004158%22,%20%22index%22:%200,%20%22guid%22:%20%2268124ce4-6a65-4459-8189-f245236399a9%22,%20%22isActive%22:%20true,%20%22balance%22:%20%22$3,415.67%22,%20%22picture%22:%20%22http://placehold.it/32x32%22,%20%22age%22:%2036,%20%22eyeColor%22:%20%22brown%22,%20%22name%22:%20%22Bobbi%20Barr%22,%20%22gender%22:%20%22female%22,%20%22company%22:%20%22ACCUPHARM%22,%20%22email%22:%20%22bobbibarr@accupharm.com%22,%20%22phone%22:%20%22%2B1%20(938)%20592-3835%22,%20%22address%22:%20%22551%20Lester%20Court,%20Sedley,%20South%20Carolina,%203698%22,%20%22about%22:%20%22Dolor%20deserunt%20nostrud%20ipsum%20sunt%20aute%20elit%20exercitation%20tempor%20eu%20ipsum.%20Dolor%20magna%20nisi%20incididunt%20sit%20non%20mollit%20ut%20aliqua.%20Magna%20est%20officia%20veniam%20sit%20deserunt%20eiusmod%20consectetur%20do%20dolore%20et%20ea%20aliquip.%20Magna%20velit%20tempor%20est%20dolore%20sint%20voluptate.%20Et%20enim%20cillum%20voluptate%20nisi%20est%20non.%20Non%20enim%20amet%20ad%20qui%20cillum%20ipsum%20ipsum%20magna%20id%20nostrud%20cillum%20amet%20esse.%5Cr%5Cn%22,%20%22registered%22:%20%222014-08-05T12:07:38%20%2B07:00%22,%20%22latitude%22:%20-79.673386,%20%22longitude%22:%20-30.821609,%20%22tags%22:%20%5B%20%22aute%22,%20%22consequat%22,%20%22veniam%22,%20%22exercitation%22,%20%22quis%22,%20%22proident%22,%20%22mollit%22%20%5D,%20%22friends%22:%20%5B%20%7B%20%22id%22:%200,%20%22name%22:%20%22Carolina%20Barton%22%20%7D,%20%7B%20%22id%22:%201,%20%22name%22:%20%22Glover%20Gibbs%22%20%7D,%20%7B%20%22id%22:%202,%20%22name%22:%20%22Simpson%20Hicks%22%20%7D%20%5D,%20%22greeting%22:%20%22Hello,%20Bobbi%20Barr!%20You%20have%202%20unread%20messages.%22,%20%22favoriteFruit%22:%20%22banana%22%20%7D%20%5D
2017-02-21 09:28:18.002  INFO 51360 --- [o-auto-1-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2017-02-21 09:28:18.002  INFO 51360 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2017-02-21 09:28:18.013  INFO 51360 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 11 ms
resBody: %5B%20%7B%20%22_id%22:%20%2258ac70a1d998ec63dc004158%22,%20%22index%22:%200,%20%22guid%22:%20%2268124ce4-6a65-4459-8189-f245236399a9%22,%20%22isActive%22:%20true,%20%22balance%22:%20%22$3,415.67%22,%20%22picture%22:%20%22http://placehold.it/32x32%22,%20%22age%22:%2036,%20%22eyeColor%22:%20%22brown%22,%20%22name%22:%20%22Bobbi%20Barr%22,%20%22gender%22:%20%22female%22,%20%22company%22:%20%22ACCUPHARM%22,%20%22email%22:%20%22bobbibarr@accupharm.com%22,%20%22phone%22:%20%22%2B1%20(938)%20592-3835%22,%20%22address%22:%20%22551%20Lester%20Court,%20Sedley,%20South%20Carolina,%203698%22,%20%22about%22:%20%22Dolor%20deserunt%20nostrud%20ipsum%20sunt%20aute%20elit%20exercitation%20tempor%20eu%20ipsum.%20Dolor%20magna%20nisi%20incididunt%20sit%20non%20mollit%20ut%20aliqua.%20Magna%20est%20officia%20veniam%20sit%20deserunt%20eiusmod%20consectetur%20do%20dolore%20et%20ea%20aliquip.%20Magna%20velit%20tempor%20est%20dolore%20sint%20voluptate.%20Et%20enim%20cillum%20voluptate%20nisi%20est%20non.%20Non%20enim%20amet%20ad%20qui%20cillum%20ipsum%20ipsum%20magna%20id%20nostrud%20cillum%20amet%20esse.%5Cr%5Cn%22,%20%22registered%22:%20%222014-08-05T12:07:38%20%2B07:00%22,%20%22latitude%22:%20-79.673386,%20%22longitude%22:%20-30.821609,%20%22tags%22:%20%5B%20%22aute%22,%20%22consequat%22,%20%22veniam%22,%20%22exercitation%22,%20%22quis%22,%20%22proident%22,%20%22mollit%22%20%5D,%20%22friends%22:%20%5B%20%7B%20%22id%22:%200,%20%22name%22:%20%22Carolina%20Barton%22%20%7D,%20%7B%20%22id%22:%201,%20%22name%22:%20%22Glover%20Gibbs%22%20%7D,%20%7B%20%22id%22:%202,%20%22name%22:%20%22Simpson%20Hicks%22%20%7D%20%5D,%20%22greeting%22:%20%22Hello,%20Bobbi%20Barr!%20You%20have%202%20unread%20messages.%22,%20%22favoriteFruit%22:%20%22banana%22%20%7D%20%5D

知道发生了什么吗?

【问题讨论】:

    标签: spring-boot spring-boot-test


    【解决方案1】:

    您正在点击this bug。您可以通过使用 String 而不是 URI 调用 TestRestTemplate 来避免此问题。

    【讨论】:

    • 感谢您的指点。我将代码更改为使用 String uri = ...toUriString() 但仍然有同样的问题。看起来修复程序将在 3 月 2 日发布,所以我可能会等待 ^^
    • 那么您可能会遇到不同的问题。请尝试使用来自repo.spring.io/libs-snapshot 的 1.5.2.BUILD-SNAPSHOT 并检查问题是否已修复。
    • 1.5.2.BUILD-SNAPSHOT:使用 URI;当我不在 UriComponentsBuilder 上调用 encode() 时,也可以使用字符串。当我在 toUriString 之前不调用 encode() 时,1.5.1.RELEASE 也适用于字符串...我想 TestRestTemplate 在内部对字符串 url 进行编码...我认为最好让调用者确定是否应该对 URI/URL 进行编码,而不是在 TestRestTemplate 中进行额外的编码...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2018-04-15
    • 2022-01-15
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多