如何使用JAX-RS设置charset?

时间:2010-08-07 20:52:44

标签: java java-ee character-encoding jax-rs

如何使用JAX-RS设置charset?我已经尝试了@Produces("text/html; charset=UTF-8")但是这被忽略了,只有text/html与HTTP标头一起发送。我想在MessageBodyWriter中设置charset,但不想通过我自己的反射分析@Produces注释来提取媒体类型。

7 个答案:

答案 0 :(得分:65)

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

@Produces

答案 1 :(得分:15)

也可以使用ResponseBuilder.header(...)方法使用charset设置内容类型。请参阅下面的代码示例(使用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();

答案 2 :(得分:11)

只是为了让它保持最新状态。不确定这是否在旧版本的Jersey中受支持,但是如果您决定使用ResponseBuilder.header(...)方法,则可以使用MediaType方法 withCharset()。像这样:

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

答案 3 :(得分:10)

如果要以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之外还有不同的字符集,则可能需要创建自定义注释并将其添加到每个资源方法。然后,尝试在writeTo()方法中使用annotations参数。

仅供参考,Apache Wink支持在媒体类型上使用字符集和其他属性。我希望未来的JAX-RS规范版本能够让这更容易。

答案 4 :(得分:1)

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

然后在返回类型的MessageBodyWriter中,您可以使用writeTo()方法执行此操作:

response.setContentType(mediaType.toString);

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

@Context
protected HttpServletResponse response;

答案 5 :(得分:1)

我所做的是获取servlet响应对象的实例:

protected @Context HttpServletResponse response;

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

response.setCharacterEncoding("utf-8");

这适合我。

答案 6 :(得分:1)

如果使用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

中设置charset