问题
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:
- Simple Framework itself
- jersey-simple-server
Grizzly:
- grizzly-framework
- grizzly-http
- grizzly-http-server (different repository!)
- jersey-grizzly2
Jersey:
- jersey-archive
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.
回答1:
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.
回答2:
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.
回答3:
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