RestTemplate 不要转义 url
RestTemplate 不要转义 url
我成功地使用Spring RestTemplate,代码如下:
String url = "http://example.com/path/to/my/thing/{parameter}"; ResponseEntityresponse = restTemplate.postForEntity(url, payload, MyClass.class, parameter);
这个方法很好用。
然而,有时候parameter
是%2F
。我知道这不是理想的,但事实就是这样。正确的URL应该是:http://example.com/path/to/my/thing/%2F
,但当我将parameter
设置为"%2F"
时,它会被双重转义成http://example.com/path/to/my/thing/%252F
。我该如何防止这种情况发生?
RestTemplate不对URL进行转义的原因是因为模板参数被假定为需要编码。解决方法是使用UriComponentsBuilder构建一个URI对象,而不是直接使用String类型的URL。可以通过调用UriComponentsBuilder的build方法来指示是否对URL进行编码。另一种解决方法是使用String的replace方法替换URL中的参数,并创建一个URI对象。具体实现代码如下:
String url = "http://example.com/path/to/my/thing/{parameter}"; String parameter = "%2F"; url = url.replace("{parameter}", parameter); URI uri = new URI(url); System.out.println(uri);
通过这种方式创建的URI对象可以作为postForObject方法的第一个参数使用。除此之外,还可以使用UriComponentsBuilder的fromUriString方法来构建URI对象,这种方式可以接受形如"/path/without/host"的URI形式,这在使用Spring的MockMvc进行测试时非常有用。需要注意的是,RestTemplate的文档中有一条注意事项提到了这个问题,但是它应该至少在Javadoc中进行记录。
RestTemplate to NOT escape url的问题出现的原因是RestTemplate会自动对URL进行转义,导致已经进行过编码的URL再次被转义,从而导致请求失败。解决方法是告诉RestTemplate,URL已经被编码过了,不需要再次转义。
具体的解决方法如下:
1. 首先,将需要进行请求的URL中的参数进行编码,例如将"{parameter}"替换为"%2F"。
2. 使用UriComponentsBuilder类创建一个新的URI对象,传入编码后的URL。
3. 调用UriComponentsBuilder的build方法,将参数设置为true,表示URL已经被编码过了。
4. 将生成的URI对象传入RestTemplate的相关方法中进行请求。
代码示例:
String url = "http://example.com/path/to/my/thing/{parameter}"; url = url.replace("{parameter}", "%2F"); UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url); // Indicate that the components are already escaped URI uri = builder.build(true).toUri(); ResponseEntityresponse = restTemplate.postForEntity(uri, payload, MyClass.class, parameter);
通过以上方法,可以告诉RestTemplate不要对URL进行转义,从而解决RestTemplate to NOT escape url的问题。