SpringBootを基づいてのLombok+Validationの導入（第二章）

#１　Lombokの導入
***冗長コード(getter、setter)を削減する為に導入した***
***[※その他内容について、ここをクリックしてください](https://projectlombok.org/)***
#####1.1 pom.xmlにLombok用のdependencyの追加

```ruby:pom.xml
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<optional>true</optional>
</dependency>
```

#####1.2 UserModel.javaの修正
***Lombokを使用する為***

```ruby:UserModel.java
package com.example.demo.model;

import lombok.Data;

@Data
public class UserModel {
    private String Id;
    private String Name;
    private String Email;
}
```

| 変更点              |    |
|:-------------------|---:|
| import lombok.Data;|追加|
| @Data              |追加|
| getter             |削除|
| setter             |削除|



#２　Validationの導入
***画面からの入力データのvalidationを簡単にチェックする為に導入した***
#####2.1 pom.xmlにValidation用のdependencyの追加

```ruby:pom.xml
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
	<groupId>javax.validation</groupId>
	<artifactId>validation-api</artifactId>
	<version>2.0.1.Final</version>
</dependency>
```
#####2.2 ユーザフォームクラスの作成

***新規作成ユーザのvalidationチェック用***

```ruby:UserForm.java
package com.example.demo.dto;

import java.io.Serializable;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import lombok.Data;

@Data
public class UserForm implements Serializable {
	@Size(min = 8, max = 20, message = "IDは8桁から20桁まで入力してください。")
	@Pattern(regexp = "^[a-zA-Z0-9]*$", message = "IDは英数字のみで入力してください")
	private String Id;

	@Size(min = 8, max = 50, message = "名前は8桁から50桁まで入力してください。")
	@Pattern(regexp = "^[ァ-タダ-ヶー]*$", message = "名前はのカタカナのみで入力してください")
	private String Name;

	@NotBlank(message = "メールアドレスの入力が必要です。")
	@Email(message = "メールアドレスの形式に入力してください。")
	private String Email;
}


```

#####2.3 コントロールクラスの修正

***注意点：addUser Methodの修正も必要***
***BindingResultを新規作成例も作っている***

```ruby:UserController.java
package com.example.demo.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.demo.dto.UserForm;
import com.example.demo.model.UserModel;
import com.example.demo.service.UserService;

@Controller
public class UserController {
	private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;

    }

    @RequestMapping("/new")
    public String addUser(UserForm userForm) {
        return "NewUser.html";
    }

    @PostMapping("/new")
    public String create(@Validated @ModelAttribute UserForm userForm, BindingResult errorResult, Model model) {
		if (errorResult.hasErrors()) {
			return "NewUser.html";
		}

    	try {
    		userService.insert(userForm);
    		return "redirect:userlist";
    	} catch(UncategorizedSQLException e) {
    		FieldError fieldError = new FieldError(errorResult.getObjectName(), "Id", "ユーザ新規作成に失敗");
    		errorResult.addError(fieldError);
    		return "NewUser.html";
    	}
    }

    @GetMapping("/userlist")
    public String displayUsers(Model model) {
    	List<UserModel> users = userService.selectAll();
    	model.addAttribute("users", users);
        return "UserList.html";
    }
}
```

#####2.4 ユーザ登録画面の修正

```ruby:NewUser.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="UTF-8" />
    <title>新規作成画面</title>
  </head>
  <body>
    <h1>新規登録</h1>
    <div><a th:href="@{/userlist}">一覧はこちら</a></div>
    <form action="#" th:action="@{/new}" th:object="${userForm}" method="post">
      <table>
        <tr>
          <th class="cell_title">ID</th>
          <td><input type="text" th:field="*{Id}"></td>
          <td th:if="${#fields.hasErrors('Id')}" th:errors="*{Id}">Id Error</td>
        </tr>
        <tr>
          <th class="cell_title">名前</th>
          <td><input type="text" th:field="*{Name}"></td>
          <td th:if="${#fields.hasErrors('Name')}" th:errors="*{Name}">Name Error</td>
        </tr>
        <tr>
          <th class="cell_title">メール</th>
          <td><input type="text" th:field="*{Email}"></td>
          <td th:if="${#fields.hasErrors('Email')}" th:errors="*{Email}">Email Error</td>
        </tr>
      </table>
      <button type="submit">新規</button>
      <input type="button" value="終了" onclick="window.open('about:blank', '_self').close()">
    </form>
  </body>
</html>
```

#####2.5 ユーザサービスクラスの修正

***コントローラークラスの修正に伴い***

```ruby:UserService.java
package com.example.demo.service;

import java.util.List;

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

import com.example.demo.dto.UserForm;
import com.example.demo.mapper.UserMapper;
import com.example.demo.model.UserModel;

@Service
public class UserService {

    private final UserMapper dao;

    @Autowired
    public UserService(UserMapper dao) {
        this.dao = dao;
    }

    public boolean insert(UserForm userReq) {
    	UserModel user = new UserModel();
    	user.setId(userReq.getId());
    	user.setName(userReq.getName());
    	user.setEmail(userReq.getEmail());

        return dao.insert(user) > 0;
    }

    public List<UserModel> selectAll() {
        return dao.selectAll();
    }
}
```

#３　デモ
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663377/05558d85-7f6f-5c94-96d7-9a70d0217baa.png)
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663377/690a501e-6402-57d8-bc56-553427b837d7.png)
![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663377/7bd6dbbf-7191-f12e-3897-20368cf34790.png)

#４　終わりに
ここまで、lombokとvalidationについて、書きました。
前章と比較しながら参照すればよいと思います。