I am just teaching myself the Spring framework and am trying to makie a simple library app which stores user (book) inputs in a form in the H2 Database, and then shows the user the newly inputted data from the H2 Database.
Form submission attempt 1:
I now have a working POST method which correctly saves a new book to the H2 repository – however when I try to connect this method to the submission of a form, no such repository stores occur.
Form submission attempt 2:
Working POST request using POSTman 3:
Working POST request using POSTman 4:
Code snippets below:
HTMLfile with the Thymeleaf form inside:
<h2> Enter a book below to add it to your basket: </h2> <form action="/addToBasket" th:action="@{/addToBasket}" th:object="${book}" method="post"> <p> Book Title: <input type="text" th:field="*{bookTitle}"></p> <p> Author: <input type="text" th:field="*{bookAuthor}"></p> <p> publicationYear: <input type="text" th:field="*{publicationYear}"></p> <p> price: <input type="text" th:field="*{price}"></p> <br> <!-- <input type="submit" value="Submit">--> <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p> </form> </body> </html>
POST method in the controller class which works for POST requests from POSTman, but fails to store the form data in the same way:
@PostMapping("/addToBasket") public Basket addToBasket(@RequestBody Basket newBook) { return basketRepository.save(newBook); }
Basket @entity:
@Entity public class Basket { private @Id @GeneratedValue Long basketId; private String bookTitle; private String author; private String publisher; public Basket() { } public Basket( String bookTitle, String author, String publisher) { this.bookTitle = bookTitle; this.author = author; this.publisher = publisher; }
Advertisement
Answer
For anyone wondering, this is how you do it…
Set the form up like below, (it just needs to point to the name of the path in the controller method):
<form action="/addToBasket" method="post"> B name:<input name="bookTitle" value="yosi"/><br> A name:<input name="author" value="lev"/><br> <input type="submit"/> </form>
Then set up the method in the controller like so:
@RequestMapping(value = "/addToBasket", method = RequestMethod.POST) public @ResponseBody String test( Basket basket) { basketRepository.save(basket); return "Hello test : " + basket; }
^It takes in the inputs from the form as a Basket object so you just need to save this to the appropriate repository, make sure you have a toString() method in this Basket class so you can print out the results if necessary to do so
This is my Basket class in case this is useful:
package springLibrary.domain; import javax.persistence.*; import java.util.HashMap; import java.util.HashSet; import java.util.Objects; import java.util.Set; @Entity public class Basket { // private Set<Book> bookBasket = new HashSet<>(); private @Id @GeneratedValue Long basketId; private String bookTitle; private String author; private String publisher; public Basket() { } public Basket( String bookTitle, String author, String publisher) { this.bookTitle = bookTitle; this.author = author; this.publisher = publisher; } public Long getBasketId() { return basketId; } public void setBasketId(Long basketId) { this.basketId = basketId; } public String getBookTitle() { return bookTitle; } public void setBookTitle(String bookTitle) { this.bookTitle = bookTitle; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getPublisher() { return publisher; } public void setPublisher(String publisher) { this.publisher = publisher; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Basket basket = (Basket) o; return Objects.equals(basketId, basket.basketId); } @Override public String toString() { return "Basket{" + "basketId=" + basketId + ", bookTitle='" + bookTitle + ''' + ", author='" + author + ''' + ", publisher='" + publisher + ''' + '}'; } @Override public int hashCode() { return Objects.hash(basketId); } }
^it has the same variable names as those used in the HTML file.
When you run your locally hosted site, if you have an appropriate getter for basket e.g
@RequestMapping("/basket") public String getBasket(Model model){ model.addAttribute("basket", basketRepository.findAll()); return "basket/list"; }
… then you should be able to see your newly stored basket object in your basket repository.