生成的Swagger REST客户端无法正确处理查询参数的+字符 [英] Generated Swagger REST client does not handle + character correctly for query parameter
问题描述
我有这个Spring REST控制器方法:
I have this Spring REST controller method:
@ApiOperation("My method")
@RequestMapping(method = RequestMethod.POST, value = "/myMethod")
public void myMethod(@RequestParam("myParam") String myParam) {
...
}
使用swagger codegen CLI生成REST客户端,语言为 Java ,库 resttemplate :
The REST client is generated using swagger codegen CLI with language Java and library resttemplate:
public void myMethod(String myParam) throws RestClientException {
...
return apiClient.invokeAPI(path, HttpMethod.POST, queryParams, postBody, headerParams, formParams, accept, contentType, authNames, returnType);
}
的源代码ApiClient#invokeAPI
- 也是生成的 - 是:
And the source code for ApiClient#invokeAPI
- which is also generated - is:
public <T> T invokeAPI(String path, HttpMethod method, MultiValueMap<String, String> queryParams, Object body, HttpHeaders headerParams, MultiValueMap<String, Object> formParams, List<MediaType> accept, MediaType contentType, String[] authNames, ParameterizedTypeReference<T> returnType) throws RestClientException {
updateParamsForAuth(authNames, queryParams, headerParams);
final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(basePath).path(path);
if (queryParams != null) {
builder.queryParams(queryParams);
}
final BodyBuilder requestBuilder = RequestEntity.method(method, builder.build().toUri());
if(accept != null) {
requestBuilder.accept(accept.toArray(new MediaType[accept.size()]));
}
if(contentType != null) {
requestBuilder.contentType(contentType);
}
addHeadersToRequest(headerParams, requestBuilder);
addHeadersToRequest(defaultHeaders, requestBuilder);
RequestEntity<Object> requestEntity = requestBuilder.body(selectBody(body, formParams, contentType));
ResponseEntity<T> responseEntity = restTemplate.exchange(requestEntity, returnType);
...
}
现在,当我打电话给 myMethod
在服务器I传递一个包含 +
的字符串,在 myParam
中签名收到空格字符而不是 +
。似乎是编码问题,因为在URL查询参数中保留加号以替换空格字符。这是来自swagger codegen或Spring类的错误还是没有错误?我该如何解决?
Now, when I call myMethod
passing a string containing a +
sign in myParam
, at the server I receive a space character instead of the +
. Seems to be an encoding issue since the plus sign is reserved in URL query parameters to be a replacement for the space character. Is this a bug from swagger codegen or from Spring classes or no bug at all? How can I fix that?
编辑:
Swagger定义如(从Spring REST控制器生成):
Swagger definition is like (generated from Spring REST controller):
{
"swagger": "2.0",
...
"paths": {
"/myMethod": {
"get": {
"operationId": "myMethod",
"produces": [
"application/json"
],
"parameters": [
{
"name": "myParam",
"in": "query",
"required": true,
"type": "string"
}
],
"responses": {
...
}
}
}
...
}
编辑:
类似的问题似乎是路径变量的编码。当我将bla:bla / bla
传递给路径变量时,特殊字符:
和 /
将不会被编码,但会发送,导致错误服务器端,因为找不到映射。
Similar problems seems to be the encoding of path variables. When I pass "bla:bla/bla"
to a path variable the special characters :
and /
will not be encoded but send as is which causes an error server side because the mapping not found.
推荐答案
+
通常表示url参数中的空格。这是一个标准。您的网址在下面的代码行生成
A +
usually means a space in url params. This is a standard. Your url gets generated on below line of code
final BodyBuilder requestBuilder = RequestEntity.method(method, builder.build().toUri());
+
未编码,因为它是一个有效的值,然后将在接收端转换为空格。现在,当您尝试使用%2B
时,上面的代码行看到您有一个未编码的%
字符,它将其转换为%252B
。
And +
is not encoded as it is a valid value to have which will be then later converted to space at the receiving end. Now when you try use %2B
the above line of code sees that you have a un-encoded %
character and it converts it to %252B
.
当您在Spring收到此信息时,它会将其转换回%2B
。解决该问题的一种方法是自己发送编码值。所以你将改变
When you receive this back at Spring it converts it back to %2B
for you. One way to solve the issue is to send encoded values yourself. So you will change
final BodyBuilder requestBuilder = RequestEntity.method(method, builder.build().toUri());
到
final BodyBuilder requestBuilder = RequestEntity.method(method, builder.build(true).toUri());
然后将API方法调用为
And then call the API method as
client.myMethod("tarun%2blalwani")
现在春天将收到 tarun + lalwani
,如下所示
And now spring will receive tarun+lalwani
as shown below
这篇关于生成的Swagger REST客户端无法正确处理查询参数的+字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!