【问题标题】:How do you configure a JAX-RS MessageBodyWriter on a per-request basis?如何根据每个请求配置 JAX-RS MessageBodyWriter?
【发布时间】:2013-05-01 22:39:52
【问题描述】:

基本上,我有一个将对象写入 JSON 的 MessageBodyWriter,我希望能够根据处理请求的资源方法来控制输出的某些方面。但是,@Provider 类的默认生命周期是单例的(每个 JVM 一个),因此我无法注入某些配置对象的实例。这给我留下了两个明显的解决方法:

  1. 使用自定义注释:对 writeTo(...) 的每次调用都包含所调用方法的注释列表,因此我可以检查是否存在某些注释。然而,JAX-RS 方法已经充满了元编程。
  2. 使用 ThreadLocal 属性映射:假设每个线程一个请求,但这种方法有点破坏封装。资源方法需要知道还有其他一些类在寻找这个映射。

有没有办法改变 Provider 本身的生命周期?我正在使用泽西岛。

【问题讨论】:

    标签: java jersey jax-rs


    【解决方案1】:

    不确定为什么您需要一个基于每个请求的 MessageBodyWriter 提供程序。如果您只是想区分哪些方法使用 JSON 输出,哪些没有,那么 jersey-json 已经支持。

    虽然@Provider 是单例的。您仍然可以在其中使用 per-request 对象,如下所示。

    @Provider
    public class StViewProcessor implements ViewProcessor<ST> {     
    
        ......
    
        @Context
        HttpServletRequest request;
    
    
        public void writeTo(ST st, Viewable viewable, OutputStream out)
                throws IOException {
            System.out.println(request.getRequestURI());
            ...
        }
    
    
    }
    

    如果您想根据请求注入您的实例,您可以查看PerRequestTypeInjectableProvider。这是关于它的link

    【讨论】:

    • 澄清一下,不是区分 JSON 和非 JSON,而是如何格式化 JSON,或者过滤它。因此,最终涉及同一作家。使用请求对象与 ThreadLocal 属性非常等效,但有趣的是,每个请求的上下文将在每个请求中正确注入(不知道)。
    • 是的,带有@Context 的每个请求对象基于线程本地代理。所以你不需要实现你自己的 ThreadLocal 属性映射来做同样的事情。
    【解决方案2】:

    JAX-RS 1.1 规范requires that implementations support singleton providers and allows support for other lifecycles,但没有在这些方面提出任何其他建议。据我所知,纯泽西不支持单例以外的任何东西。使用the jersey-spring contrib module,您可以支持将 Spring 用作 Jersey 的 IoC 容器(从中获取资源和提供者实例)。我知道 Spring 支持多个生命周期,包括请求,但我不确定 jersey-spring 是否内置了对它的支持。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-31
      • 2014-12-26
      • 1970-01-01
      • 2013-07-13
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 2023-03-09
      相关资源
      最近更新 更多