[JAVA] Créer une application d'enquête avec Spring Boot

Cette fois aussi, j'ai créé une application avec Spring Boot pour étudier. Nous prévoyons d'ajouter des fonctions à tout moment.

06/06/2020: Ajout de la fonction de suppression

environnement d'utilisation

・ Windows10 (64 bits) ・ Démarrage à ressort: 2.2.6 ・ Éclipse: 4.9.0 ・ H2 · Amorcer

Dessin d'achèvement

C'est une simple application d'enquête.

image.png

Entity

Inquiry.java


import java.time.LocalDateTime;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import org.springframework.format.annotation.DateTimeFormat;

@Entity
public class Inquiry {

	@Id
	@GeneratedValue
	private int id;

	private String name;
	private String email;
	private String contents;

	@DateTimeFormat(pattern="yyyy-MM-dd")
	private LocalDateTime created;

	public Inquiry() {
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getContents() {
		return contents;
	}

	public void setContents(String contents) {
		this.contents = contents;
	}

	public LocalDateTime getCreated() {
		return created;
	}

	public void setCreated(LocalDateTime created) {
		this.created = created;
	}
}

Repository

InquiryDao.java


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

@Repository
public interface InquiryDao extends JpaRepository<Inquiry, Integer> {

}

Service

InquiryService.java


import java.util.List;

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

@Service
public class InquiryService {

	@Autowired
	InquiryDao inquiryDao;

	//Enregistrer le processus
	public Inquiry save(Inquiry inquiry) {

		return inquiryDao.saveAndFlush(inquiry);
	}

	//Processus de recherche
	public List<Inquiry> find() {

		return inquiryDao.findAll();
	}

	//Supprimer le processus
	public void delete(int id) {

		inquiryDao.deleteById(id);
	}
}

Form Préparez une classe Form pour contenir la valeur entrée. Le contrôle de validation est également défini ici.

InquiryForm.java


import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;

public class InquiryForm {

	@Size(min=1, max=20, message="Erreur de vérification d'entrée de nom")
	private String name;

	@NotEmpty(message="Non entré")
	private String email;

	@NotEmpty(message="Non entré")
	private String contents;

	public  InquiryForm() {}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getContents() {
		return contents;
	}
	public void setContents(String contents) {
		this.contents = contents;
	}
}

Controller

InquiryController.java


import java.time.LocalDateTime;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@Controller
@RequestMapping("/inquiry")
public class InquiryController {

	@Autowired
	InquiryService inquiryService;

	//Traitement d'écran de liste
	@GetMapping()
	public String index(Model model) {

		//Tous les traitements de recherche
		List<Inquiry> list = inquiryService.find();
		model.addAttribute("list", list);
		model.addAttribute("title", "Écran de liste");
		return "index_boot";
	}

	//Traitement des entrées d'enquête
	@GetMapping("form")
	public String form(@ModelAttribute("inquiryForm") InquiryForm inquiryForm, Model model, @ModelAttribute("complete") String complete) {

		model.addAttribute("title", "Formulaire de demande");
		return "form_boot";
	}

	//Traitement qui a volé en appuyant sur le bouton "Retour" de la page de confirmation
	@PostMapping("form")
	public String formGoBack(@ModelAttribute("inquiryForm") InquiryForm inquiryForm, Model model) {

		model.addAttribute("title", "Formulaire de demande");
		return "form_boot";
	}

	/*Traitement lorsque vous entrez le contenu de l'entrée et appuyez sur la "page de confirmation"
	 * @Effectuer le contrôle d'entrée de la classe de formulaire avec Validé,
	 *Stocker le résultat du contrôle dans BindingResult
	*/
	@PostMapping("confirm")
	public String confirm(@ModelAttribute("inquiryForm") @Validated InquiryForm inquiryForm, BindingResult res, Model model) {

		//Si le résultat de BindingResult est une erreur, un message d'erreur est émis.
		if(res.hasErrors()) {
			model.addAttribute("title", "Formulaire de demande");
			return "form_boot";
		}
		model.addAttribute("title", "Page de confirmation");
		return "confirm_boot";
	}

	//Traitement lorsque le bouton "Enregistrer" est enfoncé
	@PostMapping("complete")
	public String complete(@ModelAttribute("inquiryForm") @Validated InquiryForm inquiryForm, BindingResult res, Model model, RedirectAttributes redirectAttributes) {

		if(res.hasErrors()) {
			return "form_boot";
		}

		//Remballage d'une demande à partir du conteneur du formulaire
		Inquiry inquiry = new Inquiry();
		inquiry.setName(inquiryForm.getName());
		inquiry.setEmail(inquiryForm.getEmail());
		inquiry.setContents(inquiryForm.getContents());
		inquiry.setCreated(LocalDateTime.now());

		//Enregistrer le processus
		inquiryService.save(inquiry);

		redirectAttributes.addFlashAttribute("complete", "Enregistrer terminé");
		return "redirect:/inquiry/form";
	}

