Fi0x
Fi0x

Reputation: 185

Spring MVC pass object from list to post-endpoint

I have a spring-controller with a post-endpoint that receives a WordDto. Another get-endpoint puts a list of WordDtos in the ModelMap and shows a jsp-file. In the jsp-file, I show each entry of the list in a row of a table. Each row has additionally a button, that should call the post-endpoint with the WordDto for that row.

But I don't know, how to pass the WordDto from the row correctly to the post-endpoint.

Endpoints

    @GetMapping("/generate")
    public String generateWords(ModelMap model, @RequestParam(value = "language", defaultValue = "-1", required = false) long language, @RequestParam(value = "amount", defaultValue = "-1", required = false) int amount)
    {
        model.put("language", language);
        model.put("amount", amount);

        LanguageData languageData = languageService.getLanguageData(language);

        model.put("languageName", languageData.getName());
        model.put("words", generationService.generateWords(language, amount));

        return "list-words";
    }

    @PostMapping("word")
    public String saveWord(ModelMap model, HttpServletRequest request, @Valid WordDto singleWord)
    {
        translationService.saveOrGetWord(singleWord);

        return "redirect:" + request.getHeader("Referer");
    }

jsp-file

<body>
    <%--@elvariable id="languageName" type="java.lang.String"--%>
    <h1>Generated words with '${languageName}'</h1>
    <table class="table">
        <thead>
        <tr>
            <th>Word</th>
        </tr>
        </thead>
        <tbody>
        <%--@elvariable id="words" type="java.util.List"--%>
        <c:forEach items="${words}" var="singleWord">
            <tr>
                <td>
                        ${singleWord.word}
                </td>
                <td>
                    <form:form method="post" action="word" modelAttribute="singleWord.word">
                        <form:input type="hidden" path="languageId"/>
                        <form:input type="text" path="word"/>
                    </form:form>
                </td>
            </tr>
        </c:forEach>
        </tbody>
    </table>
</body>

How can I send the WordDto, that I have in a row in the jsp-table, to the /word endpoint?

Upvotes: 0

Views: 47

Answers (1)

Fi0x
Fi0x

Reputation: 185

I got it working, but only with different approach, that is (in my eyes) not as nice as I originally planned. The new version takes two parameters, instead of the entire object at once.

I adjusted the table to look like this:

        <tbody>
        <%--@elvariable id="words" type="java.util.List"--%>
        <c:forEach items="${words}" var="singleWord" varStatus="status">
            <tr>
                <form:form method="post" action="word">
                    <input type="hidden" name="languageId" value="${singleWord.languageId}"/>
                    <td>
                        <label>
                            <input type="text" name="word" value="${singleWord.word}"/>
                        </label>
                    </td>
                    <td>
                            <%--TODO: Add button to show translation page for this word (Should also save the word before showing the page, if it is not yet saved)--%>
                    </td>
                    <td>
                        <input type="submit" class="btn-success" value="Save">
                    </td>
                </form:form>
            </tr>
        </c:forEach>
        </tbody

And the endpoint had to be modified too:

    @PostMapping("word")
    public String saveWord(HttpServletRequest request, @RequestParam(value = "languageId") long languageId, @RequestParam(value = "word") String word)
    {
        translationService.saveOrGetWord(new WordDto(languageId, word));

        return "redirect:" + request.getHeader("Referer");
    }

Upvotes: 0

Related Questions