-
Notifications
You must be signed in to change notification settings - Fork 6
Home
tapestry-jersey is inspired by Tynamo’s tapestry-resteasy and provides the Jersey integration to Tapestry5. With tapestry-jersey, you can expose tapestry managed services as jax-rs services.
<dependency>
<groupId>com.bluetangstudio</groupId>
<artifactId>tapestry-jersey</artifactId>
<version>1.0.3-SNAPSHOT</version>
</dependency>
By default, tapestry-jersey will forward requests prefixed with ‘/rest’ to Jersey ServletContainer. If you would like to change this, you can add the following lines to your AppModule class.
public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration) {
configuration.add(JerseySymbols.REQUEST_PATH_PREFIX, "/rest");
}
package com.bluetangstudio.shared.jersey.test.services.rest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@Path("/rest/helloworld")
public interface HelloWorld {
@GET
public String getHello();
}
package com.bluetangstudio.shared.jersey.test.services.rest;
public class HelloWorldImpl implements HelloWorld {
public String getHello() {
return "hello";
}
}
To expose HelloWorldImpl to jersey, you have to define the service scope for it in Tapestry first. Here, I use default scope(singleton) for the HelloWorld service. You can use PerThread scope but this will make Tapestry to create a new instance of HelloWorldImpl for each new request.
Next, you have to expose your services to Jersey by contributing your service instances to JerseyRootResources. If your service is a singleton service, configuration.add(objectLocator.getService(HelloWorld.class));
will add your singleton service to Jersey.
If the service is a PerThread service, objectLocator.getService(HelloWorld.class)
will return your service instance wrapped in a PerThreadManager proxy. This proxied instance will create a thread local HelloWorldImpl instance for each new request.
AppModule.java
public static void bind(ServiceBinder binder) {
binder.bind(HelloWorld.class, HelloWorldImpl.class);
}
public static void contributeJerseyRootResources(Configuration<Object> configuration,
ObjectLocator objectLocator) {
configuration.add(objectLocator.getService(HelloWorld.class));
}
The default json serializer generate a single element node if an array element only contains one sub-element.
for example
int[] collections = new int[] {1} => {collections: 1}
int[] collections = new int[] {1,2} => {collections: [1,2]}
This cause lots of trouble when parsing json outputs. Jersey would like to change its default json serialization implementation but it can’t due to backward compatibility. To fix this issue by yourself, please add jackson libraries to your dependencies and contribute JacksonJsonProvider to JerseyRootResources
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>com.bluetangstudio</groupId>
<artifactId>tapestry-jersey</artifactId>
<version>1.0.3-SNAPSHOT</version>
</dependency>
public static JacksonJsonProvider buildJacksonJsonProvider() {
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
// make deserializer use JAXB annotations (only)
mapper.getDeserializationConfig().setAnnotationIntrospector(introspector);
// make serializer use JAXB annotations (only)
mapper.getSerializationConfig().setAnnotationIntrospector(introspector);
return new JacksonJsonProvider(mapper);
}
public static void contributeJerseyRootResources(Configuration<Object> configuration,
JacksonJsonProvider jsonProvider) {
configuration.add(jsonProvider);
}