Как получить не отредактированный объект из формы с помощью spring

#html #spring #model #controller #thymeleaf

#HTML #spring #Модель #контроллер #thymeleaf

Вопрос:

У меня есть простой контроллер для оформления заказа в моем приложении
В начале, мы переносим в форму только объект нашего заказа:

 @GetMapping
    public String getOrderForm(Model model){
        model.addAttribute("orderForm", new OrderDto());
        model.addAttribute("deliveryType", orderService.getDeliveryTypeList());
        model.addAttribute("paymentType", orderService.getPaymentTypeList());
        return "create-order";
    }
 

После этого пользователь заполняет 2 поля в этом объекте, и все это выполняется следующим способом:

     @PostMapping
    public String addNewOrder(@ModelAttribute("orderForm") @Valid OrderDto orderDto,
                              @AuthenticationPrincipal UserDetails currentUser,
                              BindingResult bindingResult,
                              Model model,
                              RedirectAttributes redirectAttributes){
        User userFromBd = userRepository.findByEmail(currentUser.getUsername());
        orderDto.setUser_id(userFromBd.getId());
        List<AddressDto> savedAddress = addressService.getAllSaved(orderDto.getUser_id());
        model.addAttribute("savedAddress", savedAddress);
        model.addAttribute("addressForm", new AddressAdditionDto());
        return "order-address";
    }
 

Здесь мы передаем другие объекты в форму и позволяем пользователю заполнять их. Вот как выглядит форма:

 <!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Add new order</title>
</head>
<body>
    <div th:each="address : ${savedAddress}">
        <p>
            <span th:text="*{address.country}"></span>
        </p>
        <p>
            <span th:text="*{address.city}"></span>
        </p>
    </div>

    <form th:method="POST" th:action="@{/order/savedaddress}">
        <td>Choose adress:</td>
        <select name="addressId">
            <span th:each="address : ${savedAddress}">
                   <option th:value="${address.id}"
                           th:text="${address.id}"></option>
            </span>
        </select>
        <br>
        <label>
            <input name="submit" type="submit" value="Select"/>
        </label>
    </form>
<p><a href="/">Home</a></p>
</body>
</html>
 

В этой форме нет взаимодействия с нашим исходным объектом OrderDto. Все данные из этой формы поступают следующим способом:

     @PostMapping("/savedaddress")
    public String addAddress(@ModelAttribute("orderForm") @Valid OrderDto orderDto,
                             @RequestParam(value = "addressId", required = false) Long addressId,
                             BindingResult bindingResult,
                             Model model){
        model.addAttribute("orderForm", orderDto);
        if(orderDto.getPaymentType().equals("CARD")) {
            model.addAttribute("savedCard", cardService.getAllByUserId(orderDto.getUser_id()));
            model.addAttribute("cardForm", new CardRegisterDto());
            return "order-card";
        }
        return "order-finish";
    }
 

Но проблема в том, что мой объект OrderDto уже приходит к этому методу совершенно пустым. То есть поля, которые уже были заполнены в предыдущих формах, пусты. С чем это может быть связано?

Ответ №1:

Я думаю, что вы не использовали объект OrderDto в своем HTML-файле, что может быть причиной получения пустого объекта в качестве атрибута ModelAttribute. Вы можете использовать th:object в своей форме, например:

  <form th:method="POST" th:action="@{/order/savedaddress}" th:object="${orderForm}">
  <input type="hidden" th:field="*{user_id}">
   '''
    other code
   ''' 
</form>
 

Ответ №2:

Добавить аннотацию @sessionAttributes (типы = {OrderDto.class }) выше класса

Ответ №3:

Попробуйте это:

 <form th:method="POST" th:action="@{/order/savedaddress} th:object={orderForm}">
    <input type="hidden" th:value="${orderForm.user_id} name=userId">
    <td>Choose adress:</td>
    <select name="addressId">
        <span th:each="address : ${savedAddress}">
               <option th:value="${address.id}"
                       th:text="${address.id}"></option>
        </span>
    </select>
    <br>
    <label>
        <input name="submit" type="submit" value="Select"/>
    </label>
</form>