0

My directory

I'm trying to create spring boot application for school that lists books to a html page from database with a controller.

Personally, i think that the problem is that the controller cannot find the template for some reason. Because when i navigate to the wanted template through chrome, it just shows "booklist" on the page, nothing else.

I've tried creating totally new project and copying the code from my other files to the new files with no results.

My controller class:

@Controller
@ResponseBody
public class BookController {
@Autowired
BookRepository bookRepository;

@RequestMapping(value = "/books", method = RequestMethod.GET)
public String getBooks(Model model) {
    List<Book> books =  (List<Book>) bookRepository.findAll();
    model.addAttribute("books", books);
    return "booklist";
}

My html template:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Book List</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Books</h1>
<table>
    <tr>
        <th>Id</th>
        <th>Title</th>
        <th>Year</th>
        <th>Isbn</th>
        <th>Price</th>
    </tr>

    <tr th:each="book : ${books}">
        <td th:text="${book.id}">id</td>
        <td th:text="${book.title}">title</td>
        <td th:text="${book.year}">year</td>
        <td th:text="${book.isbn}">isbn</td>
        <td th:text="${book.price}">price</td>

    </tr>
</table>
</body>
</html>

pom.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.2.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>hh.swd20</groupId>
<artifactId>Bookstore</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Bookstore</name>
<description>Demo project for Spring Boot</description>

<properties>
    <java.version>1.8</java.version>
</properties>

<dependencies>

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

</project>

application.properties file:

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.jpa.show-sql=true
hc_dev
  • 8,389
  • 1
  • 26
  • 38
Roni
  • 11
  • 9

2 Answers2

2

Remove the annotation @ResponseBody from your controller class, because:

The @ResponseBody annotation tells a controller that the object returned is automatically serialized into JSON and passed back into the HttpResponse object.

Then the returned String booklist will be used by Spring-MVC to resolve the named HTML template file.

The template file (e.g. booklist.html) will be looked for by default within default template directory is src/main/resources/templates.

Otherwise make sure to have configured the ViewResolver properly.

For Thymeleaf you have to add dependency to your Maven POM:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

See also this Spring-Boot & Thymeleaf tutorial

hc_dev
  • 8,389
  • 1
  • 26
  • 38
  • I did, but then i get whitelabel error page that says "This application has no explicit mapping for /error, so you are seeing this as a fallback." – Roni Feb 10 '19 at 18:45
  • @Roni Thanks for updates and directory-structure. Looks OK. What about Thymeleaf in your pom.xml? How is your BookstoreApplication class configured/annotated (including application.properties) ? Do the other templates shown work? – hc_dev Feb 10 '19 at 19:22
  • i'll add them to the original post, thanks! None of the other templates work unfortunately. – Roni Feb 10 '19 at 19:59
  • @Roni Now it's clear thanks for your POM and other templates failed too. Add dependency (see my answer) and ViewResolver is auto-configured to find your templates. – hc_dev Feb 10 '19 at 20:15
  • Oh my god, thank you so much! It finally worked! I was fighting with this problem for hours! – Roni Feb 10 '19 at 20:26
0

You can try this .

Hit : localhost://yourportnumber/api/books

//@Controller
  @RestController
//@ResponseBody
  @RequestMapping("/api")
  public class BookController {
  @Autowired
  BookRepository bookRepository;

  @GetMapping(value = "/books", method = RequestMethod.GET)
  public ModelAndView getBooks(Model model) {
  List<Book> books =  (List<Book>) bookRepository.findAll();
  model.addAttribute("books", books);
  ModelAndView mav = new ModelAndView("booklist");
  return mav;

}
AchillesVan
  • 4,156
  • 3
  • 35
  • 47
  • whitelabel error page. This application has no explicit mapping for /error, so you are seeing this as a fallback. There was an unexpected error (type=Not Found, status=404). No message available – Roni Feb 10 '19 at 20:23
  • Sorry. But actually _@RestController_ includes _@ResponseBody_ which is useful for serving REST-responses as direct body. But Roni's MVC approach with String and simple _@Controller_ without _@ResponseBody_ is cleaner. – hc_dev Feb 10 '19 at 20:23
  • Yes @Controller should be fine. Please try my updated answer. – AchillesVan Feb 10 '19 at 20:30