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?
HOW-TO
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:
Example
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();
}
}
Resolved dependencies:
Simple:
Grizzly:
- grizzly-framework
- grizzly-http
- grizzly-http-server (different repository!)
- jersey-grizzly2
Jersey:
Notice
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.
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.
gzipping the output is the reponsibility of JAX WS implementation. You should refer to server's (Tomcat, Glassfish, JBoss, etc) documentation in order to configure your http network listeners.
If using CXF for your JAX-WS implementation (or JAX-RS), you could just add @GZIP annotation onto the service class.
来源:https://stackoverflow.com/questions/8277409/jax-rs-with-embedded-server