解决restTemplate中URL 参数含有特殊字符的问题
背景
restTemplate请求和在页面上直接请求结果不一样,发现是restTemplate对url 参数中特殊字符处理的不好。
以下是解决办法
encode URI中的参数
1.利用正则提取需要encode的uri部分
public static String getUTF8URLString2(String src) { // String str = "xxxx?a=1&b=2&c=3"; src+="&";//先加后删 String reg = "=(.*?)\\&"; Pattern p = Pattern.compile(reg); Matcher m = p.matcher(src); String temp = null; StringBuffer sb = new StringBuffer(); while(m.find()){ temp = "="+m.group(1)+"&"; temp = temp.replace(m.group(1), getUTF8URLString(m.group(1))); m.appendReplacement(sb, temp); } m.appendTail(sb); String end =sb.substring(0,sb.length()-1); return end; }
2.调用encode方法
// 特殊字符 public static String getUTF8URLString(String src) { if (!StringUtils.hasText(src)){ return src; } if (src.contains("&")){ return src;//理论上不会有这种情况 } String dest = ""; try { dest = URLEncoder.encode(src, "utf-8").replaceAll("\\+", "%20"); } catch (UnsupportedEncodingException e) { log.error("编码text错误",e); dest=src; }// 编码 return dest; }
3.通过UriComponentsBuilder创建URI对象
这样RestTemplate不会自动进行urlencode,这一步不能少
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(endUrl); URI uri = uriComponentsBuilder.build(true).toUri(); ResponseEntity<String> baseObject=restTemplate.getForEntity(uri,String.class);
最佳答案 直接处理URL
尝试借助URI类拆分为URL:String sUrl = "http://bla.com:8080/test and test/bla.php?query=bla and bla";
URL url = new URL(sUrl);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
String canonical = uri.toString();
System.out.println(canonical);
原文链接:https://blog.csdn.net/weixin_29435115/article/details/114562225