"Une introduction approfondie à Spring" a appelé un bon livre pour apprendre le Spring Framework. J'essaye d'apprendre tout en mettant en œuvre le tutoriel, J'en ai pris note car je suis parfois tombé dessus contrairement à mon propre environnement. J'ai essayé de résoudre ce problème pour autant que je puisse comprendre, mais il y a peut-être encore ...?
Livre | Mon environnement | |
---|---|---|
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 * Ceci a été modifié en raison de problèmes d'environnement personnel | PostgreSQL | MySQL |
p.643 Changé pour 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 et schema.sql sont également modifiés pour MySQL.
Injection de champ modifiée en injection de constructeur. L'injection de constructeur est la plus recommandée des trois méthodes DI. La description augmentera, mais le champ peut être finalisé (Immuable).
S'il n'y a qu'un seul constructeur dans la classe, @Autowired peut être omis (il est omis ci-dessous)
RoomService.java
//Changer avant
@Autowired
ReservableRoomRepository reservableRoomRepository;
@Autowired
MeetingRoomRepository meetingRoomRepository;
//Après le changement
private final ReservableRoomRepository reservableRoomRepository;
private final MeetingRoomRepository meetingRoomRepository;
public RoomService(ReservableRoomRepository reservableRoomRepository,
MeetingRoomRepository meetingRoomRepository) {
this.reservableRoomRepository = reservableRoomRepository;
this.meetingRoomRepository = meetingRoomRepository;
}
ReservationUserDetailsService.java
//Changer avant
@Autowired
UserRepository userRepository;
//Après le changement
private final UserRepository userRepository;
public ReservationUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
ReservationService.java
//Changer avant
@Autowired
ReservationRepository reservationRepository;
@Autowired
ReservableRoomRepository reservableRoomRepository;
//Après le changement
private final ReservationRepository reservationRepository;
private final ReservableRoomRepository reservableRoomRepository;
public ReservationService(ReservationRepository reservationRepository,
ReservableRoomRepository reservableRoomRepository) {
this.reservationRepository = reservationRepository;
this.reservableRoomRepository = reservableRoomRepository;
}
RoomsController.java
//Changer avant
@Autowired
RoomService roomService;
//Après le changement
private final RoomService roomService;
public RoomsController(RoomService roomService) {
this.roomService = roomService;
}
ReservationsController.java
//Changer avant
@Autowired
RoomService roomService;
@Autowired
ReservationService reservationService;
//Après le changement
private final RoomService roomService;
private final ReservationService reservationService;
public ReservationsController(RoomService roomService,
ReservationService reservationService) {
this.roomService = roomService;
this.reservationService = reservationService;
}
@RequestMapping a été remplacé par l'annotation correspondant à chaque méthode HTTP "path =" est facultatif
RoomsController.java
//Changer avant
@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) {
・ ・ ・
}
//Après le changement
@GetMapping
String listRooms(Model model) {
・ ・ ・
}
@GetMapping("{date}")
String listRooms(
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
@PathVariable("date") LocalDate date, Model model) {
・ ・ ・
}
ReservationsController.java
//Changer avant
@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) {
・ ・ ・
}
//Après le changement
@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) {
・ ・ ・
}
Changé au format HTML selon Thymeleaf3 (Thymeleaf 2 est au format XHTML) Aucune erreur ne se produit même sans la balise de fermeture "/".
loginForm.html
//Changer avant
<!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>
・ ・ ・
//Après le changement
<!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
//Changer avant
<!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 = "Annuler" />
</form>
</td>
</tr>
・ ・ ・
//Après le changement
<!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 = "Annuler">
</form>
</td>
</tr>
・ ・ ・
listRooms.html
//Changer avant
<!DOCTYPE html>
<html xmlns:th = "http://www.thymeleaf.org"
xmlns:sec = "http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset = "UTF-8" />
・ ・ ・
//Après le changement
<!DOCTYPE html>
<html xmlns:th = "http://www.thymeleaf.org"
xmlns:sec = "http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset = "UTF-8">
・ ・ ・
Il n'est pas nécessaire de créer les trois convertisseurs aux pages 650 et 651. (Parce que Spring Data JPA2.2 prend en charge java.time.Time) ・LocalDateConverter.java ・LocalTimeConverter.java ・LocalDateTimeConverter.java
La méthode findOne () de CrudRepository a été renommée en méthode findById (). La valeur de retour est passée du type d'entité au type facultatif. Par conséquent, changez comme suit fineOne() => findById().get()
ReservatoinService.java
//Changer avant
・ ・ ・
public Reservation findById(Integer reservationId) {
return reservationRepository.findOne(reservationId);
}
//Après le changement
・ ・ ・
public Reservation findById(Integer reservationId) {
return reservationRepository.findById(reservationId).get();
}
RoomService.java
//Changer avant
・ ・ ・
public MeetingRoom findMeetingRoom(Integer roomId) {
return meetingRoomRepository.findOne(roomId);
}
//Après le changement
・ ・ ・
public MeetingRoom findMeetingRoom(Integer roomId) {
return meetingRoomRepository.findById(roomId).get();
}
ReservationUserDetailsService.java
//Changer avant
・ ・ ・
User user = userRepository.findOne(username);
//Après le changement
・ ・ ・
User user = userRepository.findById(username).get();
Recommended Posts