【问题标题】:Change what @Produces(...) produces in Jersey?更改 @Produces(...) 在泽西岛产生的内容?
【发布时间】:2014-06-10 06:20:24
【问题描述】:

我是泽西岛的新手,想更改以下生成的内容:

@Produces(MediaType.APPLICATION_JSON)

我最终要做的是确保响应的字符编码设置为 UTF-8。如果我对每个生成 json 的方法都执行此操作,我可以根据具体情况执行此操作。

@Produces("application/json;charset=UTF-8")

我当然想在我的应用程序中执行一次,让它在任何地方都可以使用。我的第一个想法是 implement a java filter 修改它,但我无法让它工作。

编辑:所以要 100% 清楚 - 我想在我的应用程序中以某种全局方式执行此操作,并让它影响 Jersey 为我有的任何地方生成的所有输出@Produces(MediaType.APPLICATION_JSON) 在我的代码中。因此,如果我有 100 个带有 @Produces(MediaType.APPLICATION_JSON) 的方法,那么现在突然有 100 个方法将使用 UTF-8 编码的内容发送。

那么无论如何我可以替换@Produces(MediaType.APPLICATION_JSON) 产生的东西吗?如果不是最终值,我只需将 MediaType.APPLICATION_JSON 更改为我的新值;-)

【问题讨论】:

  • 您可以使用Response 生成您想要的任何内容类型(和编码)的响应。
  • 如果您的所有 JSON 都必须编码为 UTF-8,您可能应该利用框架始终这样做。根据您序列化为 JSON 的方式,您需要配置序列化以便发生这种情况。这是最稳健的方式。
  • 当然……听起来不错……那你觉得我应该怎么做?
  • 您可以为每个请求添加一个ContainerResponseFilterWriterInterceptor

标签: java json jersey content-type


【解决方案1】:

您可以将其实现为 ContainerResponseFilter 在您感兴趣的特定情况下覆盖 @Produces 注释的行为。

@Provider
@Priority(Priorities.HEADER_DECORATOR)
public class MediaTypeFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        for (Annotation annotation : responseContext.getEntityAnnotations()) {
            filterProducesAnnotation(annotation, responseContext);
        }
    }

    private void filterProducesAnnotation(Annotation annotation, ContainerResponseContext responseContext) {
        if (annotation instanceof Produces) {
            Produces produces = (Produces) annotation;
            filterMediaTypes(produces, responseContext);
        }
    }

    private void filterMediaTypes(Produces produces, ContainerResponseContext responseContext) {
        List<Object> mediaTypes = new ArrayList<Object>();
        for (String mediaType : produces.value()) {
            contentTypes.add(mediaType.equals(MediaType.APPLICATION_JSON) ? mediaType + ";charset=UTF-8" : mediaType);
        }
        responseContext.getHeaders().put("Content-Type", mediaTypes);
    }
}

只需确保在您的 Jersey 应用程序中注册 MediaTypeFilter

【讨论】:

    【解决方案2】:

    我认为没有default media type 具有您想要的字符编码。

    虽然过滤器的替代方法可能是引入一个包含您所需的 mimetype + 字符编码的常量。所以很简单:

    private static final String APPLICATION_JSON_UTF8 = MediaType.APPLICATION_JSON + ";charset=UTF-8";

    这样做的唯一原因是“application/json;charset=UTF-8”不会将您的代码作为纯文本污染(想象一下,如果您需要在任何地方使用“魔术字符串”更改字符编码,请进行重构) :) )

    【讨论】:

    • 嘿...感谢您的建议...我正在尝试 1)使所有现有代码按建议工作,以及 2)未来证明任何可能引入的新代码,只使用@Produces(MediaType.APPLICATION_JSON) 注释,并且不知道新的方法。
    猜你喜欢
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 2011-08-02
    • 1970-01-01
    • 1970-01-01
    • 2017-05-13
    • 2013-12-21
    • 1970-01-01
    相关资源
    最近更新 更多