【问题标题】:JAX-RS with embedded server带有嵌入式服务器的 JAX-RS
【发布时间】:2011-11-26 09:10:10
【问题描述】:

澄清:这个问题是关于 GZIPping 一个基于 JAX-WS 的 REST 服务,但我决定更改主题以便更容易找到 p>

我正在通过 JAX-WS Provider <Source> 实现 REST 服务,并使用标准 Endpoint 发布它(原因是我想避免使用 servlet 容器或应用程序服务器)。

如果存在Accept-Encoding: gzip,有没有办法让服务器对响应内容进行gzip 压缩?


如何做

nicore 提供的示例确实有效,它允许您在没有 servlet 容器的嵌入式轻量级服务器之上制作 JAX-RS 样式的服务器,但需要考虑的时间不多。

如果您更喜欢自己管理课程(并在启动期间节省时间),您可以使用以下方法:

示例

JAX-RS 你好世界级:

@Path("/helloworld")
public class RestServer {

    @GET
    @Produces("text/html")
    public String getMessage(){
        System.out.println("sayHello()");
        return "Hello, world!";
    }
}

主要方法:

对于Simple 服务器:

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 级别的小注释。

【问题讨论】:

  • 这不就是靠容器(Tomcat、Jetty等)来整理的吗?
  • 我们目前没有使用 servlet 容器,而这个 REST 服务可能是我们唯一需要它的地方。我真的不认为为了压缩这个小家伙而检查、设置和调整整个 servlet 容器是不值得的。所以我想避免使用一个,如果可能的话。
  • 为清楚起见,这些示例适用于 Jersey 1.x,不适用于 Jersey 2.x。后一种情况参见文档:jersey.java.net/documentation/latest/…

标签: java rest jax-rs embedded-server


【解决方案1】:

如果您真的想使用 Java 进行 REST,我建议您使用 JAX-RS 实现(RESTeasy、Jersey...)。

如果您主要关心的是对 servlet 容器的依赖,您可以使用 JAX-RS RuntimeDelegate 将您的应用程序注册为 JAX-RS 端点。

// Using grizzly as the underlaying server
SelectorThread st = RuntimeDelegate.createEndpoint(new MyApplication(), SelectorThread.class);

st.startEndpoint();

// Wait...
st.stopEndpoint();

关于GZIP 编码,每个 JAX-RS 提供程序都有不同的方法。 Jersey 提供a filter 透明地完成编码。 RESTEasy provides an annotation for that

编辑

我做了一些小测试。假设您使用的是Maven,以下两件事肯定对您有用。

使用 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 {
            ;
        }
    }
}

带有maven依赖

<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>

或者使用 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 {
            ;
        }
    }
}

使用 Maven 依赖项

<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>

老实说,我也无法让RuntimeDelegate 示例工作。 当然也有一种方法可以开箱即用地启动 RESTEasy,但我现在想不起来了。

【讨论】:

  • 很抱歉,但 JAX-RS(尤其是 RuntimeDelegate)是我见过的最可怕和设计最糟糕的东西之一。我在 Jersey 和 RESTEasy 上苦苦挣扎了两个小时,但仍然没有得到,如何让它们中的任何一个在没有 servlet 容器的情况下工作。您能否提供一个简单的示例来说明如何实现它?附言顺便说一句 - 哪个 jar 包含SelectorThread?灰熊本身有很多罐子,而泽西岛似乎没有这个。
  • 嗯,我个人喜欢 JAX-RS,并用它制作了一些很酷的东西。至少这是一个比我猜想自己开发所有东西更好的选择。关于 JAR 问题:我无法说出答案,因为我使用 maven 为我解决了这个问题。也许泽西 wiki 页面会有所帮助。
  • 花了一些时间来解决这个问题,但它有效,谢谢。我会接受你的回答并编辑我的问题,以便向其他走这条路的人澄清这一点。
  • 可能会在 SO 上添加到我的 necro 徽章,但到底是什么!我正在努力让它与球衣一起工作,抛出异常 - “ResourceConfig 实例不包含任何根资源类。”另外我猜这不需要 web.xml 这是我尝试过的事情之一。使用 jersey-simple-server 1.17.1
【解决方案2】:

压缩输出是 JAX WS 实现的责任。您应该参考服务器的(Tomcat、Glassfish、JBoss 等)文档来配置您的 http 网络侦听器。

【讨论】:

    【解决方案3】:

    如果将 CXF 用于您的 JAX-WS 实现(或 JAX-RS),您只需将 @GZIP 注释添加到服务类。

    【讨论】:

      猜你喜欢
      • 2016-11-15
      • 2012-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-16
      • 2013-06-26
      • 1970-01-01
      相关资源
      最近更新 更多