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

发布于 2024-09-13 04:17:11 字数 178 浏览 6 评论 0原文

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

How can I set the charset with JAX-RS? I've tried @Produces("text/html; charset=UTF-8") but that was ignored and only text/html was send with the HTTP header. I want to set the charset within a MessageBodyWriter, but don't want to extract the media type by analysing the @Produces annotation via reflection by myself.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

最丧也最甜 2024-09-20 04:17:11

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

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

As Daemon pointed out in a comment, the latest versions of JAX-RS (including the stable version as of September 2012) now do support the @Produces syntax. So you can just use:

@Produces("text/html; charset=UTF-8")
殊姿 2024-09-20 04:17: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());

Just to keep it up to date. Not sure whether this was supported in older versions of Jersey, but definitely if you decide to use ResponseBuilder.header(...) method you can use MediaType method withCharset(). Like this:

return Response.status(Status.OK)
         .entity(result)
         .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_TYPE.withCharset("utf-8"))
         .build());
遥远的绿洲 2024-09-20 04:17:11

还可以使用 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();

It is also possible to use ResponseBuilder.header(...) method to set the content type with the charset. See below for a code sample (using 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();
不语却知心 2024-09-20 04:17:11

如果您想以 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() 方法中使用注释参数。

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

If you want to do this in a JAX-RS implementation neutral way, you may be able to reset the Content-Type in the MessageBodyWriter. Something like:

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");
}

If you have different character sets besides UTF-8 per resource method, you may want to create a custom annotation and add it to each resource method. Then, try to use the annotations parameter in the writeTo() method.

Just FYI, Apache Wink supports the usage of charset and other attributes on media types. I hope that future JAX-RS spec revisions makes this easier.

夜无邪 2024-09-20 04:17:11

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

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

response.setContentType(mediaType.toString);

备注:您可以在 中注入 response作者:

@Context
protected HttpServletResponse response;

First setup @Produces annotation on your resource class methods.

Then in MessageBodyWriter of your returned type, you can do this in writeTo() method:

response.setContentType(mediaType.toString);

Remark: You can inject response in your writer by:

@Context
protected HttpServletResponse response;
梦幻之岛 2024-09-20 04:17:11

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

protected @Context HttpServletResponse response;

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

response.setCharacterEncoding("utf-8");

这对我有用。

What I do is to get an instance of the servlet response object:

protected @Context HttpServletResponse response;

And then set the character encoding to utf-8:

response.setCharacterEncoding("utf-8");

That works for me.

记忆里有你的影子 2024-09-20 04:17:11

如果使用 RESTEasy,您可以注册一个拦截器:

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中设置字符集

If using RESTEasy you can register an 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;
    }
}

Note: If you manually set a @Produces it overrides the ContentType set by this interceptor. If you do that, set the charset in @Produces

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文