如何使用JAX-RS设置字符集?

我如何设置JAX-RS的字符集? 我试过了@Produces("text/html; charset=UTF-8")但是被忽略了,只有text/html和HTTP头一起发送。 我想在MessageBodyWriter中设置字符集,但不想通过自己的reflection来分析@Produces注释来提取媒体types。

正如Daemon在评论中指出的那样,最新版本的JAX-RS(包括截止到2012年9月的稳定版)现在支持@Produces语法。 所以你可以使用:

 @Produces("text/html; charset=UTF-8") 

也可以使用ResponseBuilder.header(…)方法来设置字符集的内容types。 请参阅下面的代码示例(使用JAX-RS 1.1.1,CXF 2.3.1)。

 final Response myResponse = Response.status(Response.Status.BAD_REQUEST) .entity("La requête n'est pas correcte.\n ...") .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN+"; charset=ISO-8859-15" ) .build(); 

如果您想以JAX-RS实现中立的方式执行此操作,则可以重置MessageBodyWriter中的Content-Type。 就像是:

 public void writeTo(Object obj, Class<?> cls, Type type, Annotation[] annotations, MediaType mt, MultivaluedMap<String, Object> responseHttpHeaders, OutputStream stream) throws IOException { responseHttpHeaders.putSingle(javax.ws.rs.core.HttpHeaders.CONTENT_TYPE, mt.toString() + ";charset=UTF-8"); } 

如果除了UTF-8每个资源方法外,还有不同的字符集,则可能需要创build一个自定义注释并将其添加到每个资源方法。 然后,尝试在writeTo()方法中使用注释参数。

仅供参考, Apache Wink支持在媒体types上使用字符集和其他属性。 我希望未来的JAX-RS规格修订版更容易。

只是为了保持最新。 不确定这是否在旧版本的泽西岛支持,但肯定如果你决定使用ResponseBuilder.header(…)方法,你可以使用MediaType方法withCharset() 。 喜欢这个:

 return Response.status(Status.OK) .entity(result) .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_TYPE.withCharset("utf-8")) .build()); 

我所做的是获得一个servlet响应对象的实例:

 protected @Context HttpServletResponse response; 

然后设置字符编码为utf-8:

 response.setCharacterEncoding("utf-8"); 

这对我行得通。

首先在您的资源类方法上设置@Produces注释。

然后在你的返回types的MessageBodyWriter中,你可以在writeTo()方法中做到这一点:

 response.setContentType(mediaType.toString); 

备注:您可以通过以下方式在writer身上注入response

 @Context protected HttpServletResponse response; 

如果使用RESTEasy,你可以注册一个Inteceptor:

 import org.jboss.resteasy.annotations.interception.ServerInterceptor; import org.jboss.resteasy.core.ResourceMethodInvoker; import org.jboss.resteasy.core.ServerResponse; import org.jboss.resteasy.spi.Failure; import org.jboss.resteasy.spi.HttpRequest; import org.jboss.resteasy.spi.interception.PreProcessInterceptor; import org.jboss.resteasy.plugins.providers.multipart.InputPart; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.ws.rs.WebApplicationException; import javax.ws.rs.ext.Provider; @Provider @ServerInterceptor public class ContentTypeSetter implements PreProcessInterceptor { @Override public ServerResponse preProcess(HttpRequest request, ResourceMethodInvoker resourceMethodInvoker) throws Failure, WebApplicationException { request.setAttribute(InputPart.DEFAULT_CONTENT_TYPE_PROPERTY, "*/*; charset=UTF-8"); return null; } } 

注意:如果您手动设置了@Produces,它将覆盖此拦截器设置的ContentType。 如果你这样做,请在@Produces中设置字符集