Совместное использование переменных между запросами JAX-RS

У меня есть, как мне кажется, очень простой вопрос о JAX-RS, но я почему-то не могу найти ответ.

Я пытаюсь реорганизовать службу REST, которая использует «стандартный» сервлет Javax — маршрутизацию запросов к методам вручную — в «более чистую» реализацию JAX-RS. Текущее приложение устанавливает некоторые переменные во время инициализации сервлета(). Он назначает их как атрибуты класса HttpServlet, поэтому они доступны во время каждого doGet() и могут быть переданы в качестве параметров для запросов методов обработки. Для ясности, одним из них является ConcurentHashMap, который действует как кеш.

Теперь, с помощью JAX-RS, я могу расширить приложение, чтобы установить свои классы ресурсов. Я также могу использовать аннотацию @Context в реализации каждого ресурса для внедрения таких вещей, как ServletContext, при обработке запроса. Но я не знаю, как аналогично вводить переменные, установленные при инициализации приложения.

Я использую реализацию JAX-RS Apache Wink 1.3.0.


person Frederic Fortier    schedule 18.04.2013    source источник
comment
Вы используете Весну?   -  person Paul Vargas    schedule 19.04.2013
comment
Нет, я не использую Spring.   -  person Frederic Fortier    schedule 19.04.2013


Ответы (1)


Вы можете использовать прослушиватель для инициализации кеша и установить контекст в качестве атрибута перед запуск веб-приложения. что-то вроде следующего:

package org.paulvargas.shared;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class CacheListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent sce) {
        Map<String, String> dummyCache = new HashMap<String, String>();
        dummyCache.put("greeting", "Hello Word!");

        ServletContext context = sce.getServletContext();
        context.setAttribute("dummyCache", dummyCache);
    }

    public void contextDestroyed(ServletContextEvent sce) {
        ServletContext context = sce.getServletContext();
        context.removeAttribute("dummyCache");
    }

}

Этот прослушиватель настроен в файле web.xml.

<listener>
    <listener-class>org.paulvargas.shared.CacheListener</listener-class>
</listener>
<servlet>
    <servlet-name>restSdkService</servlet-name>
    <servlet-class>
        org.apache.wink.server.internal.servlet.RestServlet
    </servlet-class>
    <init-param>
        <param-name>applicationConfigLocation</param-name>
        <param-value>/WEB-INF/application</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>restSdkService</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

Вы можете использовать аннотацию @Context для ввода ServletContext и получения атрибута.

package org.apache.wink.example.helloworld;

import java.util.*;

import javax.servlet.ServletContext;
import javax.ws.rs.*;
import javax.ws.rs.core.*;

import org.apache.wink.common.model.synd.*;

@Path("/world")
public class HelloWorld {

    @Context
    private ServletContext context;

    public static final String ID = "helloworld:1";

    @GET
    @Produces(MediaType.APPLICATION_ATOM_XML)
    public SyndEntry getGreeting() {

        Map<String, String> dummyCache = 
                       (Map<String, String>) context.getAttribute("dummyCache");

        String text = dummyCache.get("greeting");

        SyndEntry synd = new SyndEntry(new SyndText(text), ID, new Date());
        return synd;
    }

}
person Paul Vargas    schedule 19.04.2013
comment
Это близко к тому, что я думал: установить атрибут сервлета во время инициализации и получить его обратно из контекста сервлета во время каждого запроса. Но не будет запускать doFilter во время каждого запроса. Есть ли способ получить доступ к контексту во время init() сервлета и установить атрибут один раз? - person Frederic Fortier; 20.04.2013
comment
Выглядит отлично. Спасибо за вашу помощь! - person Frederic Fortier; 23.04.2013
comment
@PaulVargas .. Я искал что-то подобное, но я хотел запустить executorservice в servletContext при инициализации. Спасибо. за ваш ответ :) - person ; 11.06.2015
comment
Привет, @ Dc01_xx Другое решение — использовать @Singleton (Enterprise JavaBean). Если у меня будет время, я добавлю его к своему ответу. :-) - person Paul Vargas; 11.06.2015