Android Jersey/Rest默认字符编码
Jersey在返回JSON时似乎失败…Android Jersey/Rest默认字符编码,android,rest,servlets,jersey,Android,Rest,Servlets,Jersey,Jersey在返回JSON时似乎失败… 这: 失败,例如德国umlaute(üöä)将以错误的方式返回 两个问题: 1-对于JSON utf-8 ist标准-为什么不使用Jersey? 2-如果传入JSON请求,我可以为整个REST Servlet设置utf-8吗? 我在Android上使用Jersey 1.5和CRest 1.0.1…我遇到了同样的问题:我不喜欢在“@products”标记中到处添加字符集 我在这里找到了解决方案: 基本上,您只需要添加一个响应过滤器来添加字符集(例如,如果当
这: 失败,例如德国umlaute(üöä)将以错误的方式返回 两个问题:
1-对于JSON utf-8 ist标准-为什么不使用Jersey?
2-如果传入JSON请求,我可以为整个REST Servlet设置utf-8吗?
我在Android上使用Jersey 1.5和CRest 1.0.1…我遇到了同样的问题:我不喜欢在“@products”标记中到处添加字符集 我在这里找到了解决方案: 基本上,您只需要添加一个响应过滤器来添加字符集(例如,如果当前返回的内容类型是text、xml或json) 以及注册过滤器:
ServletAdapter jerseyAdapter = new ServletAdapter();
jerseyAdapter.addInitParameter("com.sun.jersey.spi.container.ContainerResponseFilters", "com.my.package.MyResponseFilter");
当然,也适用于Guice,例如在扩展ServletModule的类中:
final Map<String, String> parameters = new HashMap<String, String>();
parameters.put("com.sun.jersey.spi.container.ContainerResponseFilters", com.package.JerseyCharsetResponseFilter.class.getName());
serve("/*").with(GuiceContainer.class, parameters);
final Map parameters=new HashMap();
parameters.put(“com.sun.jersey.spi.container.ContainerResponseFilter”,com.package.JerseyCharsetResponseFilter.class.getName());
使用(GuiceContainer.class,参数)服务(“/*”);
SRGs建议的效果非常好。但是,由于Jersey 2.0的接口略有不同,因此我们必须稍微调整一下过滤器:
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) {
String contentType = type.toString();
if (!contentType.contains("charset")) {
contentType = contentType + ";charset=utf-8";
response.getHeaders().putSingle("Content-Type", contentType);
}
}
}
}
SRGs和martins解决方案对我很有效 但是,我必须对过滤器应用以下更改: 如果客户端执行带有Accept标头的请求,Jersey将向内容类型添加质量因子。情况如下: 没有问题:没有接受标头的请求:
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);
}
}
}
}
curl-ihttp://www.example.com/my-rest-endpoint
response.getMediaType().toString()
是application/json
。我们可以简单地附加;字符集=utf-8
问题:带有Accept标头的请求:
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);
}
}
}
}
curl-i-H“接受:应用程序/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);
}
}
}
}
如何归还?你能展示一些示例输出吗?它返回LÃwe而不是Löwe(英语中的Lion),但正如我所说的,如果我使用@products(MediaType.APPLICATION_JSON+“charset=UTF-8”),它可以工作……我真的是唯一一个有这个问题的人?那么你已经解决了自己的问题了吗?只需将字符集添加到末尾。似乎是客户在显示数据,而不是Jersey。是的,这是我的解决方案,但我觉得有点奇怪。这真的是处理这个问题的唯一方法吗?他们如何实现这一点的完整、更详细的来源,并允许方法已经设置了“内容类型”,从而允许在需要时进行覆盖。感谢更新!我刚开始使用球衣,偶然发现这个问题,你的解决方案完美无瑕!Grizzly用户注意:要注册此过滤器,只需调用
rc.register(com.example.CharsetResponseFilter.class)代码>在启动方法中(我使用的是教程中生成的样板代码)。
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);
}
}
}
}