生成的Swagger REST客户端无法正确处理查询参数的+字符 [英] Generated Swagger REST client does not handle + character correctly for query parameter

查看:841
本文介绍了生成的Swagger REST客户端无法正确处理查询参数的+字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