Search code examples
javagoogle-app-enginerestlet

@XStreamOmitField for Restlet GAE not working


I have a POJO field annotated with @XStreamOmitField however when I look that the response of the ServerResource, the field is there.

Here is the code I have (simplified):

@Override
public ItemDTO getStuff() {
   return stuff.getItem();
}

Here's the POM config I have:

      <dependency>
          <groupId>org.restlet.gae</groupId>
          <artifactId>org.restlet</artifactId>
          <version>${version.restlet}</version>
      </dependency>
      <dependency>
          <groupId>org.restlet.gae</groupId>
          <artifactId>org.restlet.ext.servlet</artifactId>
          <version>${version.restlet}</version>
      </dependency>
      <dependency>
          <groupId>org.restlet.gae</groupId>
          <artifactId>org.restlet.ext.xstream</artifactId>
          <version>${version.restlet}</version>
      </dependency>
      <dependency>
          <groupId>org.restlet.gae</groupId>
          <artifactId>org.restlet.ext.json</artifactId>
          <version>${version.restlet}</version>
      </dependency>

Version is, <version.restlet>2.3.1</version.restlet>

What could the the problem here? It should be automatic right?

Update:

My idea is this is caused by the APISpark library used in my app causing XStream to be not-used in favor of Jackson:

  <dependency>
      <groupId>org.restlet.gae</groupId>
      <artifactId>org.restlet.ext.apispark</artifactId>
      <version>${version.restlet}</version>
      <exclusions>
          <exclusion>
              <groupId>com.fasterxml.jackson.core</groupId>
              <artifactId>jackson-databind</artifactId>
          </exclusion>
      </exclusions>
  </dependency>
  <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.5.1</version>
  </dependency>

Solution

  • Since the extension org.restlet.ext.apispark uses the extension org.restlet.ext.jackson, the latter automatically registers a converter in addition to the ones from the extensions org.restlet.ext.xstream and org.restlet.ext.json.

    The following method allows you to see which converters are registered:

    private void configureConverters() {
        List<ConverterHelper> converters = Engine.getInstance()
                .getRegisteredConverters();
        for (ConverterHelper converterHelper : converters) {
            System.out.println(converterHelper.getClass());
        }
    }
    
    @Override
    public Restlet createInboundRoot() {
        configureConverters();
        (...)
    }
    

    The registeration depends on the order in the classpath so I guess that the jackson one is registered first. This means that this is the one used to convert the response data of your request.

    To be able to use the Jettison extension you need to manually remove the registered Jackson converter, as described below:

    private void configureConverters() {
        List<ConverterHelper> converters = Engine.getInstance()
                .getRegisteredConverters();
        JacksonConverter jacksonConverter = null;
        for (ConverterHelper converterHelper : converters) {
            System.err.println(converterHelper.getClass());
            if (converterHelper instanceof JacksonConverter) {
                jacksonConverter = (JacksonConverter) converterHelper;
                break;
            }
        }
    
        if (jacksonConverter != null) {
            Engine.getInstance()
                    .getRegisteredConverters().remove(jacksonConverter);
        }
    }
    

    Hope it helps you, Thierry