在 header 中使用带有 spring-boot rest 和 Swagger 的 utf-8 字符时响应未加载
Response not loading when using utf-8 chars in header with spring-boot rest and Swagger
我有springboot-application招摇。当我在 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'
但是当我大摇大摆地使用 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'
一切正常所以我想我的后端没有问题。有什么方法可以 fix/debug 这个问题吗?
根据RFC 2616 section 4,消息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 邮件扩展)第三部分:消息 Header [=68= 的扩展] 对其进行编码] 文字.
所以不用
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 front-end 编码你的 header 的值,你可以使用库 q-encoding, here is a live demo.
我有springboot-application招摇。当我在 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'
但是当我大摇大摆地使用 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'
一切正常所以我想我的后端没有问题。有什么方法可以 fix/debug 这个问题吗?
根据RFC 2616 section 4,消息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 邮件扩展)第三部分:消息 Header [=68= 的扩展] 对其进行编码] 文字.
所以不用
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 front-end 编码你的 header 的值,你可以使用库 q-encoding, here is a live demo.