	//Supprimer le processus
	@GetMapping("delete")
	public String delete(Model model) {

		List<Inquiry> deleteList = inquiryService.find();
		model.addAttribute("title", "Supprimer la page");
		model.addAttribute("list", deleteList);
		return "delete_boot";
	}

	//ID d'URL@Recevoir avec PathVariable et utiliser comme argument
	@GetMapping("dell/{id}")
	public String deletes(@PathVariable("id") int id, Model model) {

		inquiryService.delete(id);
		return "redirect:/inquiry";
	}

}

index_boot.html

index_boot.html


<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
    <meta name="generator" content="Jekyll v4.0.1">
    <title th:text="${title}">Starter Template · Bootstrap</title>

    <link rel="canonical" href="https://getbootstrap.com/docs/4.5/examples/starter-template/">

    <!-- Bootstrap core CSS -->
<link href="/docs/4.5/dist/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">

    <!-- Favicons -->
<link rel="apple-touch-icon" href="/docs/4.5/assets/img/favicons/apple-touch-icon.png " sizes="180x180">
<link rel="icon" href="/docs/4.5/assets/img/favicons/favicon-32x32.png " sizes="32x32" type="image/png">
<link rel="icon" href="/docs/4.5/assets/img/favicons/favicon-16x16.png " sizes="16x16" type="image/png">
<link rel="manifest" href="/docs/4.5/assets/img/favicons/manifest.json">
<link rel="mask-icon" href="/docs/4.5/assets/img/favicons/safari-pinned-tab.svg" color="#563d7c">
<link rel="icon" href="/docs/4.5/assets/img/favicons/favicon.ico">
<meta name="msapplication-config" content="/docs/4.5/assets/img/favicons/browserconfig.xml">
<meta name="theme-color" content="#563d7c">


    <style>
      .bd-placeholder-img {
        font-size: 1.125rem;
        text-anchor: middle;
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
      }

      @media (min-width: 768px) {
        .bd-placeholder-img-lg {
          font-size: 3.5rem;
        }
      }
    </style>
    <!-- Custom styles for this template -->
    <link href="starter-template.css" rel="stylesheet" th:href="@{/css/starter-template.css}">
  </head>
  <body>
    <div th:replace="~{header::headerA}"></div>

<main role="main" class="container">

  <div class="starter-template">
    <h1 th:text="${title}"></h1>
    <p class="lead">L'écran de la liste des demandes s'affiche.</p>
  </div>
<!--Liste des éléments du tableau-->
<table class="table table-striped">
  <thead>
    <tr>
      <th scope="col">id</th>
      <th scope="col">Nom complet</th>
      <th scope="col">Email</th>
      <th scope="col">Contenu</th>
      <th scope="col">Date</th>
    </tr>
  </thead>
  <tbody>
  <!--th:Sortez la valeur à plusieurs reprises avec chaque-->
    <tr th:each="list:${list}">
      <th scope="row" th:text="${list.id}">1</th>
	  <td th:text="${list.name}">
	  <td th:text="${list.email}">
	  <td th:text="${list.contents}">
      <td th:text="${list.created}">
    </tr>
  </tbody>
</table>
</main><!-- /.container -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
      <script>window.jQuery || document.write('<script src="/docs/4.5/assets/js/vendor/jquery.slim.min.js"><\/script>')</script><script src="/docs/4.5/dist/js/bootstrap.bundle.min.js" th:src="@{/js/bootstrap.bundle.min.js}" integrity="sha384-1CmrxMRARb6aLqgBO7yyAxTOQE2AKb9GfXnEo760AUcUmFx3ibVJJAzGytlQcNXd" crossorigin="anonymous"></script></body>
</html>

form_boot.html

form_boot.html


<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../../../favicon.ico">

    <title>Starter Template for Bootstrap</title>

    <!-- Bootstrap core CSS -->
    <link href="/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet">

    <!-- Custom styles for this template -->
    <link href="starter-template.css"  th:href="@{/css/starter-template.css}" rel="stylesheet">
  </head>

  <body>


	<div th:replace="~{header::headerA}"></div>
    <main role="main" class="container">

      <div class="starter-template">
        <h1 th:text="${title}">Bootstrap starter template</h1>
        <p class="lead">Vous pouvez saisir votre demande ici</p>
      </div>


