upgrade spring-cloud-release from F to G, feign urlencode error
my app server code is
@PostMapping(value = "/user/userinfo")
public BaseResult userInfoSignatureCheck(
@NotBlank @RequestHeader(WxConstants.HN_APP_ID) String hnAppId,
@NotBlank @RequestParam(WxConstants.SESSION_KEY) String sessionKey,
@NotBlank @RequestParam String rawData,
@NotBlank @RequestParam String signature,
@NotBlank @RequestParam String encryptedData,
@NotBlank @RequestParam String iv) {
try {
...
return BaseResult.success(userInfo);
} catch (WxErrorException e) {
log.error("WxErrorException", e);
return BaseResult.fail(e.getError().getErrorCode(), e.getError().getErrorMsg());
}
}
and app client code is
@FeignClient(name = "mini-program-api")
public interface MiniProgramApi {
@RequestMapping(value = "/mini-program-api/user/userinfo", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
BaseResult<Map<String,Object>> userinfo2(@RequestHeader("hn-app-id") String hnAppId,
@RequestParam("sessionKey") String sessionKey,
@RequestParam("rawData") String rawData,
@RequestParam("signature") String signature,
@RequestParam("encryptedData") String encryptedData,
@RequestParam("iv") String iv);
in spring-cloud-release F version
and i request sessionKey param is aaa+bbb
i check okhttp3 request log , sessionKey param has been change to aaa%2B%bbb
and app server accept sessionKey param is aaa+bbb
in spring-cloud-release G version
and i request sessionKey param is aaa+bbb
i check okhttp3 request log , sessionKey param has been change to aaa+bbb (no encode)
and app server accept sessionKey param is aaa bbb
how can i solve this problem?
thanks
We've also experienced this.
One thing that is not clear to me is that it would appear that not all URL encoding of params have stopped after upgrading from finchley.SR2 to greenwich.release, some characters still are.
using finchley before the + char appears to have been converted to %2B which , I thought was desirable, https://tools.ietf.org/html/rfc3986 (section 2.2. Reserved Characters) .
Using Greenwich, the + is now a literal +, but certain other characters (if present in the input string) are still encoded, e.g. ABC+&? -> ABC+%26%3F. Before (Finchley.SR2) this was ABC%2B%26%3F.
I can use java.net.URLEncoder#encode(java.lang.String, java.lang.String) prior to calling the feign client to encode any params values which might contain reserved characters but it's not clear to me whether it is advisable to do so in terms of the intended behaviour of feign (i.e. it feels like feign does take care of this for at least some chars ?, &).
For the time being, I've modified my calling code to first URL encode any strings with potential for reserved characters before calling feign
I'm looking into this. It appears that we are not applying path and query encoding correctly.
i create a new RequestInterceptor to encode all query param to solve this problem.
@Bean
public RequestInterceptor feignRequestInterceptor() {
return template -> {
if (urlEncode) {
template.queries().forEach((k, v) -> {
template.query(k, Lists.newArrayList());
template.query(k, v.stream().map(l -> URLEncoder.encode(l, StandardCharsets.UTF_8)).collect(
Collectors.toList()));
});
log.info("url is {}, urlEncode is {}", template.url(), urlEncode);
}
};
}
i hope feign official can solve this problem next version, thanks
I would caution blindly encoding this way. Only some of the encoding is incorrect and your approach will double encode if a value is handled correctly.
And one more important note, URLEncoder does not apply url encoding, it is used to encode form parameters and will incorrectly encode certain values. Use with caution.
@kdavisk6 thanks!
PR #882 is now open. This PR attempts to correct this issue by making sure that each segment of the uri, be it the path or query, are correctly encoded based on the URI and URI Template specifications. With regards to the + symbol, when this appears on the query string, it will be encoded as %2B.
If your intention is to use + as a space, you must use the space character or encode it yourself as %20.
If you are interested in more detail about where all this comes from, I invite you to look at RFC 3986 - Appendix A. It describes what characters are acceptable on each segment of the uri.
Most helpful comment
PR #882 is now open. This PR attempts to correct this issue by making sure that each segment of the uri, be it the path or query, are correctly encoded based on the URI and URI Template specifications. With regards to the
+symbol, when this appears on the query string, it will be encoded as%2B.If your intention is to use
+as a space, you must use the space characteror encode it yourself as%20.If you are interested in more detail about where all this comes from, I invite you to look at RFC 3986 - Appendix A. It describes what characters are acceptable on each segment of the uri.