使用spring @RequestParam

时间:2016-11-02 15:35:41

标签: spring-mvc spring-boot spring-test

我有一个普通的弹簧@Controller,它将URL编码的字符串作为参数:

@RequestMapping(value = "/wechat/browser", method = GET)
public void askWeChatWhoTheUserIs(@RequestParam(name = "origin") String origin,
                                  HttpServletResponse response) throws IOException {
    //omitted codes
}

当我调试spring boot应用程序并使用浏览器测试端点时:

curl http://localhost:8080/wechat/browser\?origin\=http%3A%2F%2Fwww.example.com%2Findex.html%3Fa%3Db%23%2Froute

origin自动解码并等于http://www.example.com/index.html?a=b#/route

但是当我写一个春季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这次没有被解码。只是想知道为什么它在这两种情况下表现不同。

2 个答案:

答案 0 :(得分:1)

在使用Spring MVC Test框架提供请求参数时,不需要手动编码参数的值,因为没有物理HTTP请求。

因此,只需在测试中使用original 原始值,它就可以正常工作。

换句话说,请使用:

@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
    }
}

答案 1 :(得分:0)

您可以使用此方法,这样便可以正确解码


@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;
    }