54

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

4

7 回答 7

72

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

@Produces("text/html; charset=UTF-8")
于 2012-09-26T23:54:31.147 回答
17

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

return Response.status(Status.OK)
         .entity(result)
         .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_TYPE.withCharset("utf-8"))
         .build());
于 2015-07-31T08:39:18.463 回答
15

也可以使用 ResponseBuilder.header(...) 方法来设置带有字符集的内容类型。请参阅下面的代码示例(使用 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();
于 2011-08-30T21:13:35.827 回答
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 规范修订使这更容易。

于 2010-08-09T22:01:16.923 回答
1

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

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

response.setContentType(mediaType.toString);

备注:您可以通过以下方式注入responsewriter的:

@Context
protected HttpServletResponse response;
于 2016-08-23T09:40:37.247 回答
1

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

protected @Context HttpServletResponse response;

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

response.setCharacterEncoding("utf-8");

这对我行得通。

于 2016-08-24T13:01:01.327 回答
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 中设置字符集

于 2016-12-07T16:41:02.257 回答