	<div th:unless="${#strings.isEmpty(complete)}" >
		<div th:text="${complete}" class="alert alert-success" role="alert">
		  A simple success alert?check it out!
		</div>
	</div>
	<!--Pour conserver la valeur saisie sur cet écran de saisie lorsque le bouton "Retour" est appuyé
			th:Utiliser la valeur-->
	<!--th:Si le résultat de if est vrai, e:des erreurs s'appliquent(Le jeu de validation pour chaque élément est sorti)  -->
	<form method="post" action="#" th:action="@{/inquiry/confirm}" th:object="${inquiryForm}">
	  <div class="form-group">
	    <label for="name">Name</label>
	    <input type="text" name="name" class="form-control" id="name" th:value="*{name}">
	  </div>
	  <div class="text-danger mb-4" th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></div>
	  <div class="form-group">
	    <label for="email">Email</label>
	    <input type="text" name="email" class="form-control" id="email"  th:value="*{email}">
	  </div>
	  <div class="text-danger mb-4" th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></div>
	  <div class="form-group">
	    <label for="contents">Inquiry</label>
	    <textarea  name="contents" class="form-control" id="detail" rows="3" th:field="*{contents}"></textarea>
	  </div>
	  <div class="text-danger mb-4" th:if="${#fields.hasErrors('contents')}" th:errors="*{contents}"></div>
	  <button type="submit" class="btn btn-primary">Vérification</button>
	</form>
    </main><!-- /.container -->

    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script>window.jQuery || document.write('<script src="@{/js/jquery-slim.min.js}"><\/script>')</script>
    <script src="../../assets/js/vendor/popper.min.js"  th:src="@{/js/popper.min.js}"></script>
    <script src="../../dist/js/bootstrap.min.js"  th:src="@{/js/bootstrap.min.js}"></script>
  </body>

confirm_boot.html

confirm_boot.html


<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../../../favicon.ico">

    <title>Starter Template for Bootstrap</title>

    <!-- Bootstrap core CSS -->
    <link href="/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet">

    <!-- Custom styles for this template -->
    <link href="starter-template.css"  th:href="@{/css/starter-template.css}" rel="stylesheet">
  </head>

  <body>

	<div th:replace="~{header::headerA}"></div>
    <main role="main" class="container">

      <div class="starter-template">
        <h1 th:text="${title}">Bootstrap starter template</h1>
        <p class="lead">Vous pouvez vérifier le contenu d'entrée sur cet écran.</p>
      </div>

<!--Extraire chaque valeur emballée dans l'enquête-->
<div th:object="${inquiryForm}">
<div class="mb-5">
<ul class="list-group">
  <li th:text="*{name}" class="list-group-item"></li>
  <li th:text="*{email}" class="list-group-item"></li>
  <li th:text="*{contents}"class="list-group-item"></li>
</ul>
</div>
<!--Avec masqué, vous pouvez envoyer une valeur en appuyant sur un bouton-->
<form method="post" th:action="@{/inquiry/form}">
	<input type="hidden" name="name" th:value="*{name}">
	<input type="hidden" name="email" th:value="*{email}">
	<input type="hidden" name="contents" th:value="*{contents}">
	<button type="submit" class="btn btn-primary">Revenir</button>
</form>
<form method="post" th:action="@{/inquiry/complete}" th:object="${inquiryForm}">
	<input type="hidden" name="name" th:value="*{name}">
	<input type="hidden" name="email" th:value="*{email}">
	<input type="hidden" name="contents" th:value="*{contents}">
	<button type="submit" class="btn btn-primary">Publier</button>
</form>
</div>

    </main><!-- /.container -->

    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script>window.jQuery || document.write('<script src="@{/js/jquery-slim.min.js}"><\/script>')</script>
    <script src="../../assets/js/vendor/popper.min.js"  th:src="@{/js/popper.min.js}"></script>
    <script src="../../dist/js/bootstrap.min.js"  th:src="@{/js/bootstrap.min.js}"></script>
  </body>
</html>

delete_boot.html

html.delete_boot.html



<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../../../favicon.ico">

    <title>Starter Template for Bootstrap</title>

    <!-- Bootstrap core CSS -->
    <link href="/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet">

    <!-- Custom styles for this template -->
    <link href="starter-template.css"  th:href="@{/css/starter-template.css}" rel="stylesheet">
  </head>

  <body>


	<div th:replace="~{header::headerA}"></div>
    <main role="main" class="container">

      <div class="starter-template">
        <h1 th:text="${title}">Bootstrap starter template</h1>
        <p class="lead">Veuillez sélectionner l'élément que vous souhaitez supprimer</p>
      </div>


