---
# System prepended metadata

title: RESTful&AJAX 3/10 上課內容 (Maven)
tags: [RESTful&AJAX]

---

# RESTful&AJAX 3/10 上課內容 (Maven)
###### tags: `RESTful&AJAX`

# 80 REST 讀取所有會員資料
![](https://i.imgur.com/azp5Zbx.png)

# 81 REST 新增會員資料 
![](https://i.imgur.com/Tjyp2Nu.png)
***
## 

#### 改專案
![](https://i.imgur.com/r6YRZtq.png)
![](https://i.imgur.com/iYrO9Ss.png)


# 52 訊息轉換
![](https://i.imgur.com/7nRsiab.png)

#### 動態專案 早期沒有Maven
![](https://i.imgur.com/9ZFHF5R.png)
#### Maven專案
![](https://i.imgur.com/linjkqn.png)
![](https://i.imgur.com/MJNNhac.png)
![](https://i.imgur.com/cO9syYu.png)
![](https://i.imgur.com/BkvPWxI.png)
* 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 可以調整 -->
```
![](https://i.imgur.com/I28mYpX.png)
* 建立xml 注意版本
![](https://i.imgur.com/iiU7TsJ.png)
![](https://i.imgur.com/ygNMBmq.png)
[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
![](https://i.imgur.com/Vfy21KS.png)
![](https://i.imgur.com/bTssgXj.png)
[
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>
```
![](https://i.imgur.com/ufGaoee.png)

#### 類別路徑 必須要在resources之下
![](https://i.imgur.com/UIDR3MN.jpg)
![](https://i.imgur.com/iUgyHQd.png)

#### sessionFactory定義三樣資訊
* 1.連線 2.映射 3.進階
![](https://i.imgur.com/ni3uuyU.png)
* 方言 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>
```

![](https://i.imgur.com/M8OLxDd.png)

#### 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'>&nbsp;</td>
		<td width='400'>
			&nbsp;編號: <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'>&nbsp;</td>
		<td width='400'>
			&nbsp;姓名: <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'>&nbsp;</td>
		<td width='400'>
			&nbsp;薪水: <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'>&nbsp;</td>
		<td width='400'>
			&nbsp;生日: <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
![](https://i.imgur.com/QMZZpvo.png)

# postman
https://www.postman.com/downloads/
* win64
![](https://i.imgur.com/TskR4Py.png)
![](https://i.imgur.com/tA06LAP.png)
## 生資料
![](https://i.imgur.com/KZciDsi.png)
![](https://i.imgur.com/4mlDqKE.png)
## 報錯
![](https://i.imgur.com/iqZtCl6.png)
## 成功
![](https://i.imgur.com/PXTG2Sx.png)
## 更新
![](https://i.imgur.com/kRWanMk.png)
## 刪除
![](https://i.imgur.com/WgXCbIg.png)

# 專案規則
![](https://i.imgur.com/QXe5Bpl.png)
