Автоматическое обновление данных из БД на странице

198
28 декабря 2021, 20:10

Реализую небольшой maven-проект с выводом данных из БД. Проект основан на MVC архитектуре и суть его такова: на главной странице (index.jsp) находится таблица с информацией о фильмах, кроме того здесь же присутствует возможность редактирования каждого из них, удаления и добавления нового. В качестве модели используются класс film и класс filmsDatabase, который получает данные из БД (использую PostgreSQL):

    public class Film {
    public int id;
    public String title;
    public String genre;
    public String director;
    public int year;
    public int rating;
    public Film(String title, String genre, String director, int year, int rating) {
        this.title = title;
        this.genre = genre;
        this.director = director;
        this.year = year;
        this.rating = rating;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getId() {
        return id;
    }
    public String getTitle() {
        return title;
    }
    public String getGenre() {
        return genre;
    }
    public String getDirector() {
        return director;
    }
    public int getYear() {
        return year;
    }
    public int getRating() {
        return rating;
    }
}

public class FilmsDatabase {
    private static final String DB_URL = "jdbc:postgresql://localhost/test";
    private static final String USER = "postgres";
    private static final String PASS = "*";
    private static Connection getDBConnection() {
        Connection dbConnection = null;
        try {
            Class.forName("org.postresql.Driver");
        } catch (ClassNotFoundException e) {
            System.out.println(e.getMessage());
        }
        //System.out.println("PostgreSQL JDBC Driver successfully connected");
        try {
            dbConnection = DriverManager.getConnection(DB_URL, USER, PASS);
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
        if (dbConnection != null) {
            //System.out.println("You successfully connected to database now");
        }
        return dbConnection;
    }
    public static ArrayList<Film> select() throws SQLException{
        ArrayList<Film> films = new ArrayList<>();
        String query = "SELECT * FROM films ORDER BY id";
        try (Connection dbConnection = getDBConnection(); Statement stmt = dbConnection.createStatement()) {
            ResultSet rs = stmt.executeQuery(query);
            while(rs.next()) {
                int id = rs.getInt("id");
                String title = rs.getString("title");
                String genre = rs.getString("genre");
                String director = rs.getString("director");
                int year = rs.getInt("year");
                int rating = rs.getInt("rating");
                Film film = new Film(title, genre, director, year, rating);
                films.add(film);
                film.setId(id);
            }
        } catch(SQLException e) {
            System.out.println(e.getMessage());
        }
        return films;
    }
    public static void insert(Film film) throws SQLException {
        String query = "INSERT INTO films(title, genre, director, year, rating) VALUES(?, ?, ?, ?, ?)";
        try (Connection dbConnection = getDBConnection(); PreparedStatement statement = dbConnection.prepareStatement(query)) {
            statement.setString(1, film.getTitle());
            statement.setString(2, film.getGenre());
            statement.setString(3, film.getDirector());
            statement.setInt(4, film.getYear());
            statement.setInt(5, film.getRating());
            statement.executeUpdate();
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
    }
    public static Film selectOne(int id) {
        String query = "SELECT * FROM films WHERE id = ?";
        Film film = null;
        try (Connection dbConnection = getDBConnection(); PreparedStatement stmt = dbConnection.prepareStatement(query)) {
            stmt.setInt(1, id);
            ResultSet rs = stmt.executeQuery();
            if (rs.next()){
                String title = rs.getString("title");
                String genre = rs.getString("genre");
                String director = rs.getString("director");
                int year = rs.getInt("year");
                int rating = rs.getInt("rating");
                film = new Film(title, genre, director, year, rating);
            }
        } catch(SQLException e) {
            System.out.println(e.getMessage());
        }
        return film;
    }
    public static void update(Film film) {
        String query = "UPDATE films SET title = ?, genre = ?, director = ?, year = ?, rating = ? WHERE id = ?";
        try (Connection dbConnection = getDBConnection(); PreparedStatement stmt = dbConnection.prepareStatement(query)) {
            stmt.setString(1, film.getTitle());
            stmt.setString(2, film.getGenre());
            stmt.setString(3, film.getDirector());
            stmt.setInt(4, film.getYear());
            stmt.setInt(5, film.getRating());
            stmt.setInt(6, film.getId());
            stmt.executeUpdate();
        } catch(SQLException e) {
            System.out.println(e.getMessage());
        }
    }
    public static void delete(int id) {
        String query = "DELETE FROM films WHERE id = ?";
        try(Connection dbConnection = getDBConnection(); PreparedStatement stmt = dbConnection.prepareStatement(query)) {
            stmt.setInt(1, id);
            stmt.executeUpdate();
        } catch(SQLException e) {
            System.out.println(e.getMessage());
        }
    }
}

Для реализации контроллеров я использовал java servlet. Как пример, страница добавления нового фильма и соответствующий ей CreateServlet:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Добавление нового фильма</title>
</head>
<body>
<h2>Добавление нового фильма</h2>
<form method="post">
    <label>Название фильма</label><br>
    <input name="title"/><br><br>
    <label>Жанр фильма</label><br>
    <input name="genre"/><br><br>
    <label>Режиссер фильма</label><br>
    <input name="director"/><br><br>
    <label>Год выхода фильма</label><br>
    <input name="year" type="number"/><br><br>
    <label>Рейтинг фильма</label><br>
    <input name="rating" type="number"/><br><br>
    <input type="submit" value="Сохранить"/>
</form>
</body>
</html>
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CreateServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        getServletContext().getRequestDispatcher("/create.jsp").forward(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            request.setCharacterEncoding("utf-8");
            String title = request.getParameter("title");
            String genre = request.getParameter("genre");
            String director = request.getParameter("director");
            int year = Integer.parseInt(request.getParameter("year"));
            int rating = Integer.parseInt(request.getParameter("rating"));
            Film film = new Film(title, genre, director, year, rating);
            FilmsDatabase.insert(film);
            response.sendRedirect(request.getContextPath() + "/index");
        } catch(Exception ex) {
            getServletContext().getRequestDispatcher("/create.jsp").forward(request, response);
        }
    }
}

Теперь же возникла необходимость реализовать автоматическое обновление главной страницы при любом обновлении информации в БД. Т.е. например если открыть две одинаковые вкладки в браузере и в одной изменить информацию - вторая должна автоматически обновиться (ну или хотя бы вывести предупреждение, что мол "информация обновилась, не хотите ли вы обновить страницу?"). И тут возник вопрос как это реализовать. Пытался гуглить в интернете, находил множество примеров с онлайн-чатами, но так и не смог понять алгоритм, по которому мне это нужно сделать. Пока что пришел лишь к выводу, что скорее всего нужно использовать websocket. Попробовал реализовать ServerEndpoint класс, но дальше дело не продвинулось...

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@ServerEndpoint("/ws")
public class PushUpdates {
    private static final Set<Session> SESSIONS = ConcurrentHashMap.newKeySet();
    @OnOpen
    public void onOpen(Session session) {
        SESSIONS.add(session);
    }
    @OnClose
    public void onClose(Session session) {
        SESSIONS.remove(session);
    }
    public static void sendAll(Film film) {
        synchronized (SESSIONS) {
            for (Session session : SESSIONS) {
                if (session.isOpen()) {
                    session.getAsyncRemote().sendObject(film);
                }
            }
        }
    }
}

Не могли ли вы мне подсказать как это можно реализовать?

Answer 1

каждая страница должна иметь подключение к северу по ws, и передавая информацию на сервер с одной страницы нужно отправить на другую(другие) которые "подписаны" на такие события.

READ ALSO
ошибка IOException

ошибка IOException

приложение должно сохранять файл с логином и паролем, затем при открытии приложения или при вводе данных проверять пароль, если он совпадает...

160
Сортировка списка массивов

Сортировка списка массивов

Имеется список содержащий массивы

221
Сортировка одинаковых фамилий

Сортировка одинаковых фамилий

Имеется следующий код

217
FCM уведомления не доходят

FCM уведомления не доходят

Не приходят push уведомленияПри отсылке сервер гугла возвращает {"multicast_id":410383576077558298,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1576316927466102%b078b91ff9fd7ecd"}]}...

194