BAEL-4810 Spring Boot with JSP initial sample commit
This commit is contained in:
parent
ce9f112ed6
commit
a6b215d7a3
|
@ -41,6 +41,7 @@
|
|||
<module>spring-thymeleaf</module>
|
||||
<module>spring-thymeleaf-2</module>
|
||||
<module>spring-thymeleaf-3</module>
|
||||
<module>spring-boot-jsp</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
## Spring MVC Forms JSP
|
||||
|
||||
This module contains articles about Spring Boot used with JSP
|
||||
|
||||
### Relevant Articles
|
||||
- [Spring Boot with JSP](https://www.baeldung.com/?)
|
|
@ -0,0 +1,86 @@
|
|||
<?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>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-boot-jsp</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>spring-boot-jsp</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-web-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
<version>${jstl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat.embed</groupId>
|
||||
<artifactId>tomcat-embed-jasper</artifactId>
|
||||
<!--uncomment below if external deployment-->
|
||||
<!--<scope>provided</scope>-->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!--uncomment below if external deployment-->
|
||||
<!--<dependency>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-starter-tomcat</artifactId>-->
|
||||
<!-- <scope>provided</scope>-->
|
||||
<!--</dependency>-->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>spring-boot-jsp</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<mainClass>com.baeldung.boot.jsp.SpringBootJspApplication</mainClass>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<jstl.version>1.2</jstl.version>
|
||||
<spring-boot.version>2.4.0</spring-boot.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.boot.jsp;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
|
||||
@SpringBootApplication(scanBasePackages = "com.baeldung.boot.jsp")
|
||||
public class SpringBootJspApplication extends SpringBootServletInitializer {
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
|
||||
return builder.sources(SpringBootJspApplication.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBootJspApplication.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.boot.jsp;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.baeldung.boot.jsp.repository.BookRepository;
|
||||
import com.baeldung.boot.jsp.repository.impl.InMemoryBookRepository;
|
||||
import com.baeldung.boot.jsp.repository.model.BookData;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = "com.baeldung.boot.jsp")
|
||||
public class SpringBootJspConfiguration {
|
||||
|
||||
@Bean
|
||||
public BookRepository provideBookRepository() {
|
||||
return new InMemoryBookRepository(initialBookData());
|
||||
}
|
||||
|
||||
private static Map<String, BookData> initialBookData() {
|
||||
Map<String, BookData> initData = new HashMap<>();
|
||||
initData.put("ISBN-TEST-1", new BookData("ISBN-TEST-1", "Book 1", "Book 1 Author"));
|
||||
initData.put("ISBN-TEST-2", new BookData("ISBN-TEST-2", "Book 2", "Book 2 Author"));
|
||||
initData.put("ISBN-TEST-3", new BookData("ISBN-TEST-3", "Book 3", "Book 3 Author"));
|
||||
return initData;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.baeldung.boot.jsp.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
|
||||
import com.baeldung.boot.jsp.dto.Book;
|
||||
import com.baeldung.boot.jsp.service.BookService;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/book")
|
||||
public class BookController {
|
||||
|
||||
private final BookService bookService;
|
||||
|
||||
public BookController(BookService bookService) {
|
||||
this.bookService = bookService;
|
||||
}
|
||||
|
||||
@GetMapping("/viewBooks")
|
||||
public String viewBooks(Model model) {
|
||||
model.addAttribute("books", bookService.getBooks());
|
||||
return "view-books";
|
||||
}
|
||||
|
||||
@GetMapping("/addBook")
|
||||
public String addBookView(Model model) {
|
||||
model.addAttribute("book", new Book());
|
||||
return "add-book";
|
||||
}
|
||||
|
||||
@PostMapping("/addBook")
|
||||
public RedirectView addBook(@ModelAttribute("book") Book book, RedirectAttributes redirectAttributes) {
|
||||
final RedirectView redirectView = new RedirectView("/book/addBook", true);
|
||||
Book savedBook = bookService.addBook(book);
|
||||
redirectAttributes.addFlashAttribute("savedBook", savedBook);
|
||||
redirectAttributes.addFlashAttribute("addBookSuccess", true);
|
||||
return redirectView;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.boot.jsp.dto;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class Book {
|
||||
private String isbn;
|
||||
private String name;
|
||||
private String author;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.boot.jsp.exception;
|
||||
|
||||
import com.baeldung.boot.jsp.dto.Book;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class DuplicateBookException extends RuntimeException {
|
||||
private final Book book;
|
||||
|
||||
public DuplicateBookException(Book book) {
|
||||
this.book = book;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.boot.jsp.exception;
|
||||
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
@ControllerAdvice
|
||||
public class LibraryControllerAdvice {
|
||||
|
||||
@ExceptionHandler(value = DuplicateBookException.class)
|
||||
public ModelAndView duplicateBookException(DuplicateBookException e) {
|
||||
final ModelAndView modelAndView = new ModelAndView();
|
||||
modelAndView.addObject("ref", e.getBook().getIsbn());
|
||||
modelAndView.addObject("object", e.getBook());
|
||||
modelAndView.addObject("message", "Cannot add an already existing book");
|
||||
modelAndView.setViewName("error-book");
|
||||
return modelAndView;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.baeldung.boot.jsp.repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.baeldung.boot.jsp.repository.model.BookData;
|
||||
|
||||
public interface BookRepository {
|
||||
Collection<BookData> findAll();
|
||||
|
||||
Optional<BookData> findById(String isbn);
|
||||
|
||||
BookData add(BookData book);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.boot.jsp.repository.impl;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.baeldung.boot.jsp.repository.BookRepository;
|
||||
import com.baeldung.boot.jsp.repository.model.BookData;
|
||||
|
||||
public class InMemoryBookRepository implements BookRepository {
|
||||
|
||||
private final Map<String, BookData> storedBooks;
|
||||
|
||||
public InMemoryBookRepository(Map<String, BookData> storedBooks) {
|
||||
this.storedBooks = new HashMap<>();
|
||||
this.storedBooks.putAll(storedBooks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<BookData> findAll() {
|
||||
if (storedBooks.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return storedBooks.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<BookData> findById(String isbn) {
|
||||
return Optional.ofNullable(storedBooks.get(isbn));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BookData add(BookData book) {
|
||||
storedBooks.put(book.getIsbn(), book);
|
||||
return book;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.boot.jsp.repository.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BookData {
|
||||
private String isbn;
|
||||
private String name;
|
||||
private String author;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.boot.jsp.service;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.baeldung.boot.jsp.dto.Book;
|
||||
|
||||
public interface BookService {
|
||||
Collection<Book> getBooks();
|
||||
|
||||
Book addBook(Book book);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.boot.jsp.service.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.baeldung.boot.jsp.exception.DuplicateBookException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.boot.jsp.dto.Book;
|
||||
import com.baeldung.boot.jsp.repository.BookRepository;
|
||||
import com.baeldung.boot.jsp.repository.model.BookData;
|
||||
import com.baeldung.boot.jsp.service.BookService;
|
||||
|
||||
@Service
|
||||
public class BookServiceImpl implements BookService {
|
||||
|
||||
private final BookRepository bookRepository;
|
||||
|
||||
public BookServiceImpl(BookRepository bookRepository) {
|
||||
this.bookRepository = bookRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Book> getBooks() {
|
||||
return bookRepository.findAll()
|
||||
.stream()
|
||||
.map(BookServiceImpl::convertBookData)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Book addBook(Book book) {
|
||||
final Optional<BookData> existingBook = bookRepository.findById(book.getIsbn());
|
||||
if (existingBook.isPresent()) {
|
||||
throw new DuplicateBookException(book);
|
||||
}
|
||||
|
||||
final BookData savedBook = bookRepository.add(convertBook(book));
|
||||
return convertBookData(savedBook);
|
||||
}
|
||||
|
||||
private static Book convertBookData(BookData bookData) {
|
||||
return new Book(bookData.getIsbn(), bookData.getName(), bookData.getAuthor());
|
||||
}
|
||||
|
||||
private static BookData convertBook(Book book) {
|
||||
return new BookData(book.getIsbn(), book.getName(), book.getAuthor());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
server.servlet.context-path=/spring-boot-jsp
|
||||
|
||||
spring.mvc.view.prefix: /WEB-INF/jsp/
|
||||
spring.mvc.view.suffix: .jsp
|
|
@ -0,0 +1,10 @@
|
|||
table {
|
||||
font-family: arial, sans-serif;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
td, th {
|
||||
border: 1px solid #dddddd;
|
||||
text-align: left;
|
||||
padding: 8px;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Error</title>
|
||||
</head>
|
||||
<body>
|
||||
Opps! 4xx Error Occurred.
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,23 @@
|
|||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Add Book</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<c:if test="${addBookSuccess}">
|
||||
<div>Successfully added Book with ISBN: ${savedBook.isbn}</div>
|
||||
</c:if>
|
||||
|
||||
<c:url var="add_book_url" value="/book/addBook"/>
|
||||
<form:form action="${add_book_url}" method="post" modelAttribute="book">
|
||||
<form:label path="isbn">ISBN: </form:label> <form:input type="text" path="isbn"/>
|
||||
<form:label path="name">Book Name: </form:label> <form:input type="text" path="name"/>
|
||||
<form:label path="author">Author Name: </form:label> <form:input path="author"/>
|
||||
<input type="submit" value="submit"/>
|
||||
</form:form>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<%--
|
||||
Created by IntelliJ IDEA.
|
||||
User: jason
|
||||
Date: 3/13/21
|
||||
Time: 10:39 PM
|
||||
To change this template use File | Settings | File Templates.
|
||||
--%>
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Error</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Reference: ${ref}</p>
|
||||
<p>Error Message: ${message}</p>
|
||||
<p>Object: ${object}</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,30 @@
|
|||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<html>
|
||||
<head>
|
||||
<title>View Books</title>
|
||||
|
||||
<link href="<c:url value="/css/common.css"/>" rel="stylesheet" type="text/css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ISBN</th>
|
||||
<th>Name</th>
|
||||
<th>Author</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<c:forEach items="${books}" var="book">
|
||||
<tr>
|
||||
<td>${book.isbn}</td>
|
||||
<td>${book.name}</td>
|
||||
<td>${book.author}</td>
|
||||
</tr>
|
||||
</c:forEach>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue