Java Spring Boot (Part 4)
Neil Haddley • October 29, 2023
ModelAndView
I used Spring MVC's ModelAndView class to pass model data to a Thymeleaf view template for rendering, adding a CRUD interface for the TodoItem application.
pom.xml
XML
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
JAVA
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}






