java - 在带有 spring-boot rest 和 Swagger 的 header 中使用 utf-8 字符时响应未加载

标签 java rest spring-boot swagger

我有 spring boot-application with swagger。当我在 header 中没有 utf-8 字符的情况下测试我的休息服务时,一切正常。我可以使用 Swagger 生成命令来测试它:

curl -X GET --header 'Accept: application/json' --header 'user: me' --header 'reason: zst' --header 'Authorization: Basic dG9tYXM6dG9tYXMxMjM=' 'http://localhost:8080/my-app/uuid/756531B55A3D029A0894D7C9C4ACDF3EC0'

但是当我 Swagger 使用 utf-8 字符时,我没有得到任何回应。 Swagger 只是在加载一些东西。当我查看 firefox 的控制台时,我只看到一些获取请求:

http://localhost:8080/my-app/webjars/springfox-swagger-ui/images/throbber.gif 

没有反应。

当我尝试编辑上面的 curl 命令时:

curl -X GET --header 'Accept: application/json' --header 'user: me' --header 'reason: žšť' --header 'Authorization: Basic dG9tYXM6dG9tYXMxMjM=' 'http://localhost:8080/my-app/uuid/756531B55A3D029A0894D7C9C4ACDF3EC0'

一切正常,所以我想我的后端没有问题。有什么方法可以解决/调试这个问题吗?

最佳答案

根据RFC 2616 section 4 , Message Headers定义如下:

message-header = field-name ":" [ field-value ]
field-name     = token
field-value    = *( field-content | LWS )
field-content  = <the OCTETs making up the field-value
                 and consisting of either *TEXT or combinations
                 of token, separators, and quoted-string>

知道根据section 2 :

token          = 1*<any CHAR except CTLs or separators>
separators     = "(" | ")" | "<" | ">" | "@"
                  | "," | ";" | ":" | "\" | <">
                  | "/" | "[" | "]" | "?" | "="
                  | "{" | "}" | SP | HT
CHAR           = <any US-ASCII character (octets 0 - 127)>
quoted-string  = ( <"> *(qdtext | quoted-pair ) <"> )
qdtext         = <any TEXT except <">>

The TEXT rule is only used for descriptive field contents and values that are not intended to be interpreted by the message parser. Words of *TEXT MAY contain characters from character sets other than ISO-8859-1 only when encoded according to the rules of RFC 2047.

TEXT          = <any OCTET except CTLs,
                but including LWS>    

换句话说, header 的值只能是 ISO-8859-1 编码,如果你想编码不包含在这个字符集中的字符,这里似乎就是这种情况,您应该根据 RFC 2047 也称为 MIME(多用途 Internet 邮件扩展)第三部分:非 ASCII 文本的邮件 header 扩展 对其进行编码。

所以不是

reason: žšť

应该是

reason: =?utf-8?q?=C5=BE=C5=A1=C5=A5?=

在实践中,当您没有只有 US-ASCII 字符时,甚至建议对值进行编码。

你这边最后要检查的是,你的 JAX-RS 实现是否支持开箱即用的 RFC 2047,如果不支持,你将需要手动解码它,例如使用实用程序方法MimeUtility.decodeText(String etext) .

这是一个具体的例子:

@GET
public Response showHeader(@HeaderParam("reason") String reason) 
    throws UnsupportedEncodingException {
    // Decode it
    reason = MimeUtility.decodeText(reason);
    // Return the value of the decoded String
    return Response.status(Response.Status.OK)
        .entity(String.format("Value of reason = '%s'", reason))
        .build();
}

使用 curl--header 'reason: =?utf-8?q?=C5=BE=C5=A1= 调用此资源方法 C5=A5?=' 按预期给出:

Value of reason = 'žšť'

注意:要从您的 js 前端对 header 的值进行编码,您可以使用库 q-encoding , 这是一个 live demo .

关于java - 在带有 spring-boot rest 和 Swagger 的 header 中使用 utf-8 字符时响应未加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40914909/

相关文章:

java - Button.setOnclickListener(this) 的问题

java - 如何找到具有相同值的所有相邻像素而不遇到当前的 StackOverflowError 问题?

java - 通过提示配置打印机的重定向端口

wcf - .Net 3.5 堆栈的 REST API 有哪些选项

java - 使用 AmazonSQSClient 的消息消耗缓慢

java - spring boot删除 Controller 中的员工代码困惑

java - 如何通过拖放交换jtable中单元格的值

Controller 休息服务的 Spring Junit 测试用例

c# - 使用 REST API 返回 XML 文档

spring-boot - 升级 Spring 和 thymeleaf 打破了我的授权