[JAVA] Créons une application Web de gestion de livres avec Spring Boot part2

introduction

Salut, je m'appelle @ Ikuto19, un étudiant en programmation. Cette fois, je partirai de Suite de la dernière fois (part1). Après avoir brièvement expliqué la revue précédente, je vais vous expliquer la procédure de création et créer l'application.

Dernier examen et commentaire

À propos de la dernière fois

Dans la première partie, nous avons créé et publié une application de test pour vous aider à comprendre le déroulement et la préparation de la création d'une application de gestion de livres. Plus précisément, j'ai installé des outils pour utiliser Spring Framework et enregistré un compte avec Heroku.

Précautions après cela! !!

J'expliquerai le rôle du code et des annotations de cette partie, mais c'est la première fois que je touche au Spring Framework. Bref, je suis débutant, donc je ne peux pas l'expliquer en détail. C'est juste une explication approximative de mon interprétation, alors ne le prenez pas pour les mêmes débutants qui regardent cet article. Cela correspond à peu près, mais je pense que cela peut être différent, alors vérifiez-le vous-même. Au contraire, si vous êtes une personne avancée, indiquez de plus en plus comme je l'ai dit la dernière fois.

Explication du code précédent

App.java Cette App.java exécute l'application Web. Donc, si vous n'incluez pas cette fonction principale, l'application ne démarre pas. Le nom de la classe peut être n'importe quoi, mais je l'ai nommé App. Si vous souhaitez changer le nom de la classe, changez le contenu "App.class" en "Class name.class".

À propos de @ SpringBootApplication, [Traduction japonaise du document Spring](https://spring.pleiades.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-using- Dans "6. @ SpringBootApplication Annotation" "de springbootapplication-annotation), il a été écrit comme suit.

@EnableAutoConfiguration: Activer le mécanisme de configuration automatique de Spring Boot @ComponentScan: Activez @Component Scan sur le package où se trouve l'application (voir Bonnes pratiques) @Configuration: vous pouvez enregistrer des beans supplémentaires dans le contexte et importer des classes de configuration supplémentaires.

Quand j'ai interprété tout cela ensemble, j'ai pensé que cela ressemblerait à ceci.

App.java


package com.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}

IndexController.java IndexController.java est le contrôleur dans le modèle MVC. Le contrôleur contrôle le modèle et la vue en fonction de l'entrée de l'utilisateur, mais cette fois, j'essaie d'afficher index.html lorsque l'URL est "/". Avec "model.setAttribute (" message ", message)", vous pouvez gérer la chaîne de caractères stockée dans message dans le fichier html appelé.

IndexController.java


package com.app.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class IndexController {
	
	@GetMapping("/")
	public String getIndexPage(Model model) {
		String message = "Hello, World!!";
		model.addAttribute("message",message);
		return "index";
	}
}

index.html

J'ai interprété la partie de "xmlns: th = ~" pour utiliser le moteur de template Thymeleaf. Cela permet de gérer les valeurs et les chaînes de caractères du contrôleur même en HTML. Le contenu (chaîne de caractères) du message stocké dans "th: text =" $ {message} "peut être affiché.

index.html


<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<meta charset="UTF-8">
<head>
<title>Tester l'application</title>
</head>
<body>
	<p th:text="${message}"></p>
</body>
</html>

Procfile

Java: j'ai essayé le déploiement Heroku de l'application Spring Boot J'ai imité le style d'écriture de cette personne tel qu'il est. J'ai cherché \ $ JAVA_OPTS et --server.port = $ PORT, mais je n'ai pas eu beaucoup de résultats. En gros, pour autant que je puisse voir The Procfile de Heroku Dev Center, je pense que je devrais écrire "App type: Execution command". Je vais.

Procfile


