SRGs 和 martins 解决方案对我来说效果很好。
但是,我必须对过滤器应用以下更改:
如果客户端发出带有 Accept 标头的请求,Jersey 会在内容类型中添加一个质量因子。如下所示:
没问题:没有 Accept 头的请求:
curl -i http://www.example.com/my-rest-endpoint
response.getMediaType().toString() 是 application/json。我们可以简单地追加;charset=utf-8。
问题:带有 Accept 标头的请求:
curl -i -H "Accept: application/json" http://www.example.com/my-rest-endpoint
response.getMediaType().toString() 是 {application/json, q=1000}。我们不能简单地追加;charset=utf-8,因为这会导致以下异常:
java.lang.IllegalArgumentException: Error parsing media type '{application/json, q=1000};charset=utf-8'
at org.glassfish.jersey.message.internal.MediaTypeProvider.fromString(MediaTypeProvider.java:92) ~[na:na]
at org.glassfish.jersey.message.internal.MediaTypeProvider.fromString(MediaTypeProvider.java:60) ~[na:na]
at javax.ws.rs.core.MediaType.valueOf(MediaType.java:179) ~[na:na]
...
Caused by: java.text.ParseException: Next event is not a Token
at org.glassfish.jersey.message.internal.HttpHeaderReader.nextToken(HttpHeaderReader.java:129) ~[na:na]
at org.glassfish.jersey.message.internal.MediaTypeProvider.valueOf(MediaTypeProvider.java:110) ~[na:na]
at org.glassfish.jersey.message.internal.MediaTypeProvider.fromString(MediaTypeProvider.java:90) ~[na:na]
... 193 common frames omitted
我建议使用以下代码来解决此问题:
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.MediaType;
public class CharsetResponseFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext request, ContainerResponseContext response) {
MediaType type = response.getMediaType();
if (type != null) {
if (!type.getParameters().containsKey(MediaType.CHARSET_PARAMETER)) {
MediaType typeWithCharset = type.withCharset("utf-8");
response.getHeaders().putSingle("Content-Type", typeWithCharset);
}
}
}
}