0

The application cannot find an object corresponding to the attribute specified in the form. Please Help !!! My controller:

    @GetMapping("/ads/{id}/edit")
public String adEdit(@PathVariable(value = "id") int id, Model model) {
    List<Platform> platforms = platformRepository.findAll();
    Ad ad = adRepository.findById(id).orElseThrow(() ->
            new ResponseStatusException(HttpStatus.NOT_FOUND,
                    "Ad having id " + id + " not found"));
    model.addAttribute("platforms", platforms);
    model.addAttribute("ad",ad);
    return "ad-edit";
}

@PostMapping("/ads/{id}/edit")
public String adUpdate(@PathVariable(value = "id") int id, @RequestBody AdDTO adDto,
                       Model model) {
    Ad ad = adRepository.findById(id).orElseThrow(() ->
            new ResponseStatusException(HttpStatus.NOT_FOUND,
                    "Ad having id " + id + " not found"));
    ad.setPlatforms((platformRepository.findAllById(adDto.platformsIds)));
    ad.setName(adDto.getName());
    ad.setAssetUrl(adDto.getAssetUrl());
    adRepository.save(ad);
    return "redirect:/ads";
}

AdDTO class:

public class AdDTO {
public int id;
public String name;
public String assetUrl;
public Status status;
public Campaign campaign;
public Set<Integer> platformsIds;

   

HTML "ad-edit":

<!DOCTYPE html>
<html>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
      integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
<link rel="stylesheet" href="/css/style.css"/>
<head>
    <meta charset="UTF-8">
    <title>Редактирование обьявления</title>
</head>
<body>
<header>
    <nav class="navbar navbar-light bg-light">
        <form class="container justify-content-start">
            <h3 class="caption">Редактирование обьявления <span th:text="${ad.name}"></span></h3>
            <button class="navbar-toggler" type="button">
                <a href="../home.html" th:href="@{/home}">На главную</a></button>
            <button type="button" class="btn btn-light">
                <a href="../info.html" th:href="@{/info}">Обе SQL Таблицы</a></button>
            <button type="button" class="btn btn-light">
                <a href="../ads.html" th:href="@{/ads}">Обьявления</a></button>
            <button type="button" class="btn btn-light">
                <a class="link" href="../campaigns.html" th:href="@{/campaigns}">Кампании</a></button>
        </form>
    </nav>
</header>
<!--<div th:object="${adDto}"  class="container justify-content-start">-->
    <form th:object="${adDto}" th:action="@{/ads/{id}/edit}" method="post">
        <input type="text" th:value="${ad.name}" th:field="*{adDto.name}"

               placeholder="Введите название обьявления" class="form-control">

        <input type="text" th:value="${ad.assetUrl}" th:field="*{adDto.assetUrl}"

               placeholder="Введите ссылку на рекламу" class="form-control">
        <!--        <h6>id кампании </h6> <h6 th:value="${el.campaign.id}"></h6>-->
        <select class="form-control" th:field="*{adDto.platformsIds}" multiple="multiple">
            <div> <option th:each="platform : ${platforms}"
                    th:value="${platform.id}"
                    th:text="${platform.name}"
                    th:selected="${adDto.platformsIds.contains(platform.id)}">
            </option> </div>
        </select>
        <button type="submit" class="btn btn-success">Редактировать</button>
    </form>
<!--</div>-->
</body>
</html>

I want to return the DTO object from the form, I think the problem in @Requestbody, and maybe not. Perhaps the problem in HTML, THYMELEAF, I am a beginner help!

image of error

1 Answer 1

0

@RequestBody is when you create a @RestController with Spring to build a REST API. If you use Thymeleaf, you use a @Controller and use @ModelAttribute instead.

In your @GetMapping method, you need to add a AdDTO instance, created from the actual Ad object, something like this:

@GetMapping("/ads/{id}/edit")
public String adEdit(@PathVariable(value = "id") int id, Model model) {
    List<Platform> platforms = platformRepository.findAll();
    Ad ad = adRepository.findById(id).orElseThrow(() ->
            new ResponseStatusException(HttpStatus.NOT_FOUND,
                    "Ad having id " + id + " not found"));
    model.addAttribute("platforms", platforms);
    model.addAttribute("adDto", mapToDto(ad)); // <-- changed line here
    return "ad-edit";
}

For the @PostMapping, use @ModelAttribute:

@PostMapping("/ads/{id}/edit")
public String adUpdate(@PathVariable(value = "id") int id, @ModelAttribute("adDto") AdDTO adDto,
                       Model model) {
    Ad ad = adRepository.findById(id).orElseThrow(() ->
            new ResponseStatusException(HttpStatus.NOT_FOUND,
                    "Ad having id " + id + " not found"));
    ad.setPlatforms((platformRepository.findAllById(adDto.platformsIds)));
    ad.setName(adDto.getName());
    ad.setAssetUrl(adDto.getAssetUrl());
    adRepository.save(ad);
    return "redirect:/ads";
}

See Form handling with Thymeleaf for more information.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Very Much!!! I need create mapper(interface) named mapToDto?
Can be just a private function in the controller, or a static method on AdDto or a separate mapper class if you use something like MapStruct.
If you have a little free time Help please: stackoverflow.com/questions/68273019/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.