web: java $JAVA_OPTS -jar target/*.jar --server.port=$PORT

Procédure de création

  1. Créez un projet
  2. Implémentation de l'écran d'accueil
  3. Implémentation de l'écran de connexion et de la transition d'écran par authentification DB
  4. Mise en œuvre de la transition d'écran de l'écran d'accueil à la page pour la recherche de livres, l'affichage des informations sur les livres et l'affichage de la calligraphie
  5. Implémentation d'une fonction d'enregistrement / suppression de la base de données après recherche de livres
  6. Appliquer CSS
  7. Contrôle de fonctionnement

Création de projet

Créez le projet comme vous l'avez fait la dernière fois. Le nom du projet est "BookManagement-webapp", et à part cela, créez avec les mêmes paramètres que la dernière fois. Cependant, supprimez BookManagementWebappApplication.java.

Implémentation de l'écran d'accueil

Créer un nouveau fichier

App.java Créez et placez le fichier App.java suivant dans le package com.app. Comme expliqué précédemment, l'exécution de cette classe lance l'application Spring.

App.java


package com.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}

index.html Créez index.html, qui sera l'écran d'accueil, dans le dossier des modèles. L'écran d'accueil a les fonctions suivantes.

indexhtml


<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<meta charset="UTF-8">
<head>
<title>Application de gestion de livres</title>
</head>
<body>
	<div class="main_container">
		<div class=title>
			<h1>Application Web de gestion de livres</h1>
		</div>
		<div class="middle_container">
			<div class="contains collate">
				<form method="get" action="operateCollate">
					<input type="text" class="texts" name="isbn" value=""
						placeholder="Code ISBN"> <input class="submit"
						type="submit" value="Correspondance de livre">
				</form>
			</div>
			<div class="contains flexbox">
				<form method="get" action="operateCheck">
					<input class="submit" type="submit" value="Affichage des informations sur le livre">
				</form>
				<form method="get" action="operateCover">
					<input class="submit" type="submit" value="Affichage de la couverture du livre">
				</form>
			</div>
		</div>
	</div>
</body>
</html>

Confirmation d'exécution

Vous devriez voir quelque chose comme ce qui suit. スクリーンショット 2020-07-29 16.49.38.png

Implémentation de la connexion à l'aide de l'authentification DB de Spring Security

Ensuite, nous implémenterons la connexion par authentification DB de Spring Security. Les fichiers à modifier (bleu) et les fichiers à ajouter (rouge) sont les suivants. Cette authentification de connexion est Implémentation de la fonction d'authentification dans Spring Security ① ~ Implémentation de la fonction d'authentification dans Spring Security ③ / 3047949cb6018d2453dc) sera référencé, et il sera modifié et créé si nécessaire. Je pense donc que le code est presque le même. De plus, les commentaires de chaque fichier appartiennent à la personne qui a écrit cet article, je les ai donc supprimés. Alors lisez cet article si vous voulez voir les commentaires. スクリーンショット 2020-07-29 23.24.43.png

Créer un nouveau fichier / modifier le fichier existant

WebSecurityConfig.java Les paramètres de sécurité sont définis dans cette classe. configure: la méthode de configuration de WebSecurity exclut les fichiers et dossiers requis de l'authentification. Dans la méthode configure de configure-HttpSecurity, les transitions d'écran et les utilisateurs accessibles sont définis lorsque l'authentification réussit ou échoue. La dernière méthode de configuration de configure-AuthenticationManagerBuilder est utilisée pour configurer l'authentification.

WebSecurityConfig.java


package com.app.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

import com.app.service.UserDetailsServiceImpl;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private UserDetailsServiceImpl userDetailsService;

	//Cryptage du mot de passe
	@Bean
	public BCryptPasswordEncoder passwordEncoder() {
		BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
		return bCryptPasswordEncoder;
	}

	//Il est possible de gérer des fichiers CSS, Javascript, etc. et des images externes.
	@Override
	public void configure(WebSecurity web) throws Exception {
		web.ignoring().antMatchers(
				"/images/**",
				"/css/**",
				"/js/**"
				);
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception{
			http
				.authorizeRequests()
				.anyRequest().authenticated()
				.and()
			.formLogin()
				.loginPage("/login") //URL de la page de connexion
				.loginProcessingUrl("/login")
				.usernameParameter("username")
				.passwordParameter("password")
				.defaultSuccessUrl("/index", true) //URL transférée par authentification réussie
				.failureUrl("/login?error") //URL qui transite en raison d'un échec d'authentification
				.permitAll() //Tous les utilisateurs peuvent se connecter
				.and()
			.logout()
				.logoutUrl("/logout") //URL de la page de déconnexion
				.logoutSuccessUrl("/login?logout") //URL après une déconnexion réussie
				.permitAll();
	}
	
	@Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
}

LoginController.java Lorsque l'URL est "/ login", login.html s'affiche.

LoginController.java


package com.app.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class LoginController {
	@GetMapping("/login")
	public String getSignUp(Model model) {
		return "login";
	}
}

LoginUser.java

LoginUser.java


package com.app.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "user")
public class LoginUser {

    @Column(name = "user_id")
    @Id
    private Long userId;

    @Column(name = "user_name")
    private String userName;

    @Column(name = "password")
    private String password;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

	public Long getUserId() {
		return userId;
	}

	public void setUserId(Long userId) {
		this.userId = userId;
	}
}

LoginUserDao.java Accédez à la base de données avec la méthode findUser et renvoyez l'objet utilisateur avec le nom d'utilisateur approprié.

LoginUserDao.java


package com.app.repository;

import javax.persistence.EntityManager;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.app.entity.LoginUser;

@Repository
public class LoginUserDao {

    @Autowired
    EntityManager em;

    public LoginUser findUser(String userName) {

        String query = "";
        query += "SELECT * ";
        query += "FROM user ";
        query += "WHERE user_name = :userName ";

        return (LoginUser)em.createNativeQuery(query, LoginUser.class).setParameter("userName", userName).getSingleResult();
    }
}

UserRepository.java

UserRepository.java


package com.app.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.app.entity.LoginUser;

/*
 *<Classe d'entité,Type d'identification>
 */
