[JAVA] Spring thorough introduction version upgrade memo

"A thorough introduction to Spring" called a good book to learn the Spring Framework. I try to learn while implementing the tutorial, I made a note of it because I sometimes stumbled on it unlike my own environment. I tried to fix it as far as I can understand, but maybe there is still ...?

environment

Book My environment
Spring Framework 4.2.6 5.2.3
Spring Boot 1.3.5 2.2.4
Thymeleaf 2.1.0 3.0.4
thymeleaf-extras-springsecurity4 2.1.2 -
thymeleaf-extras-springsecurity5 - 3.0.4
SQL * This is changed due to personal environmental issues PostgreSQL MySQL

Changes

Property file settings

p.643 Changed for MySQL

application.properties


spring.jpa.database=MYSQL
spring.datasource.url=jdbc:mysql://localhost:3306/spring_tutorial
spring.datasource.username=*****
spring.datasource.password=*****
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.initialization-mode=always
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.format_sql=true
spring.datasource.sql-script-encoding=UTF-8
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
spring.datasource.separator=/;

Data.sql and schema.sql are also changed for MySQL.

Injection change

Changed field injection to constructor injection. Constructor injection is the most recommended of the three DI methods. The description will increase, but the field can be immutable.

@Autowired can be omitted if there is only one constructor in the class (it is omitted below)

Service class

RoomService.java


 //Change before
 @Autowired
 ReservableRoomRepository reservableRoomRepository;
	
 @Autowired
 MeetingRoomRepository meetingRoomRepository;

 //After change
 private final ReservableRoomRepository reservableRoomRepository;
 private final MeetingRoomRepository meetingRoomRepository;
	
 public RoomService(ReservableRoomRepository reservableRoomRepository, 
				MeetingRoomRepository meetingRoomRepository) {
	this.reservableRoomRepository = reservableRoomRepository;
	this.meetingRoomRepository = meetingRoomRepository;
 }

ReservationUserDetailsService.java


 //Change before
 @Autowired
 UserRepository userRepository;

 //After change
 private final UserRepository userRepository;
	
 public ReservationUserDetailsService(UserRepository userRepository) {
	this.userRepository = userRepository;
 }

ReservationService.java


 //Change before
 @Autowired
 ReservationRepository reservationRepository;

 @Autowired
 ReservableRoomRepository reservableRoomRepository;

 //After change
 private final ReservationRepository reservationRepository;
 private final ReservableRoomRepository reservableRoomRepository;

 public ReservationService(ReservationRepository reservationRepository, 
			ReservableRoomRepository reservableRoomRepository) {
	this.reservationRepository = reservationRepository;
	this.reservableRoomRepository = reservableRoomRepository;
 }	

Controller class

RoomsController.java


 //Change before
 @Autowired
 RoomService roomService;

 //After change
 private final RoomService roomService;

 public RoomsController(RoomService roomService) {
	this.roomService = roomService;
 }

ReservationsController.java


 //Change before
 @Autowired
 RoomService roomService;

 @Autowired
 ReservationService reservationService;

 //After change
 private final RoomService roomService;
 private final ReservationService reservationService;

 public ReservationsController(RoomService roomService, 
				ReservationService reservationService) {
	this.roomService = roomService;
	this.reservationService = reservationService;
 }

Change request mapping

Changed @RequestMapping to annotation corresponding to each HTTP method "path =" is optional

Controller class

RoomsController.java


 //Change before
 @RequestMapping(method = RequestMethod.GET)
 String listRooms(Model model) {
・ ・ ・
 }

 @RequestMapping(path = "{date}", method = RequestMethod.GET)
 String listRooms(
	@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) 
	@PathVariable("date") LocalDate date, Model model) {
・ ・ ・
 }

 //After change
 @GetMapping
 String listRooms(Model model) {
・ ・ ・
 }

 @GetMapping("{date}")
 String listRooms(
	@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) 
	@PathVariable("date") LocalDate date, Model model) {
・ ・ ・
 }

ReservationsController.java


 //Change before
 @RequestMapping(method = RequestMethod.GET)
 String reserveForm(
	@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
	@PathVariable("date") LocalDate date,
	@PathVariable("roomId") Integer roomId, Model model) {
・ ・ ・
 }

 @RequestMapping(method = RequestMethod.POST)
 String reserve(@Validated ReservationForm form, BindingResult bindingResult,
	@AuthenticationPrincipal ReservationUserDetails userDetails,
	@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
	@PathVariable("date") LocalDate date,
	@PathVariable("roomId") Integer roomId, Model model) {
・ ・ ・
 }

 @RequestMapping(method = RequestMethod.POST, params = "cancel")
 String cancel(
	@RequestParam("reservationId") Integer reservationId,
	@PathVariable("roomId") Integer roomId,
	@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
	@PathVariable("date") LocalDate date, Model model) {
・ ・ ・
 }

 //After change
 @GetMapping
 String reserveForm(
	@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
	@PathVariable("date") LocalDate date,
	@PathVariable("roomId") Integer roomId, Model model) {
・ ・ ・
 }

 @PostMapping
 String reserve(@Validated ReservationForm form, BindingResult bindingResult,
	@AuthenticationPrincipal ReservationUserDetails userDetails,
	@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
	@PathVariable("date") LocalDate date,
	@PathVariable("roomId") Integer roomId, Model model) {
・ ・ ・
 }

 @PostMapping(params = "cancel")
 String cancel(
	@RequestParam("reservationId") Integer reservationId,
	@PathVariable("roomId") Integer roomId,
	@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
	@PathVariable("date") LocalDate date, Model model) {
・ ・ ・
 }

