Запланированное задание с помощью аннотаций в сервлете не работает - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть сервер, который обрабатывает запросы, и с регулярными интервалами (каждые 1-2 минуты) необходимо вызывать другой сервер и обновлять список объектов, который используется для создания ответа на запрос. Вдохновленный, например, принятым ответом на этот вопрос, я попытался использовать аннотацию «Расписание», но не смог заставить ее работать.

Как запустить фоновую задачу в веб-приложении на основе сервлетов?

Упрощенное представление сервера:

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "MyServer", urlPatterns = {"/data/*", "/scheduled/*"}, loadOnStartup = 1)
public class MyServlet extends HttpServlet {

    private static final String UTF_8 = "UTF-8";
    private static final String APPLICATION_JSON = "application/json";
    private static final long serialVersionUID = 1L;
    private static connector connector;

    public MyServlet() {
        super();
    }

    public void destroy() {}

    @Override
    public void init() throws ServletException {
        connector = new connector();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String path = request.getServletPath();
        String pathInfo = request.getPathInfo().substring(1);
        response.setContentType(APPLICATION_JSON);
        response.setCharacterEncoding(UTF_8);

        if (path.endsWith("/data")) {
            List<DataItem> dataItems = connector.currentData;
            response.getWriter().write(JsonUtility.convertToJsonString(dataItems));
        } else if (path.endsWith("/scheduled")) {
            connector.fetchData();
            response.getWriter().write("Done");
        } else {
            response.getWriter()
            .write(pathInfo + " Is not Found but not returning 404");
            return;
        }
    }
}

Класс соединителя, который должен обновлять сохраненные данные с другого сервера через равные промежутки времени:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.ejb.Startup;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

@Startup
@Singleton
public class Connector {
    public List<DataItem> currentData = new LinkedList<>();

    @Lock(LockType.READ)
    @Schedule(second = "*", minute = "*/2", hour = "*", persistent = false)
    public void fetchNews() {
        logger.debug("Fetching data");
        String response = sendGet(url, bearerToken);

        JsonObject json = new Gson().fromJson(response, JsonObject.class);
        //Transform the response to a list of DataItems.
        List<DataItem> retrievedData = toDataList(json)

        System.out.println(retrievedData);
        synchronized(currentData) {
            currentData = retrievedData;
        }

    }

    private String sendGet(String path, String authorizationProperty) {
        URL url;
        try {
            url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setRequestProperty("Authorization", authorizationProperty);
            conn.setRequestProperty("Content-Type","application/json");
            conn.setRequestMethod("GET");

            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String output;

            StringBuffer response = new StringBuffer();
            while ((output = in.readLine()) != null) {
                response.append(output);
            }

            in.close();
            return response.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

Однако метод fetchData запускается не каждую секунду, как я ожидал. Я не знаю, чего мне не хватает. Я немного поигрался с добавлением / удалением аннотации @Startup, создавая экземпляр класса в методе init () на сервере, но все равно ничего не дал.

...