# RESTful&AJAX 3/10 上課內容 (Maven)
###### tags: `RESTful&AJAX`
# 80 REST 讀取所有會員資料

# 81 REST 新增會員資料

***
##
#### 改專案


# 52 訊息轉換

#### 動態專案 早期沒有Maven

#### Maven專案




* Versoin:1.0版本
* Packaging:現在是war檔 (spring boot 是jar檔)
[Apache Tomcat](http://tomcat.apache.org/whichversion.html)
#### pom.xml
```clike=
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.ntu.eeit126</groupId>
<artifactId>springRest</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<properties>
<!--不需要用到xml打false 需要就改true -->
<failOnMissingWebXml>true</failOnMissingWebXml>
<!--改java11 -->
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<!-- 改常數EL -->
<hibernate.version>5.4.21.Final</hibernate.version>
<spring.version>5.4.21.Final</spring.version>
<spring.version>5.2.12.RELEASE</spring.version>
</properties>
<dependencies>
<!--Dynamic web Module 4.0 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>8.2.2.jre11</version>
</dependency>
<!-- c3p0連線池的功能 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- 做成常數Final -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 自動加到類別路徑 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- hibernate用 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- JSON用 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</project>
<!-- ctrl+shift+f 可以調整 -->
```

* 建立xml 注意版本


[Java Servlet API » 4.0.1](https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api/4.0.1)
[JavaServer Pages(TM) API » 2.3.3](https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api/2.3.3)
[JSTL » 1.2](https://mvnrepository.com/artifact/javax.servlet/jstl/1.2)
* xml 2.5殺掉 改4.0


[
Microsoft JDBC Driver For SQL Server » 8.2.2.jre11](https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc/8.2.2.jre11)
[C3P0 » 0.9.5.2](https://mvnrepository.com/artifact/com.mchange/c3p0/0.9.5.2)
[Hibernate Core Relocation » 5.4.21.Final](https://mvnrepository.com/artifact/org.hibernate/hibernate-core/5.4.21.Final)
[Spring Web MVC » 5.2.12.RELEASE](https://mvnrepository.com/artifact/org.springframework/spring-webmvc/5.2.12.RELEASE)
[Jackson Databind » 2.9.4](https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.9.4)
#### web.xml 組態檔
```clike=
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<display-name>springRest</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/data-access.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
```

#### 類別路徑 必須要在resources之下


#### sessionFactory定義三樣資訊
* 1.連線 2.映射 3.進階

* 方言 hibernate.cfg.xml
***
* 額外:[SQLServer2012Dialect](https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/dialect/SQLServer2012Dialect.html)
#### Employee
```clike=
package proj.model;
import java.sql.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonFormat;
@Entity
@Table(name="employee_rest")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Integer empPk;
String employeeId;
String name;
Double salary;
@JsonFormat(pattern = "yyyy-MM-dd")
Date birthday;
public Employee() {
super();
}
public Employee(Integer empPk, String employeeId, String name, Double salary, Date birthday) {
super();
this.empPk = empPk;
this.employeeId = employeeId;
this.name = name;
this.salary = salary;
this.birthday = birthday;
}
public Integer getEmpPk() {
return empPk;
}
public void setEmpPk(Integer empPk) {
this.empPk = empPk;
}
public String getEmployeeId() {
return employeeId;
}
public void setEmployeeId(String employeeId) {
this.employeeId = employeeId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "Employee [empPk=" + empPk + ", employeeId=" + employeeId + ", name=" + name + ", salary=" + salary
+ ", birthday=" + birthday + "]";
}
}
```
#### BaseController
```clike=
package proj.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class BaseController {
@GetMapping("/")
public String index() {
return "index";
}
}
```
#### index.jsp
```clike=
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div align='center'>
<h2>專案首頁</h2>
<hr>
<a href="<c:url value='/insertEmployee' />" >1. 接收Server送回的JSON物件</a><br>
<a href="<c:url value='/showAllEmployee' />" >2. 輸入會員資料</a><br>
</div>
</body>
</html>
```

#### EmployeeController
```clike=
package proj.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import proj.model.Employee;
import proj.service.EmployeeService;
@Controller
public class EmployeeController {
@Autowired
EmployeeService employeeService;
@PostMapping("/_02/CheckEmployeeId")
public @ResponseBody Map<String, Object> checkEmployeeId(@RequestParam("id") String id) {
Map<String, Object> map = new HashMap<String, Object>();
if (employeeService.checkEmployeeId(id)) {
map.put("id", "已存在");
} else {
map.put("id", "");
}
return map;
}
@PostMapping("/employees")
public @ResponseBody Map<String, Object> saveEmployee(@RequestBody Employee employee) {
System.out.println("employee==>"+employee);
Map<String, Object> map = new HashMap<String, Object>();
try {
employeeService.save(employee);
map.put("success", "新增成功");
} catch (Exception e) {
map.put("fail", "新增失敗");
}
return map;
}
}
```
#### EmployeeService
```clike=
package proj.service;
import proj.model.Employee;
public interface EmployeeService {
boolean checkEmployeeId(String id);
void save(Employee employee);
}
```
#### EmployeeServiceImpl
```clike=
package proj.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import proj.model.Employee;
import proj.repository.EmployeeRepository;
import proj.service.EmployeeService;
@Service
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
EmployeeRepository employeeRepository;
@Transactional
@Override
public boolean checkEmployeeId(String id) {
return employeeRepository.checkEmployeeId(id);
}
@Transactional
@Override
public void save(Employee employee) {
employeeRepository.save(employee);
}
}
```
#### EmployeeRepository
```clike=
package proj.repository;
import proj.model.Employee;
public interface EmployeeRepository {
boolean checkEmployeeId(String id);
void save(Employee employee);
}
```
#### EmployeeRepositoryImpl
```clike=
package proj.repository;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import proj.model.Employee;
@Repository
public class EmployeeRepositoryImpl implements EmployeeRepository {
@Autowired
SessionFactory factory;
@SuppressWarnings("unchecked")
@Override
public boolean checkEmployeeId(String id) {
boolean exist = false;
String hql = "FROM Employee e WHERE e.employeeId = :eid";
Session session = factory.getCurrentSession();
List<Employee> employees = session.createQuery(hql)
.setParameter("eid", id)
.getResultList();
if (employees.isEmpty()) {
exist = false;
} else {
exist = true;
}
return exist;
}
@Override
public void save(Employee employee) {
if (checkEmployeeId(employee.getEmployeeId())) {
//丟出例外
throw new RuntimeException("員工編號已存在,無法新增");
}
Session session = factory.getCurrentSession();
session.save(employee);
}
}
```
* 404 請求找不到
* 405 get post
#### register.jsp
```clike=
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href="<c:url value='/css/styles.css' />" >
<script>
var hasError = false;
window.onload = function() {
var alink = document.getElementById("accountCheck");
var div = document.getElementById('result0c');
alink.onclick = function() {
var idValue = document.getElementById("id").value;
if (!idValue) {
div.innerHTML = "<font color='blue' size='-1'>請輸入員工編號...</font>";
return;
}
var xhr = new XMLHttpRequest();
xhr.open("POST", "<c:url value='/_02/CheckEmployeeId' />", true);
xhr.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
xhr.send("id=" + idValue);
var message = "";
xhr.onreadystatechange = function() {
// 伺服器請求完成
if (xhr.readyState == 4 && xhr.status == 200) {
var result = JSON.parse(xhr.responseText);
if (result.id.length == 0) {
message = "<font color='green' size='-2'>帳號可用</font>";
} else if ( result.id.startsWith("Error") ) {
message = "<font color='red' size='-2'>發生錯誤: 員工編號" + result.id + "</font>";
} else {
message = "<font color='red' size='-2'>帳號重複,請重新輸入員工編號</font>";
}
div.innerHTML = message;
}
}
}
var sendData = document.getElementById("sendData");
sendData.onclick = function() {
hasError = false;
// 讀取欄位資料
var idValue = document.getElementById("id").value;
var nameValue = document.getElementById("name").value;
var salaryValue = document.getElementById("salary").value;
var birthdayValue = document.getElementById("birthday").value;
var div0 = document.getElementById('result0c');
var div1 = document.getElementById('result1c');
var div2 = document.getElementById('result2c');
var div3 = document.getElementById('result3c');
var divResult = document.getElementById('resultMsg');
if (!idValue){
setErrorFor(div0, "請輸入員工編號");
} else {
div0.innerHTML = "";
}
if (!nameValue){
setErrorFor(div1, "請輸入姓名");
} else {
div1.innerHTML = "";
}
if (!salaryValue){
setErrorFor(div2, "請輸入薪水");
} else {
var objRegex = /^\d+$|(^-?\d\d*\.\d\d*$)|(^-?\.\d\d*$)/;
if(!objRegex.test(salaryValue)) {
setErrorFor(div2, "薪水欄必須是數值");
} else {
div2.innerHTML = "";
}
}
if (!birthdayValue){
setErrorFor(div3, "請輸入生日");
} else if(!dateValidation(birthdayValue)) {
setErrorFor(div3, "生日格式錯誤,正確格式為yyyy-MM-dd");
} else {
div3.innerHTML = "";
}
if (hasError){
return false;
}
var xhr1 = new XMLHttpRequest();
xhr1.open("POST", "<c:url value='/employees' />", true);
var jsonMember = {
"employeeId": idValue,
"name": nameValue,
"salary": salaryValue,
"birthday": birthdayValue
}
xhr1.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr1.send(JSON.stringify(jsonMember));
xhr1.onreadystatechange = function() {
// 伺服器請求完成
if (xhr1.readyState == 4 && (xhr1.status == 200 || xhr1.status == 201) ) {
result = JSON.parse(xhr1.responseText);
if (result.fail) {
divResult.innerHTML = "<font color='red' >"
+ result.fail + "</font>";
} else if (result.success) {
divResult.innerHTML = "<font color='GREEN'>"
+ result.success + "</font>";
div0.innerHTML = "";
div1.innerHTML = "";
div2.innerHTML = "";
div3.innerHTML = "";
} else {
if (result.idError) {
div0.innerHTML = "<font color='green' size='-2'>"
+ result.idError + "</font>";
} else {
div0.innerHTML = "";
}
if (result.nameError) {
div1.innerHTML = "<font color='green' size='-2'>"
+ result.nameError + "</font>";
} else {
div1.innerHTML = "";
}
if (result.salaryError) {
div2.innerHTML = "<font color='green' size='-2'>"
+ result.salaryError + "</font>";
} else {
div2.innerHTML = "";
}
if (result.birthdayError) {
div3.innerHTML = "<font color='green' size='-2'>"
+ result.birthdayError + "</font>";
} else {
div3.innerHTML = "";
}
}
}
}
}
}
function setErrorFor(input, message){
input.innerHTML = "<font color='red' size='-2'>" + message + "</font>";
hasError = true;
}
function dateValidation(str) {
var re = new RegExp("^([0-9]{4})[.-]{1}([0-9]{1,2})[.-]{1}([0-9]{1,2})$");
var days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var strDataValue;
var valid = true;
if ((strDataValue = re.exec(str)) != null) {
var y, m, d;
y = parseFloat(strDataValue[1]);
if (y <= 0 || y > 9999) { /*年*/
return false;
}
m = parseFloat(strDataValue[2]);
if (m < 1 || m > 12) { /*月*/
return false;
}
d = parseFloat(strDataValue[3]);
if ( y % 4 == 0 && y % 100 != 0 || y % 400 == 0 ){
days[2] = 29;
} else {
days[2] = 28;
}
if (d <= 0 || d > days[m]) { /*日*/
valid = false;
}
} else {
valid = false;
}
return valid;
}
function isEmail(email) {
return /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(email);
}
</script>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/styles.css">
<meta charset="UTF-8">
<title>Registration</title>
</head>
<body>
<div align='center'>
<h3>輸入員工資料</h3>
<hr>
<div id='resultMsg' style="height: 18px; font-weight: bold;"></div>
<br>
<fieldset style='display: inline-block; width: 820px;'>
<legend>填寫下列資料</legend>
<table border='1'>
<tr height='60'>
<td width='200'> </td>
<td width='400'>
編號: <input type="text" name="id" id='id'><br>
<div style='font-size: 10pt; text-align: center;'>
<a href='#' id='accountCheck' style='font-size: 10pt;'>檢查編號</a>
</div>
</td>
<td width='200'>
<div id='result0c' style="height: 10px;"></div><br>
<div id='result0s' style="height: 10px;"></div>
</td>
</tr>
<tr height='60'>
<td width='200'> </td>
<td width='400'>
姓名: <input type="text" name="name" id='name'><br>
</td>
<td width='200' style="vertical-align:top">
<div id='result1c' style="height: 10px;"></div><br>
<div id='result1s' style="height: 10px;"></div>
</td>
</tr>
<tr height='60'>
<td width='200'> </td>
<td width='400'>
薪水: <input type="text" name="salary" id='salary'><br>
</td>
<td width='200' style="vertical-align:top">
<div id='result2c' style="height: 10px;"></div><br>
<div id='result2s' style="height: 10px;"></div>
</td>
</tr>
<tr height='60'>
<td width='200'> </td>
<td width='400'>
生日: <input type="text" name="birthday" id='birthday' size='24'>
</td>
<td width='200'>
<div id='result3c' style="height: 10px;"></div><br>
<div id='result3s' style="height: 10px;"></div>
</td>
</tr>
<tr height='50'>
<td colspan='3' align='center'><button id='sendData'>送出</button></td>
</tr>
</table>
</fieldset>
<hr>
<p>
<a href="<c:url value='/' />">回前頁</a>
<hr>
</div>
</body>
</html>
```
### 我先統一丟這邊
```clike=
@Override
public List<Employee> getAllEmployees() {
String hql = "FROM Employee";
Session session = factory.getCurrentSession();
@SuppressWarnings("unchecked")
List<Employee> employees = session.createQuery(hql).getResultList();
return employees;
}
```
```clike=
List<Employee> getAllEmployees();
```
```clike=
@Transactional
@Override
public List<Employee> getAllEmployees() {
return employeeRepository.getAllEmployees();
}
```
```clike=
List<Employee> getAllEmployees();
```
```clike=
@GetMapping("/showAllEmployee")
public @ResponseBody List<Employee> getAllEmployees() {
return employeeService.getAllEmployees();
}
```
# Entity類別:Member

# postman
https://www.postman.com/downloads/
* win64


## 生資料


## 報錯

## 成功

## 更新

## 刪除

# 專案規則
