【问题标题】:CDI injection not resolved inside a Jackson Serializer在 Jackson 序列化器中未解决 CDI 注入
【发布时间】:2016-01-11 03:31:59
【问题描述】:

我正在尝试在 Jackson 的 JsonSerializer<> 中注入 @RequestScoped 对象类:

public class DigitalInputSerializer extends JsonSerializer<DigitalInput>
{
    @Inject private UserRequestResources user;

    @Override
    public void serialize(DigitalInput value, JsonGenerator gen,
            SerializerProvider serializers) throws IOException,
            JsonProcessingException {

        gen.writeStartObject();
        gen.writeStringField("user", this.user.getMe().getUser());

在最后一行,this.usernull

@RequestScoped
public class UserRequestResources
{

这个对象类在项目的其他地方被解析。 我正在使用 Wildfly 8 J2EE 实现。

编辑:

我有一个配置杰克逊映射器的主要资源:

@ApplicationScoped
public class SerializationApplicationResources
{

  protected ObjectMapper mapper;

  @PostConstruct
  protected void initialize_resources() throws IllegalStateException
  {
    this.mapper = new ObjectMapper();

    SimpleModule module = new SimpleModule();

    module.addDeserializer(DigitalInput.class, new DigitalInputDeserializer());
    module.addSerializer(DigitalInput.class, new DigitalInputSerializer());

为了使用它,我只用@Inject 注释我的字段,然后我有一个实例。

@Inject protected SerializationApplicationResources jacksonResources;

那么,

this.jacksonResources.getMapper().writeValueAsBytes(entity);

【问题讨论】:

  • 你的DigitalInputSerializer类的范围是什么?
  • 我不明白为什么这应该起作用,JsonSerializer 不是服务器管理的资源,您可能没有手动将其转换为命名 bean。
  • 如何获得DigitalInputSerializer 类型的对象?如果您自己构建它们,请将UserRequestResources 的注入实例传递给DigitalInputSerializer。如果没有,则将DigitalInputSerializer CDI 托管并在使用它的类中注入DigitalInputSerializer
  • 请参阅编辑后的帖子。我有一个主要的对象类。

标签: java jakarta-ee jackson cdi


【解决方案1】:

第一种可能性:

UserRequestResources 注入SerializationApplicationResources 并通过构造函数将注入的实例传递给DigitalInputSerializer

第二种可能性:

使DigitalInputSerializer 也被管理,例如RequestScoped(甚至Stateless?),将其注入SerializationApplicationResources并使用注入的实例而不是显式创建对象 - 然后,传递注入的UserRequestResources也应该启动。

【讨论】:

  • 将请求范围的 bean 注入应用范围的 bean 不是一个好主意。
【解决方案2】:

可能没有简单的方法来做到这一点,因为正如其他人所指出的那样,Jackson 序列化的对象不会自动注入,因为 Jackson 不知道这个过程将如何发生。

但是 Jackson 确实有一些扩展点,可以用来构建能够做到这一点的简单模块。例如有 Guice 和 OSGi 模块:

这两者都可以支持使用 Jackson 的 @JacksonInject 注释(表示在哪里注入,以及使用什么逻辑 id)来使用任何机制模块查找可注入对象。 所以应该可以实现 CDI 注入模块,如果不存在的话(我不知道有一个,但既然它应该是可行的,那么有人可能已经这样做了)。

这假设您要注入的对象是由 Jackson 基于 JSON 创建的;在这种情况下,CDI 实现本身通常无法访问它。

【讨论】:

    【解决方案3】:

    由于DigitalInputSerializer 不是由容器实例化(这是由new 运算符创建的),因此此类中的注入将不起作用。

    如果您需要快速修复解决方案,您可以通过编程方式获得UserRequestResources。看看这个帖子去做吧:How to programmatically inject a Java CDI managed bean into a local variable in a static method

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-28
      • 2017-02-14
      • 1970-01-01
      • 2018-11-12
      • 2018-05-06
      • 1970-01-01
      • 2021-06-17
      • 2015-10-28
      相关资源
      最近更新 更多