Clarification: this question was about GZIPping an JAX-WS-based REST service, but I've decided to change the topic to make it easier to find
I'm implementing a REST service via JAX-WS Provider <Source>
, and publishing it with standard Endpoint
(the reason is that I want to avoid using a servlet container or application server).
Is there a way to make server to gzip response content, if Accept-Encoding: gzip
is present?
Samples provided by nicore
actually works, and it allows you to make JAX-RS-styled server on top of embedded lightweight server without servlet container, but there are few moments to be considered.
If you prefer to manage classes by yourself (and save a time during startup), you may use the following:
JAX-RS hello world class:
@Path("/helloworld")
public class RestServer {
@GET
@Produces("text/html")
public String getMessage(){
System.out.println("sayHello()");
return "Hello, world!";
}
}
Main method:
For Simple Server:
public static void main(String[] args) throws Exception{
DefaultResourceConfig resourceConfig = new DefaultResourceConfig(RestServer.class);
// The following line is to enable GZIP when client accepts it
resourceConfig.getContainerResponseFilters().add(new GZIPContentEncodingFilter());
Closeable server = SimpleServerFactory.create("http://0.0.0.0:5555", resourceConfig);
try {
System.out.println("Press any key to stop the service...");
System.in.read();
} finally {
server.close();
}
}
For Grizzly2:
public static void main(String[] args) throws Exception{
DefaultResourceConfig resourceConfig = new DefaultResourceConfig(RestServer.class);
// The following line is to enable GZIP when client accepts it
resourceConfig.getContainerResponseFilters().add(new GZIPContentEncodingFilter());
HttpServer server = GrizzlyServerFactory.createHttpServer("http://0.0.0.0:5555" , resourceConfig);
try {
System.out.println("Press any key to stop the service...");
System.in.read();
} finally {
server.stop();
}
}
Simple:
Grizzly:
Jersey:
Make sure the javax.ws.rs
archive didnt get into your classpath, as it conflicts with Jersey's implementation. The worst thing here is a silent 404 error with no logging - only a small note on FINER
level is logged.
Since the basic Tomcat server does not support JAX-RS, a straightforward deployment of a JAX-RS based application will fail.
JAX-RS is an specification (just a definition) and Jersey is a JAX-RS implementation. Jersey framework is more than the JAX-RS Reference Implementation. Jersey provides its own API that extend the JAX-RS toolkit with additional features and utilities to further simplify RESTful service and client development.
JAX-RS is a standard defined in Java Specification Request 311 (JSR-311) and Jersey / RESTEasy are implementations of it.
Jersey is an open source framework for developing RESTful Web Services in Java. It is a reference implementation of the Java API for RESTful Web Services (JAX-RS) specification. Jetty is a Java HTTP (Web) server and Java Servlet container.
If you really want to do REST with Java I would suggest you to to use a JAX-RS implementation (RESTeasy, Jersey...).
If your main concern is the dependency on a servlet container, you could use the JAX-RS RuntimeDelegate to register your application as a JAX-RS endpoint.
// Using grizzly as the underlaying server
SelectorThread st = RuntimeDelegate.createEndpoint(new MyApplication(), SelectorThread.class);
st.startEndpoint();
// Wait...
st.stopEndpoint();
Concerning GZIP
encoding, each JAX-RS provider has different approaches. Jersey provides a filter to accomplish the encoding transparently. RESTEasy provides an annotation for that.
EDIT
I did some small tests. The following two things will definitely work for you, assuming you are using Maven.
Using Jersey + SimpleServer:
public static void main( String[] args ) throws Exception {
java.io.Closeable server = null;
try {
// Creates a server and listens on the address below.
// Scans classpath for JAX-RS resources
server = SimpleServerFactory.create("http://localhost:5555");
System.out.println("Press any key to stop the service...");
System.in.read();
} finally {
try {
if (server != null) {
server.close();
}
} finally {
;
}
}
}
with maven dependencies
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-simple-server</artifactId>
<version>1.10</version>
</dependency>
Or using the Jersey + Grizzly2:
public static void main(String[] args) throws Exception {
HttpServer server = null;
try {
server = GrizzlyServerFactory.createHttpServer("http://localhost:5555");
System.out.println("Press any key to stop the service...");
System.in.read();
} finally {
try {
if (server != null) {
server.stop();
}
} finally {
;
}
}
}
with maven dependencies
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-grizzly2</artifactId>
<version>1.10</version>
</dependency>
Honestly speaking I was not able to get the RuntimeDelegate
sample working, too.
There certainly is a way to start RESTEasy out of the box, too but I cannot recall it at the moment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With