返回顶部
首页 > 资讯 > 精选 >如何解决RestTemplate请求url中包含百分号会被转义成25的问题
  • 571
分享到

如何解决RestTemplate请求url中包含百分号会被转义成25的问题

2023-06-25 11:06:46 571人浏览 独家记忆
摘要

小编给大家分享一下如何解决RestTemplate请求url中包含百分号会被转义成25的问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!RestTemplate

小编给大家分享一下如何解决RestTemplate请求url中包含百分号会被转义成25的问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

RestTemplate 请求url中包含百分号 会被转义成25

最初使用RestTemplate 进行远程调用方法如下:

private String getRemoteData(String url) {  logger.info("Request URL :" + url + "|");   String resp = rest.getForObject(url, String.class);   logger.info("Response result : " + resp.toString());  return resp; }

但发现请求结果一直为空。

最后发现由于我们的业务场景中,请求参数包含中文要求按指定规则转码,导致请求url中包含% ,而RestTemplate会自动调用encode方法进行转义,将%转义成了%25 。

解决方法

自建URI 传入:

private String getRemoteData(String url) {  logger.info("Request URL :" + url + "|");  String resp = null;  try {   URI uri = new URI(url);   resp = rest.getForObject(uri, String.class);  } catch (URISyntaxException e) {   logger.error("Create URI Exception !");  }   logger.info("Response result : " + resp.toString());  return resp; }

RestTemplate转码bug

发现一个关于Http的Get请求的罕见bug。

转码问题的背景

需要向tigergraph服务端发送一个复杂的get请求,参数只有一个,但是参数的值是一个复杂JSON

服务端收到的值始终是不正常的值。观察发现,不正常地方在于服务端本应解析为空格的地方都变成了加号(+)。

以为是代码写得有问题,然后使用HTTPclient的原生的方式发起请求:

public static String doGet(String url) throws Exception{        HttpGet get = new HttpGet(url);        return doMethod(get);    }    private static String doMethod(HttpRequestBase method)throws Exception{        CloseableHttpResponse response = null;        CloseableHttpClient client;        HttpClientBuilder hcb = HttpClientBuilder.create();        HttpRequestRetryHandler hrrh = new DefaultHttpRequestRetryHandler();        HttpClientBuilder httpClientBuilder = hcb.setRetryHandler(hrrh);        client = httpClientBuilder.build();        method.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; windows NT 5.1;SV1)");        method.addHeader(HTTP.CONTENT_TYPE, APPLICATION_jsON);        RequestConfig.Builder confBuilder = RequestConfig.custom();        confBuilder.setConnectTimeout(CONNECT_TIMEOUT);        confBuilder.setConnectionRequestTimeout(REQUEST_TIMEOUT);        confBuilder.setSocketTimeout(SOCKET_TIMEOUT);        RequestConfig config = confBuilder.build();        method.setConfig(config);        response = client.execute(method);        int code = response.getStatusLine().getStatusCode();        String result = EntityUtils.toString(response.getEntity());        response.close();        client.close();        return result;    }

得到结果还是这个问题,使用Assured测试工具构建http请求也有这问题。

结论

后来仔细检查了URLEncode.encode方法和RestTemplate源码实现后,发现是客户端的转码协议和服务端的解码协议不匹配导致。

经反复测试和严重,这个问题只有参数中带有空格时才会有,其他字符都不有,比如: / * & 这类特殊字符都没这问题。

最后的解决方案是替换URL串的转码后的字符串中的空格为%20,然后使用http client原生的请求方式。

第二个解决方案是使用RestTemplate的UriComponentsBuilder类,使用(builder.build(false).toUri()获得URL,参数必须是false才会把空格转成%20

  @Override    @SuppressWarnings("all")    public <Req, Resp> Resp doGet(String url, Req request, Class<Resp> responseType) throws Exception {        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);        Map<String, Object> parameters = (Map<String, Object>)request;        for (Map.Entry<String, Object> entry : parameters.entrySet()) {            builder.queryParam(entry.geTKEy(), Objects.toString(entry.getValue(), ""));        }        return restTemplate.getForObject(builder.build(false).toUri(), responseType);    }

为什么会有这个问题?

根源在于Java语言的URLEncode类只能适用于早期的RFC协议,通常spring开发的服务端是兼容这种模式的。

新版的RFC协议会把+号当成关键字不再反转成空格,这通常体现在新技术上,比如目前用的tigergraph图数据库就有这情形。

以上是“如何解决RestTemplate请求url中包含百分号会被转义成25的问题”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: 如何解决RestTemplate请求url中包含百分号会被转义成25的问题

本文链接: https://lsjlt.com/news/304242.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作