Spring Boot RestTemplate solve the problem in the URL escape character escaped
Code uses the same problems encountered when requesting RestTemplate SpringBoot in different versions:
Map<String, Object> param = new HashMap<String, Object>();
param.put("version","2.0.0");
String userSing = sign(param);
param.put("user_sign", userSing);
logger.info("签名:" + userSing);
StringBuilder paramStr = new StringBuilder("?");
for(Map.Entry<String, Object> entry : param.entrySet()){
paramStr.append(entry.getKey()).append("=")
.append(entry.getValue() == null ? "" : String.valueOf(entry.getValue()))
.append("&");
}
paramStr.deleteCharAt(paramStr.length() - 1);
logger.info("入参:" + paramStr.toString());
RestTemplate restTemplate = new RestTemplate();
String jsonStr = restTemplate.getForObject(sendMessagesUrl + paramStr.toString(), String.class);
logger.info("响应值:" + jsonStr);
The following screenshot springboot1.5.3 RestTemplate request log
The following screenshot springboot2.1.7 RestTemplate request log
In can be seen in these two log value corresponding to the value user_sign + is a special character, version 1.0 is escaped as: % 2B , version 2.0 is not escaped, RestTemplate final version 2.0 program requests a third party by the time the signature verification is not decoded.
1. Try and analysis
According to the above information we can delineate the scope of the problem, = there is transcoded, the instructions may be constructed in a manner RestTemplate transcoding parameters in the url httpClient what nowhere, try various types of treatment.
Main methods used are:
- UriComponent build uri (unresolved)
2. Tracking RestTemplate source
found user_sign is escaped but here debug + not changed.
In this case URLDecoder.decode ( "/ QaNSBls / U8ciXEWaCWtmeMK6 + w% 3D") will find + into a box , the third party is at the time of decoding the signature verification is not passed.
By comparison will again find StringBoot2.0 version corresponding URL transcoding + will not be parsed.
After several Baidu have seen the following:
According to RFC 3986 can indeed occur in the plus symbols such parameters, and no coding, a problem that the server is not resolved times
3. solve the problem
Finally, to address some of the problems when using RestTemplate initiate a request, if the request parameters need url encoding to address the following two ways:
- Without wishing to pose problems to be passed using a URI object rather than a string, to modify the parameters of the request method RestTemplate
String url
modifyURI url
. - Modified when the encoding format parameters, and then build RestTemplate,
RestTemplate restTemplate = new RestTemplate();
DefaultUriBuilderFactory uriFactory = new DefaultUriBuilderFactory();
uriFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY);
restTemplate.setUriTemplateHandler(uriFactory);`
summary
Note SpringBoot2.0 version of the url parameter encoding, default = and & only for processing; for compatibility url we generally back-end processing codec encoding parameters when needed, try not to use personal recommendations Spring default mode, or received and inconsistent data is expected.