带有嵌入式服务器的 JAX-RS
澄清:这个问题是关于 GZIPping 基于 JAX-WS 的 REST 服务,但我决定更改主题以使其更容易找到
我正在通过 JAX-WS Provider
实现 REST 服务,并使用标准 Endpoint
发布它(原因是我想避免使用servlet 容器或应用程序服务器)。
如果存在 Accept-Encoding: gzip
,是否有办法使服务器对 gzip 响应内容进行处理?
操作方法
nicore 提供的示例确实有效,它允许您在嵌入式轻量级服务器之上创建 JAX-RS 风格的服务器,而无需 servlet 容器,但有一些时刻需要考虑。
如果您喜欢自己管理类(并在启动过程中节省时间),您可以使用以下内容:
示例
JAX-RS hello world 类:
@Path("/helloworld")
public class RestServer {
@GET
@Produces("text/html")
public String getMessage(){
System.out.println("sayHello()");
return "Hello, world!";
}
}
Main 方法:
For 简单 服务器:
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();
}
}
对于 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();
}
}
已解决的依赖关系:
简单:
灰熊:
球衣:
注意
确保 javax.ws.rs
存档没有进入您的类路径,因为它与 Jersey 的实现冲突。这里最糟糕的是没有记录的静默 404 错误 - 仅记录 FINER
级别的小注释。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您确实想使用 Java 进行 REST,我建议您使用 JAX-RS 实现(RESTeasy、Jersey...)。
如果您主要关心的是对 servlet 容器的依赖,您可以使用 JAX-RS RuntimeDelegate 将您的应用程序注册为 JAX-RS 端点。
关于 GZIP 编码,每个 JAX-RS 提供商都有不同的方法。 Jersey 提供过滤器来透明地完成编码。 RESTEasy 为此提供了注释。
编辑
我做了一些小测试。假设您使用 Maven,以下两件事肯定对您有用。
使用 Jersey + SimpleServer:
带有 Maven 依赖项
或使用 Jersey + Grizzly2:
带有 Maven 依赖项
老实说,我无法获取
RuntimeDelegate
示例也工作。当然也有一种方法可以开箱即用地启动 RESTEasy,但我现在不记得了。
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.
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:
with maven dependencies
Or using the Jersey + Grizzly2:
with maven dependencies
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.
对输出进行 gzip 压缩是 JAX WS 实现的责任。您应该参考服务器(Tomcat、Glassfish、JBoss 等)的文档来配置您的 http 网络侦听器。
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.
如果将 CXF 用于 JAX-WS 实现(或 JAX-RS),您只需将 @GZIP 注释添加到服务类中即可。
If using CXF for your JAX-WS implementation (or JAX-RS), you could just add @GZIP annotation onto the service class.