Jersey and Guice and nice JSON
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;
}
}
精彩评论