@Repository
public interface UserRepository extends JpaRepository<LoginUser, Integer>{}

UserDetailsServiceImpl.java

UserDetailsServiceImpl.java


package com.app.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.app.repository.LoginUserDao;
import com.app.entity.LoginUser;

@Service
public class UserDetailsServiceImpl implements UserDetailsService{

    @Autowired
    private LoginUserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {

        LoginUser user = userDao.findUser(userName);
        if (user == null) throw new UsernameNotFoundException(userName + "N'existe pas dans la base de données.");

        List<GrantedAuthority> grantList = new ArrayList<GrantedAuthority>();
        GrantedAuthority authority = new SimpleGrantedAuthority("USER");
        grantList.add(authority);
        
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        UserDetails userDetails = (UserDetails)new User(user.getUserName(), encoder.encode(user.getPassword()),grantList);

        return userDetails;
    }
}

index.html Placez ce qui suit en bas de la balise div "class =" contains flexbox "".

index.html


<form  method="post" id="logout" th:action="@{/logout}">
		<button type="submit">Se déconnecter</button>
</form>

login.html

login.html


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<meta charset="UTF-8">
<title>LoginPage</title>
</head>
<body>
	<div class="main_container">
		<p th:if="${param.error}" class="message">* Le nom d'utilisateur ou le mot de passe est différent</p>
		<p th:if="${param.logout}" class="message">* Déconnecté</p>
		<div class="login_container">
			<form th:action="@{/login}" method="post">
				<div class="buttons username">
					<i class="fas fa-users"></i> <input class="texts" type="text" name="username"
						placeholder="username" />
				</div>
				<div class="buttons pass">
					<i class="fas fa-lock"></i> <input class="texts" type="password" name="password"
						placeholder="password" />
				</div>
				<div class="submitButton">
					<input class="submit" type="submit" value="S'identifier" />
				</div>
			</form>
		</div>
	</div>
</body>
</html>

application.properties

application.properties