	<div th:unless="${#strings.isEmpty(complete)}" >
		<div th:text="${complete}" class="alert alert-success" role="alert">
		  A simple success alert?check it out!
		</div>
	</div>
	<table class="table table-striped">
	  <thead>
	    <tr>
	      <th scope="col">id</th>
	      <th scope="col">Nom complet</th>
	      <th scope="col">Email</th>
	      <th scope="col">Contenu</th>
	      <th scope="col">Date</th>
	      <th scope="col">Effacer</th>
	    </tr>
	  </thead>
	  <tbody>
	  <!--th:Sortez la valeur à plusieurs reprises avec chaque-->
	    <tr th:each="list:${list}">
	      <th scope="row" th:text="${list.id}"></th>
		  <td th:text="${list.name}">
		  <td th:text="${list.email}">
		  <td th:text="${list.contents}">
	      <td th:text="${list.created}">
	      <td><a th:href="@{/inquiry/dell/{id}(id=${list.id})}">Effacer</a>
	    </tr>
	  </tbody>
	</table>
    </main><!-- /.container -->

    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script>window.jQuery || document.write('<script src="@{/js/jquery-slim.min.js}"><\/script>')</script>
    <script src="../../assets/js/vendor/popper.min.js"  th:src="@{/js/popper.min.js}"></script>
    <script src="../../dist/js/bootstrap.min.js"  th:src="@{/js/bootstrap.min.js}"></script>
  </body>

Modèle de traitement

Cliquez sur "Formulaire de demande" dans l'en-tête pour passer à l'écran du formulaire. Saisissez votre nom, votre adresse e-mail et votre contenu, puis cliquez sur le bouton «Confirmer». L'écran passera à l'écran de confirmation, mais cliquez sur le bouton «Retour» pour revenir à l'écran précédent. Modifiez le contenu, etc., puis cliquez à nouveau sur le bouton "Confirmer". Cliquez sur le bouton «Publier» sur l'écran de confirmation pour enregistrer le contenu.

image.png

image.png

image.png

image.png

image.png

Supprimer le motif

Cliquez sur le bouton "Supprimer" de Natsuta. Ensuite, vous pouvez voir qu'il a été supprimé. image.png

image.png

référence

Introduction au printemps

Recommended Posts

Créer une application d'enquête avec Spring Boot
[Spring Boot] Création d'applications Web
Traitement lors du démarrage d'une application avec Spring Boot
Démarrez le développement d'applications Web avec Spring Boot
Lancez l'application Nginx + Spring Boot avec docker-compose
Exécutez l'application WEB avec Spring Boot + Thymeleaf
Disponibilité de l'application Spring Boot 2.3
Télécharger avec Spring Boot
Configurer l'application Spring Boot avec le module multiple maven
Développement d'applications Web Spring Boot2 avec création de Visual Studio Code Hello World
Générer un code à barres avec Spring Boot
Hello World avec Spring Boot
Implémenter GraphQL avec Spring Boot
Démarrez avec Spring Boot
Exécutez LIFF avec Spring Boot
Connexion SNS avec Spring Boot
Téléchargement de fichiers avec Spring Boot
Spring Boot commençant par copie
Application Java CICS-Run - (4) Application Spring Boot
Spring Boot à partir de Docker
Hello World avec Spring Boot
Définir des cookies avec Spring Boot
Utiliser Spring JDBC avec Spring Boot
Ajouter un module avec Spring Boot
Premiers pas avec Spring Boot
Créer un micro service avec Spring Boot
Envoyer du courrier avec Spring Boot
Essayez d'utiliser OpenID Connect avec Keycloak (application Spring Boot)
Développement d'applications Spring Boot dans Eclipse
Points de révision du code de l'application Spring Boot
Créez une application avec Spring Boot 2
Liaison de base de données avec doma2 (Spring boot)
Implémenter l'API REST avec Spring Boot et JPA (Application Layer)
Programmation Spring Boot avec VS Code
Jusqu'à "Hello World" avec Spring Boot
Obtenez des résultats de validation avec Spring Boot
(Intellij) Hello World avec Spring Boot
Créez une application avec Spring Boot
Google Cloud Platform avec Spring Boot 2.0.0
Implémenter l'application Spring Boot dans Gradle
J'ai essayé GraphQL avec Spring Boot
[Java] Intégration LINE avec Spring Boot
Application Spring Boot qui spécifie les paramètres de connexion à la base de données avec des paramètres
À partir de Spring Boot 0. Utilisez Spring CLI
J'ai essayé Flyway avec Spring Boot
La coopération des messages a commencé avec Spring Boot
Créons une application Web de gestion de livres avec Spring Boot part3
Créons une application Web de gestion de livres avec Spring Boot part2
[Débutant] Essayez d'écrire l'API REST pour l'application Todo avec Spring Boot
Hello World avec Eclipse + Spring Boot + Maven
Envoyez des notifications régulières avec LineNotify + Spring Boot
Effectuer un test de confirmation de transaction avec Spring Boot
HTTPS avec Spring Boot et Let's Encrypt
Essayez d'utiliser Spring Boot avec VS Code
J'ai essayé l'initialisation paresseuse avec Spring Boot 2.2.0
Implémenter CRUD avec Spring Boot + Thymeleaf + MySQL
Traitement asynchrone avec Spring Boot en utilisant @Async
Application CI / CD Spring avec CircleCI (Heroku)