Change from Thymeleaf2 to Thymeleaf3

Changed to HTML format according to Thymeleaf3 (Thymeleaf2 is in XHTML format) No error occurs even if there is no closing tag "/".

loginForm.html


 //Change before
<!DOCTYPE html>
<html xmlns:th = "http://www.thymelaef.org">
<head>
<meta charset = "UTF-8" />
<title></title>
</head>

・ ・ ・

<td>
    <input type = "text" id = "username" name = "username" value = "aaaa" />
</td>

・ ・ ・

<td>
<input type = "password" id = "password" name = "password" value = "demo" />
</td>

・ ・ ・



 //After change
<!DOCTYPE html>
<html xmlns:th = "http://www.thymelaef.org">
<head>
<meta charset = "UTF-8">
<title></title>
</head>

・ ・ ・

<td>
    <input type = "text" id = "username" name = "username" value = "aaaa">
</td>

・ ・ ・

<td>
<input type = "password" id = "password" name = "password" value = "demo">
</td>

・ ・ ・


reserveForm.html


 //Change before
<!DOCTYPE html>
<html xmlns:th = "http://www.thymeleaf.org"
       xmlns:sec = "http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset = "UTF-8" />

・ ・ ・

	<tr th:each = "reservation : ${reservations}">
		<td>
			<span th:text = "${reservation.startTime}" />
			-
			<span th:text = "${reservation.endTime}" />
		</td>
		<td>
			<span th:text = "${reservation.user.lastName}" />
			<span th:text = "${reservation.user.firstName}" />
		</td>
		<td>
			<form th:action = "@{'/reservations/' + ${date} + '/' + ${roomId}}" method = "post"
					sec:authorize = "${hasRole('ADMIN') or #vars.user.userId == #vars.reservation.user.userId}">
				<input type = "hidden" name = "reservationId" th:value = "${reservation.reservationId}" />
				<input type = "submit" name = "cancel" value = "cancel" />
			</form>
		</td>
	</tr>

・ ・ ・

 //After change
<!DOCTYPE html>
<html xmlns:th = "http://www.thymeleaf.org"
       xmlns:sec = "http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset = "UTF-8">

・ ・ ・

	<tr th:each = "reservation : ${reservations}">
		<td>
			<span th:text = "${reservation.startTime}">
			-
			<span th:text = "${reservation.endTime}">
		</td>
		<td>
			<span th:text = "${reservation.user.lastName}">
			<span th:text = "${reservation.user.firstName}">
		</td>
		<td>
			<form th:action = "@{'/reservations/' + ${date} + '/' + ${roomId}}" method = "post"
					sec:authorize = "${hasRole('ADMIN') or #vars.user.userId == #vars.reservation.user.userId}">
				<input type = "hidden" name = "reservationId" th:value = "${reservation.reservationId}">
				<input type = "submit" name = "cancel" value = "cancel">
			</form>
		</td>
	</tr>

・ ・ ・


listRooms.html


 //Change before
<!DOCTYPE html>
<html xmlns:th = "http://www.thymeleaf.org"
       xmlns:sec = "http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset = "UTF-8" />

・ ・ ・

 //After change
<!DOCTYPE html>
<html xmlns:th = "http://www.thymeleaf.org"
       xmlns:sec = "http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset = "UTF-8">

・ ・ ・

Changes for Spring Data JPA 2.2

Unnecessary source

There is no need to create the three Converters on p.650 and 651. (Because Spring Data JPA2.2 supports java.time.Time) ・LocalDateConverter.java ・LocalTimeConverter.java ・LocalDateTimeConverter.java

Modifying the findOne () method of the Repository

Renamed the findOne () method of CrudRepository to the findById () method. The return value has changed from Entity type to Optional type. Therefore, change as follows fineOne() => findById().get()

Service class

ReservatoinService.java


 //Change before

・ ・ ・
 public Reservation findById(Integer reservationId) {
    return reservationRepository.findOne(reservationId);
 }

 //After change

・ ・ ・
 public Reservation findById(Integer reservationId) {
    return reservationRepository.findById(reservationId).get();
 }

RoomService.java


 //Change before

・ ・ ・

 public MeetingRoom findMeetingRoom(Integer roomId) {
	return meetingRoomRepository.findOne(roomId);
 }

 //After change

・ ・ ・

 public MeetingRoom findMeetingRoom(Integer roomId) {
	return meetingRoomRepository.findById(roomId).get();
 }

ReservationUserDetailsService.java


 //Change before

・ ・ ・

 User user = userRepository.findOne(username);

 //After change

・ ・ ・

User user = userRepository.findById(username).get();

Recommended Posts

Spring thorough introduction version upgrade memo
Spring retrospective memo
Spring Fox ① Introduction
JJUG CCC Spring 2018 memo
Spring Shell usage memo
Spring boot memo writing (1)
Rails version upgrade memorandum 5.0 → 5.1
Spring boot memo writing (2)
CentOS 7 curl version upgrade
Build a "Spring Thorough Introduction" development environment with IntelliJ IDEA
Ubuntu Ethernet driver introduction memo
[Personal memo] About Spring framework
JJUG CCC 2018 Spring participation memo
Spring Security usage memo CSRF
Spring Framework self-study memo series_1
Introduction to Ratpack (7) --Guice & Spring
Spring Security Usage memo Method security
Spring Security usage memo Remember-Me
Introduction to Spring Boot ② ~ AOP ~
[Rails] Rails version upgrade error memorandum
Eclipse 4.8 introduction memo (Plugin edition)
Spring Security usage memo CORS
XVim2 introduction memo to Xcode12.3
Spring Security usage memo test
Spring boot controller method memo