Generated Swagger REST client does not handle + character correctly for query parameter

ぃ、小莉子 提交于 2019-12-02 05:18:26

问题


I have this Spring REST controller method:

@ApiOperation("My method")
@RequestMapping(method = RequestMethod.POST, value = "/myMethod")
public void myMethod(@RequestParam("myParam") String myParam) {
...
}

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);
}

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);
    ...
}

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?

EDIT:

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": {
           ...
        }
      }
    }
 ...
}

EDIT:

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.


回答1:


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());

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.

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());

to

final BodyBuilder requestBuilder = RequestEntity.method(method, builder.build(true).toUri());

And then call the API method as

client.myMethod("tarun%2blalwani")

And now spring will receive tarun+lalwani as shown below



来源:https://stackoverflow.com/questions/48906034/generated-swagger-rest-client-does-not-handle-character-correctly-for-query-pa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!