spring.datasource.url=jdbc:mysql://localhost:3306/manageBook
spring.datasource.username=(nom d'utilisateur mysql)
spring.datasource.password=(mot de passe mysql)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.database=MYSQL
spring.jpa.hibernate.ddl-auto=update

pom.xml Ce qui suit est décrit en plus.

pom.xml


<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>

Construire une base de données

Exécutez la commande suivante sur MySQL installé.

terminal


$ mysql -u (nom d'utilisateur mysql) -p
Enter password: (mot de passe mysql)
mysql> create database manageBook;
mysql> use manageBook
mysql> create table user(user_id int auto_increment,user_name varchar(256),password varchar(256),PRIMARY KEY(user_id));
mysql> insert user value(1,"(Nom préféré)","(Mot de passe favori)");
mysql> select * from user;

Si vous vérifiez le contenu du tableau avec le dernier "select * from user;", vous verrez ce qui suit. Si vous pouvez le confirmer, déconnectez-vous avec la commande quit.

terminal


mysql> select * from user;
+---------+-----------+---------------+
| user_id | user_name | password      |
+---------+-----------+---------------+
|       1 |(Nom préféré) | (Mot de passe favori)|
+---------+-----------+---------------+
1 row in set (0.04 sec)

mysql> quit;
Bye

Confirmation d'exécution

Après avoir exécuté l'application Spring, accédez à http: // localhost: 8080 / login pour vérifier. Vous êtes probablement en mesure de vous connecter.

À la fin

C'est tout pour cette fois. La prochaine fois, à la fin, nous mettrons en œuvre la transition depuis l'écran d'accueil et les fonctions liées à l'accès à la base de données. Continuer à la prochaine fois (part3)> Publier bientôt

Site de référence

Une erreur rudimentaire qui n'a pas pu être scannée avec Spring Boot | Engineer 2 Nensei no Kiroku

Fonction d'authentification implémentée avec Spring Security ① --Qiita

Notes sur l'utilisation de Spring Boot-Qiita

Annotations Spring Boot

Comment définir un bean à l'aide de la classe Configuration dans Spring Boot --Reasonable Code

Spring Security Usage Memo Basic / Mechanism --Qiita

Définir la sécurité Web avec Spring Boot (1/2): CodeZine

Annotation JPA (Java Persistence API)

Recommended Posts

Créons une application Web de gestion de livres avec Spring Boot part1
Créons une application Web de gestion de livres avec Spring Boot part2
Faisons une API simple avec EC2 + RDS + Spring boot ①
Démarrez le développement d'applications Web avec Spring Boot
Exécutez l'application WEB avec Spring Boot + Thymeleaf
Créer un serveur API Web avec Spring Boot
Un débutant Java a essayé de créer une application Web simple à l'aide de Spring Boot
Faisons un Bot LINE avec Ruby + Sinatra - Partie 2
[Spring Boot] Création d'applications Web
Faisons un Bot LINE avec Ruby + Sinatra - Partie 1
J'ai essayé de cloner une application Web pleine de bugs avec Spring Boot
Construisez un système WEB avec Spring + Doma + H2DB Partie 2
Faisons un disjoncteur pour le service backend à l'aide de l'actionneur de Spring Boot (partie 1)
La première application WEB avec Spring Boot-Making a Pomodoro timer-
Jusqu'à ce que vous créiez une application Web avec Servlet / JSP (Partie 1)
Créer une application d'enquête avec Spring Boot
Créer une application Web avec Javalin
Implémentez un serveur API Web REST simple avec Spring Boot + MySQL
[Débutant] Essayez d'écrire l'API REST pour l'application Todo avec Spring Boot
Traitement lors du démarrage d'une application avec Spring Boot
Faisons une carte de Noël avec Processing!
Créez une application Web simple avec Dropwizard
HTTPS avec Spring Boot et Let's Encrypt
Lancez l'application Nginx + Spring Boot avec docker-compose
Développement d'applications Web Spring Boot2 avec connexion Visual Studio Code SQL Server
Création d'un environnement de développement pour les applications Web Java avec Docker pour Mac Part1
Développement d'applications Web Spring Boot2 avec création de Visual Studio Code Hello World
Déployer automatiquement des applications Web développées en Java à l'aide de Jenkins [Spring Boot App Edition]
Créer un environnement de développement d'applications Web Java avec Docker pour Mac Part2
Créez un site Web avec Spring Boot + Gradle (jdk1.8.x)
Créez une application de recherche simple avec Spring Boot
Créez une application Spring Boot à l'aide d'IntelliJ IDEA
Faisons une fonction de recherche avec Rails (ransack)
Déployer l'application Spring Boot sur Elastic Beanstalk
Construisez un système WEB avec Spring + Doma + H2DB
Créer un environnement de développement Spring Boot avec docker
J'ai créé une application d'apprentissage automatique avec Dash (+ Docker) part3 ~ Practice ~
Faisons une application de calculatrice avec Java ~ Créez une zone d'affichage dans la fenêtre
Connectez-vous aux applications Web Spring Boot sur la plate-forme Microsoft ID
De la création d'un projet Spring Boot à l'exécution d'une application avec VS Code
Faisons une application TODO avec Java 2 Je veux créer un modèle avec Spring Initializr et créer Hello world
Construisez un système WEB avec Spring + Doma + H2DB + Thymeleaf
Essayez d'utiliser OpenID Connect avec Keycloak (application Spring Boot)
[Compatible JUnit 5] Ecrire un test en utilisant JUnit 5 avec Spring boot 2.2, 2.3
[Bases de Java] Créons un triangle avec une instruction for
Implémentez une API Rest simple avec Spring Security avec Spring Boot 2.0
[Mémo de travail de l'application personnelle] Créez un calendrier avec simple_calendar
Personnalisez la réponse aux erreurs de l'API REST avec Spring Boot (Partie 2)
[JUnit 5] Ecrivez un test de validation avec Spring Boot! [Test de paramétrage]
Un mémorandum lors de la création d'un service REST avec Spring Boot
Créez un site de démonstration simple avec Spring Security avec Spring Boot 2.1
Disponibilité de l'application Spring Boot 2.3
Personnalisez la réponse aux erreurs de l'API REST avec Spring Boot (Partie 1)
J'ai écrit un test avec Spring Boot + JUnit 5 maintenant
[Introduction au développement d'applications Android] Faisons un compteur
Télécharger avec Spring Boot
Faisons une application de calcul avec Java ~ Afficher la fenêtre de l'application
Implémenter l'API REST avec Spring Boot et JPA (Application Layer)
Une histoire remplie des bases de Spring Boot (résolu)