Java Spring Boot (Part 4)
Neil Haddley • October 29, 2023
ModelAndView
In Java Spring, ModelAndView is a class that represents both a model and a view for a web application. It is typically used in the context of Spring MVC (Model-View-Controller) to handle web requests and provide a way to pass data to a view template for rendering.
Using ModelAndView allows you to separate the model data and the view template, making your code more modular and following the MVC pattern, which is a common architectural pattern in web development. Note that in more recent versions of Spring, you can often return a Map or a POJO directly from a controller method, simplifying the code and eliminating the need for ModelAndView.

I added thymeleaf, bootstrap and jquery as dependencies

I added a thymeleaf page (as an alternative to JSP)

I updated the controller to populate the fetch the todo items and to pass them and the current day of the week to the thymeleaf view.

The new home page displays the todo items

I updated the controller to handle a delete request

I clicked the Delete button on the second todo item

The second todo item has been deleted
pom.xml
TEXT
1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 <parent> 6 <groupId>org.springframework.boot</groupId> 7 <artifactId>spring-boot-starter-parent</artifactId> 8 <version>3.1.5</version> 9 <relativePath/> <!-- lookup parent from repository --> 10 </parent> 11 <groupId>com.haddley</groupId> 12 <artifactId>springdatajpa</artifactId> 13 <version>0.0.1-SNAPSHOT</version> 14 <name>springdatajpa</name> 15 <description>Demo project for Spring Boot</description> 16 <properties> 17 <java.version>17</java.version> 18 </properties> 19 <dependencies> 20 <dependency> 21 <groupId>org.springframework.boot</groupId> 22 <artifactId>spring-boot-starter-data-jpa</artifactId> 23 </dependency> 24 <dependency> 25 <groupId>org.springframework.boot</groupId> 26 <artifactId>spring-boot-starter-validation</artifactId> 27 </dependency> 28 <dependency> 29 <groupId>org.springframework.boot</groupId> 30 <artifactId>spring-boot-starter-web</artifactId> 31 </dependency> 32 33 <dependency> 34 <groupId>org.springframework.boot</groupId> 35 <artifactId>spring-boot-devtools</artifactId> 36 <scope>runtime</scope> 37 <optional>true</optional> 38 </dependency> 39 <dependency> 40 <groupId>com.h2database</groupId> 41 <artifactId>h2</artifactId> 42 <scope>runtime</scope> 43 </dependency> 44 <dependency> 45 <groupId>org.projectlombok</groupId> 46 <artifactId>lombok</artifactId> 47 <optional>true</optional> 48 </dependency> 49 <dependency> 50 <groupId>org.springframework.boot</groupId> 51 <artifactId>spring-boot-starter-test</artifactId> 52 <scope>test</scope> 53 </dependency> 54 55 <dependency> 56 <groupId>org.springframework.boot</groupId> 57 <artifactId>spring-boot-starter-thymeleaf</artifactId> 58 </dependency> 59 60 <!-- https://mvnrepository.com/artifact/org.webjars/bootstrap --> 61 <dependency> 62 <groupId>org.webjars</groupId> 63 <artifactId>bootstrap</artifactId> 64 <version>3.4.1</version> 65 </dependency> 66 <!-- https://mvnrepository.com/artifact/org.webjars/jquery --> 67 <dependency> 68 <groupId>org.webjars</groupId> 69 <artifactId>jquery</artifactId> 70 <version>3.6.0</version> 71 </dependency> 72 73 </dependencies> 74 75 <build> 76 <plugins> 77 <plugin> 78 <groupId>org.springframework.boot</groupId> 79 <artifactId>spring-boot-maven-plugin</artifactId> 80 <configuration> 81 <excludes> 82 <exclude> 83 <groupId>org.projectlombok</groupId> 84 <artifactId>lombok</artifactId> 85 </exclude> 86 </excludes> 87 </configuration> 88 </plugin> 89 </plugins> 90 </build> 91 92</project>
SpringdatajpaApplication.java
TEXT
1package com.haddley.springdatajpa; 2 3import org.springframework.boot.SpringApplication; 4import org.springframework.boot.autoconfigure.SpringBootApplication; 5 6import org.springframework.web.bind.annotation.GetMapping; 7import org.springframework.web.bind.annotation.RequestParam; 8import org.springframework.web.bind.annotation.RestController; 9import org.springframework.stereotype.Controller; 10 11import com.haddley.springdatajpa.models.TodoItem; 12import com.haddley.springdatajpa.repositories.TodoItemRepository; 13import org.springframework.beans.factory.annotation.Autowired; 14 15import java.util.stream.StreamSupport; 16import java.util.stream.Collectors; 17 18import org.springframework.web.servlet.ModelAndView; 19import org.springframework.ui.Model; 20import java.time.ZoneId; 21import java.time.Instant; 22 23import org.slf4j.Logger; 24import org.slf4j.LoggerFactory; 25 26import org.springframework.web.bind.annotation.PathVariable; 27 28@SpringBootApplication 29@Controller 30public class SpringdatajpaApplication { 31 32 private final Logger logger = LoggerFactory.getLogger(SpringdatajpaApplication.class); 33 34 public static void main(String[] args) { 35 SpringApplication.run(SpringdatajpaApplication.class, args); 36 } 37 38 @Autowired 39 private TodoItemRepository todoItemRepository; 40 41 @GetMapping("/") 42 public ModelAndView index() { 43 logger.info("request to GET index"); 44 ModelAndView modelAndView = new ModelAndView("index"); 45 modelAndView.addObject("todoItems", todoItemRepository.findAll()); 46 modelAndView.addObject("today", Instant.now().atZone(ZoneId.systemDefault()).toLocalDate().getDayOfWeek()); 47 return modelAndView; 48 } 49 50 @GetMapping("/delete/{id}") 51 public String deleteTodoItem(@PathVariable("id") long id, Model model) { 52 TodoItem todoItem = todoItemRepository 53 .findById(id) 54 .orElseThrow(() -> new IllegalArgumentException("TodoItem id: " + id + " not found")); 55 56 todoItemRepository.delete(todoItem); 57 return "redirect:/"; 58 } 59 60 61}