3

I'm trying to inject a @RequestScoped object class in a Jackson's JsonSerializer<>:

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());

On the last line, this.user is null.

@RequestScoped
public class UserRequestResources
{

This object class is resolved on whereever on other places of the project. I'm using Wildfly 8 J2EE implementation.

EDIT:

I've a main resource where I configure jackson mapper:

@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());

In order to use it, I only annotate my fields with @Inject, and then I've an instance of that.

@Inject protected SerializationApplicationResources jacksonResources;

So then,

this.jacksonResources.getMapper().writeValueAsBytes(entity);
Cœur
  • 37,241
  • 25
  • 195
  • 267
Jordi
  • 20,868
  • 39
  • 149
  • 333
  • What's the scope of your `DigitalInputSerializer` class? – StuPointerException Oct 13 '15 at 11:42
  • 3
    I don't see why this should work, a JsonSerializer is not a server managed resource and you probably did not manually turn it into a named bean. – Gimby Oct 13 '15 at 12:09
  • How do you obtain objects of type `DigitalInputSerializer`? If you construct them by yourself, pass an injected instance of `UserRequestResources` to the `DigitalInputSerializer`. If not, make `DigitalInputSerializer` CDI managed and inject `DigitalInputSerializer` in the class where it is used. – Smutje Oct 13 '15 at 12:15
  • Pease, see the edited post. I've a main object class. – Jordi Oct 13 '15 at 13:12

3 Answers3

1

There may not be simple way to do that because as others have pointed out, objects that Jackson serializes are not injected automatically as Jackson has no knowledge of how this process would happen.

But Jackson does have extension points for building simple modules that do just that. For example there are Guice and OSGi modules:

both of which can support use of Jackson's @JacksonInject annotation (to denote where to inject, and what logical id to use) to find out injectable objects using whatever mechanism module wants to. So it should be possible to implement CDI-injection module, if one does not exist (I am not aware of one, but since it should be doable someone may already have done that).

This assumes that the object you want injected is created by Jackson, based on JSON; in which case CDI implementation itself does not typically have access to it.

StaxMan
  • 113,358
  • 34
  • 211
  • 239
0

First possibility:

Inject UserRequestResources into SerializationApplicationResources and pass the injected instance via the constructor to DigitalInputSerializer.

Second possibility:

Make DigitalInputSerializer also managed, e.g. RequestScoped (or even Stateless?), inject it into SerializationApplicationResources and use the injected instance instead of creating objects explicitly - then, the transitively injected UserRequestResources should be initiated as well.

Smutje
  • 17,733
  • 4
  • 24
  • 41
0

Since DigitalInputSerializer is not instantiated by container (this is created by new operator) injections in this class won't work.

If you need quickfix solution you could get UserRequestResources programmatically. Take a look at this post to do it: How to programmatically inject a Java CDI managed bean into a local variable in a static method

Community
  • 1
  • 1
A.Panzer
  • 391
  • 3
  • 15