开发者

Jersey and Guice and nice JSON

开发者 https://www.devze.com 2023-03-15 03:15 出处:网络
I have a project which uses Jersey 1.7, Guice 3.0 and has some JAXB annotated classes which are serialized through resources to XML and JSON. I\'d like to configure the JSON output using a ContextReso

I have a project which uses Jersey 1.7, Guice 3.0 and has some JAXB annotated classes which are serialized through resources to XML and JSON. I'd like to configure the JSON output using a ContextResolver as suggested in several questions here on SO, as well as in the Jersey User Guide. This involves creating a JSONJAXBContext like this:

public class JaxbResolver implements ContextResolver<JAXBContext> {

    private final JAXBContext context;

    public JaxbResolver() throws Exception {
        this.ctx = new JSONJAXBContext(
            JSONConfiguration.
                natural().
                humanReadableFormatting(true).
                build(),
            Resource1.class, Resource2.class);
    }

    /* ... */
}

My problem is, that some of my resource classes have dependencies which are to be injected by Guice, like this:

public class DisplayConfigResource {
    private final ConfigRunner cr;

    @com.google.inject.Inject
    public DisplayConfigResource(ConfigRunner cr) {
        this.cr = cr;
    }

    /* ... */
}

If I remove my JaxbResolver from the game, everything works fine except that I have no control over the generated JSON (and the default is really weird, like removing the []s from single-element collections, ...). So it seems it's common sense to plug a ContextResolver like mine into Jersey so I can tune the JSON to something I like. But

  • the JSONJAXBContext class really likes to have no-arg constructors on the resources while
  • my resources really like to have their dependecies injected in their constructors.

So my question is how 开发者_JS百科to resolve this situation and have Jersey, Guice and JSON play nicely together?


You can also use Jackson instead of JAXB for JSON marshal/unmarshal. It uses the same @XmlRootElement, @XmlType, etc annotations and it produces a more standard output (and does not need those fancy ContextResolver natural configuration stuff).

First configure your web.xml:

<servlet>
  <servlet-name>jersey</servlet-name>
  <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
  <init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
  </init-param>
</servlet>

Then add the jersey-json dependency in your pom.xml:

<dependency>
  <groupId>com.sun.jersey</groupId>
  <artifactId>jersey-json</artifactId>
  <version>1.7</version>
</dependency>


I had similar problem and I resolved it by creating custom JAXBContextResolver and manually specifying which classes are going to play nicely with json serialization:

@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {

    private JAXBContext context;
    private Class<?>[] types = {DtoIdNazov.class, DtoLokalitaPoloha.class, DtoListRestauracie.class, DtoDetailRestauracia.class};

    public JAXBContextResolver() throws Exception {
        JSONConfiguration jsonConfiguration = JSONConfiguration.natural().build();
        this.context = new JSONJAXBContext(jsonConfiguration, types);
    }

    public JAXBContext getContext(Class<?> objectType) {
        for (Class<?> type : types) {
            if (type == objectType) {
                return context;
            }
        }
        return null;
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消