JAX-RS со встроенным сервером

17

Разъяснение: этот вопрос касался GZIPping службы REST на основе JAX-WS, но я решил изменить тему, чтобы было легче найти

Я реализую службу REST через JAX-WS Provider <Source> и публикую ее со стандартным Endpoint (причина в том, что я хочу избежать использования контейнера сервлетов или сервера приложений).

Есть ли способ сделать сервер для содержимого ответа gzip, если присутствует Accept-Encoding: gzip ?

HOW-TO

Образцы, предоставленные nicore , действительно работают, и это позволяет вам создавать сервер JAX-RS поверх встроенного легкого сервера без контейнера сервлетов, но есть несколько моментов, которые следует учитывать.

Если вы предпочитаете самостоятельно управлять классами (и сохранять время во время запуска), вы можете использовать следующее:

Пример

JAX-RS привет мирового класса:

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

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

Основной метод:

Для Простой Сервер:

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();
    }
}

Решенные зависимости:

Простой:

Grizzly:

Джерси:

Примечание

Убедитесь, что архив javax.ws.rs не попал в ваш путь к классу, поскольку он противоречит реализации Джерси. Самое худшее здесь - это бесшумная ошибка 404 без регистрации - регистрируется только небольшая заметка на уровне FINER .

    
задан Alex Abdugafarov 26.11.2011 в 10:10
источник
  • Разве это не до контейнера (Tomcat, Jetty и т. д.), чтобы разобраться? –  Donal Fellows 26.11.2011 в 10:59
  • В настоящее время мы не используем сервлеты, и эта служба REST, вероятно, является единственным местом, в котором она нам понадобится. Я действительно не думаю, что это стоит того, чтобы исследовать, настраивать и настраивать весь контейнер сервлетов только для того, чтобы замаскировать этого маленького парня. Поэтому я хочу избежать использования одного, если это возможно. –  Alex Abdugafarov 26.11.2011 в 11:07
  • Просто для ясности, примеры для Jersey 1.x и не точны для Jersey 2.x. См. Документацию для последнего случая: jersey.java.net/documentation/latest/... –  Ophidian 08.07.2014 в 22:26

3 ответа

15

Если вы действительно хотите сделать REST с Java, я предлагаю вам использовать реализацию JAX-RS (RESTeasy, Jersey ...).

Если ваша основная проблема связана с зависимостью от контейнера сервлета, вы можете использовать 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 имеет разные подходы. Джерси предоставляет фильтр , чтобы прозрачно выполнить кодирование. RESTEasy предоставляет аннотацию для этого .

ИЗМЕНИТЬ

Я сделал несколько небольших тестов. Следующие две вещи определенно будут работать для вас, если вы используете Maven .

Использование Джерси + 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 из коробки, но я не могу вспомнить его в данный момент.     

ответ дан nre 26.11.2011 в 11:12
  • Извините, но JAX-RS (и особенно это RuntimeDelegate) - одна из самых ужасных и плохо продуманных вещей, которые я когда-либо видел. Я борюсь с Джерси и RESTEasy в течение двух часов и до сих пор не понимаю, как заставить любого из них работать без контейнера сервлетов. Не могли бы вы представить простой пример того, как это реализовать? Постскриптум И btw - в какой банке есть SelectorThread? У самого гризли есть тонны банок, в то время как Джерси, похоже, не содержит этого. –  Alex Abdugafarov 26.11.2011 в 13:43
  • Ну, мне лично нравится JAX-RS, и с ним выступили некоторые довольно классные вещи. По крайней мере, это лучший вариант, чем все, что я думаю. Что касается вопроса JAR: я не могу сказать ответ, потому что я использую maven для сортировки этого для меня. Возможно, страницы wiki в Джерси помогают. –  nre 26.11.2011 в 15:44
  • Пришло время понять это, но он работает, спасибо. Я приму ваш ответ и отредактирую свой вопрос, чтобы прояснить это, если кто-то еще пойдет по этому пути. –  Alex Abdugafarov 29.11.2011 в 08:06
  • Наверное, добавив в свой значок necro здесь, на SO, но что за черт! Я изо всех сил пытаюсь заставить это работать с трюком, бросающим исключение - «Экземпляр ResourceConfig не содержит классов корневых ресурсов». Также я предполагаю, что это не требует web.xml, который является одной из вещей, которые я пробовал. Использование jersey-simple-server 1.17.1 –  sfk 24.10.2013 в 01:34
  • Второй пример работает для меня. Благодаря ;-) –  peter_pilgrim 17.09.2014 в 16:44
0

gzipping выход - это ответственность за реализацию JAX WS. Вы должны обратиться к документации сервера (Tomcat, Glassfish, JBoss и т. Д.), Чтобы настроить своих слушателей сети HTTP.     

ответ дан Osw 26.11.2011 в 16:00
0

Если вы используете CXF для реализации JAX-WS (или JAX-RS), вы можете просто добавить аннотацию @GZIP к классу службы.

    
ответ дан Daniel Kulp 26.11.2011 в 17:36