Как обновить компонент фронтенда Spring Boot

Рейтинг: -2Ответов: 1Опубликовано: 04.04.2023

Есть форма на фронте:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head></head>
<body>

<div class="container">

        <div class="form_wrapper">
            <form th:method="post" action="/" th:object="${dates}">

                <div class="dates_wrapper">
                    <p th:if="${dateError}" style="color:red">Укажите даты</p>
                    <input class="dates_class" type="date" id="bgnDate" th:value="${bgnDate}" name="bgnDate" placeholder="Дата начала расчета"/>
                    <input class="dates_class" type="date" id="endDate" th:value="${endDate}" name="endDate" placeholder="Дата конца расчета"/>
                </div>

                <div class="otd_checks_wrapper">
                    <!--inputs -->
                </div>

                <!--<input type="submit" value="Запустить" name="startButton">-->
                <button type="button" onclick="postData()">Запустить</button>

                <div class="log_wrapper">
                    <textarea class="logs" name="logs" id="logs"></textarea>
                </div>

            </form>
        </div>

</div>

<script>
    const logsTextArea = document.querySelector('#logs');
    let lastUpdatedMessage = '';

    function getLogsAndUpdateTextArea() {
        fetch('/logs')
            .then(response => response.text())
            .then(data => {
                if (data !== lastUpdatedMessage) {
                    logsTextArea.value += data;
                    logsTextArea.scrollTop = logsTextArea.scrollHeight;
                    lastUpdatedMessage = data;
                }
            });
    }

    setInterval(getLogsAndUpdateTextArea);
</script>

<script>
    function postData() {
        var formData = new FormData(document.querySelector("form"));

        fetch("/", {
            method: "POST",
            body: formData,
        })
            .then((response) => {
                if (response.ok) {
                    return response.text();
                } else {
                    throw new Error("Ошибка запроса.");
                }
            })
            .then((result) => {
                alert(result);
            })
            .catch((error) => {
                alert(error);
            });
    }
</script>

</body>
</html>

В компонент <textarea class="logs" name="logs" id="logs"></textarea> нужно выводить сообщения из метода createFile.getMessage();

Есть контроллер:

@RestController
@RequestMapping("/logs")
public class LogsController implements MessageUpdateListener {

    private final CreateFile createFile;
    private String lastMessageUpdate = "";
    private String currentMessageUpdate = "";

    @Autowired
    public LogsController(CreateFile createFile) {
        this.createFile= createFile;
        this.createFile.addMessageUpdateListener(this);
    }

    @GetMapping
    public ResponseEntity<String> getLogs() {
        String message = createFile.getMessage();
        if (!message.equals(lastMessageUpdate)) {
            currentMessageUpdate = message;
            lastMessageUpdate = message;
        }
        return ResponseEntity.ok(currentMessageUpdate + "\n");
    }

    @Override
    public void onMessageUpdate(String message) {
        currentMessageUpdate = message;
    }
}

Интерфейс:

public interface MessageUpdateListener {
    void onMessageUpdate(String message);
}

Класс:

@Service
public class CreateFile {

    private String message = "";
    private final List<MessageUpdateListener> messageUpdateListeners = new ArrayList<>();

    @Autowired
    public CreateFile() {}

    public void addMessageUpdateListener(MessageUpdateListener listener) {
        messageUpdateListeners.add(listener);
        listener.onMessageUpdate(message);
    }

    public void removeMessageUpdateListener(MessageUpdateListener listener) {
        messageUpdateListeners.remove(listener);
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        if (!this.message.equals(message)) {
            this.message = message;
            notifyMessageUpdateListener(message);
        }
    }

    private void notifyMessageUpdateListener(String message) {
        for (MessageUpdateListener listener : messageUpdateListeners) {
            listener.onMessageUpdate(message);
        }
    }

    public List<Usl> readDBF(String[] check_otd) {
        ***
        setMessage("Чтение данных ");
        ***
    }

    public List<Usl> selectCorrectUsl(String[] checks) {
        List<Usl> list = readDBF(checks);
        
        setMessage("Проверка корректности услуг. Начало");

        return list;
    }

}

Основной контроллер:

@Controller
public class MainController {
    private final CreateFile createFile

    @Autowired
    public MainController(CreateFile createFile) {
        this.createFile = createFile;
    }

    @GetMapping("/")
    public String main(Model model) {

        LocalDate currentDate = LocalDate.now();
        LocalDate bgnDate = currentDate.withDayOfMonth(1);
        LocalDate endDate = bgnDate.plusDays(bgnDate.lengthOfMonth() - 1);

        model.addAttribute("bgnDate", bgnDate);
        model.addAttribute("endDate", endDate);
        return "index";
    }

    @PostMapping("/")
    public ResponseEntity<String> post(
            @RequestParam(required = false) String[] check_otd,
            @RequestParam(required = false) LocalDate bgnDate,
            @RequestParam(required = false) LocalDate endDate,
            RedirectAttributes redirectAttributes) {

        createFile.getPeriod(bgnDate, endDate);
                createFile.selectCorrectUsl(check_otd);
                createFile.createFile(createFile.getUslBlock());
    }


}

Как обновить компонент textarea с фронта чтобы каждый при вызове метода setMessage в textarea выводилось значение, которое туда поместили.

Ответы

▲ 0

Так как представление у Вас генерируется не на сервере, а на фронте, то только фронт может решить и произвести обновление компонентов. Чтобы фронт понял, что это необходимо, то в ответ на ваш запрос на сервер после отправки формы возвращайте то сообщение назад на клиент.

  1. Данное решение можно реализовать с помощью вебсокетов
  2. Либо же на стороне клиента, так как Ваши сообщения не зависят от запроса, то можно просто указать в JS коде обновление textarea после отправки сообщения на сервер
  3. Получать после отправки на сервер ответ с него и изменять значение textarea этим ответом