Spring mvc 与spring@RequestParam的自动解码不一致
我有一个普通的spring@Controller,它将URL编码的字符串作为参数:Spring mvc 与spring@RequestParam的自动解码不一致,spring-mvc,spring-boot,spring-test,Spring Mvc,Spring Boot,Spring Test,我有一个普通的spring@Controller,它将URL编码的字符串作为参数: @RequestMapping(value = "/wechat/browser", method = GET) public void askWeChatWhoTheUserIs(@RequestParam(name = "origin") String origin, HttpServletResponse response) throws
@RequestMapping(value = "/wechat/browser", method = GET)
public void askWeChatWhoTheUserIs(@RequestParam(name = "origin") String origin,
HttpServletResponse response) throws IOException {
//omitted codes
}
当我调试spring启动应用程序并使用浏览器测试端点时:
curl http://localhost:8080/wechat/browser\?origin\=http%3A%2F%2Fwww.example.com%2Findex.html%3Fa%3Db%23%2Froute
原点
自动解码,等于http://www.example.com/index.html?a=b#/route
但是当我编写spring mvc测试时:
@RunWith(SpringRunner.class)
@WebMvcTest(WeChatOauthController.class)
public class WeChatOauthControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void itShouldRedirectToWeChatToFinishOauthProtocol() throws Exception {
String origin = "http://www.example.com/index.html?a=b#/route";
String encodedOrigin = URLEncoder.encode(origin, "UTF-8");
this.mvc.perform(get("/wechat/browser")
.param("origin", encodedOrigin))
.andDo(print())
//omitted codes
}
}
当我调试这个测试和控制器时,
origin
这次没有被解码。只是想知道为什么它在这两种情况下的行为不同。当为Spring MVC测试框架提供请求参数时,不需要手动编码参数的值,因为没有物理HTTP请求
因此,只需在测试中使用原始值,它就可以正常工作
换言之,请使用以下命令:
@RunWith(SpringRunner.class)
@WebMvcTest(WeChatOauthController.class)
public class WeChatOauthControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void itShouldRedirectToWeChatToFinishOauthProtocol() throws Exception {
this.mvc.perform(get("/wechat/browser")
.param("origin", "http://www.example.com/index.html?a=b#/route"))
.andDo(print())
//omitted codes
}
}
您可以使用这种方法,因此将有适当的解码
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class WeChatOauthControllerTest {
@LocalServerPort
private int port;
TestRestTemplate restTemplate = new TestRestTemplate();
@Test
public void testAmpersandEncoded(){
ResponseEntity<String> response =
restTemplate.exchange(createURI("%26"),HttpMethod.GET, null, String.class);
assertEquals(response.getStatusCode(), HttpStatus.OK);
}
private URI createURI(String param){
URI uri = null;
String url = "http://localhost:"+ port +"/location?query=" + param;
try {
uri = new URI(url);
} catch (URISyntaxException e) {
log.error(e.getMessage());
}
return uri;
}
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=SpringBootTest.webEnvironment.RANDOM\u端口)
公共类WechaTouthControllerTest{
@本地服务器端口
专用int端口;
TestRestTemplate restTemplate=新的TestRestTemplate();
@试验
public void testAmpersandEncoded(){
响应性响应=
restemplate.exchange(createURI(“%26”)、HttpMethod.GET、null、String.class);
assertEquals(response.getStatusCode(),HttpStatus.OK);
}
私有URI createURI(字符串参数){
URI=null;
字符串url=”http://localhost:“+port+”/location?query=“+param;
试一试{
uri=新的uri(url);
}捕获(URISyntaxException e){
log.error(例如getMessage());
}
返回uri;
}
“只是想知道为什么它在这两种情况下表现不同”一种情况下你有一个服务器,另一种情况下没有。一种情况下你有一个完全配置的应用程序,而另一种情况下没有。你可能还必须为测试配置URL解码。@zeroflagL很有意义,在spring boot中,我实际上有一个嵌入式tomcat服务器。你能详细说明如何配置URL吗?是的,明白。请继续ied认为,该测试并未揭示其意图,并可能导致对如何使用该终点的误解。