---
# System prepended metadata

title: RESTful&AJAX 3/9上課內容
tags: [RESTful&AJAX]

---

# RESTful&AJAX 3/9上課內容
###### tags: `RESTful&AJAX`

# 21 AJAX的運作方式
![](https://i.imgur.com/1k90ee9.png)
* 送出請求 收到回應
![](https://i.imgur.com/7kLT2Ff.png)

# 22 XMLHttpRequest物件
![](https://i.imgur.com/kYIdp5C.png)
* 建立AJAX引擎物件
***
## XMLHttpRequest物件提供的方法
![](https://i.imgur.com/JvatFic.png)

# 23 XMLHttpRequest物件的屬性
![](https://i.imgur.com/HS5t1Zd.png)
![](https://i.imgur.com/DXkTf2F.png)
* **onreadystatechange**
    * 事件如果發生了 會執行這個程式碼 程式碼會放到這個屬性裡面
![](https://i.imgur.com/IHoJRzz.png)
```clike=
function displayMember(text){ //回傳是文字型態
	var member = JSON.parse(text);//JSON變成物件型態
```
***
## HTTP請求與HTTP回應 
![](https://i.imgur.com/5TgBq5j.png)

# 24 請求架構範例 GET
![](https://i.imgur.com/je9IF1e.png)
* 藍色地方:查詢字串
***
## 請求架構範例 POST
![](https://i.imgur.com/9rccJtM.jpg)
* Accept告訴servers 型態
* **JSON 格式**
    * application/json 
* MIME Type / Content Type / Media Type 
* **[getMimeType]**(https://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html)
```clike=
String mimeType01 = context.getMimeType("readme.txt"); 
// text/plain
String mimeType01 = context.getMimeType("snoopy.jpg");
// image/jpeg
response.setContentType("text/html; charset=UTF-8");
```
[setContentType](https://docs.oracle.com/javaee/6/api/javax/servlet/ServletResponse.html#setContentType(java.lang.String))
[mime type wiki](https://zh.wikipedia.org/wiki/%E4%BA%92%E8%81%94%E7%BD%91%E5%AA%92%E4%BD%93%E7%B1%BB%E5%9E%8B)
```clike=
text/html; charset = UTF-8
类型名 / 子类型名 [ ; 可选参数 ]
```
![](https://i.imgur.com/AT3kQqw.png)
* plain=純文字格式
[MediaType](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/MediaType.html)

# 25 經由AJAX提出HTTTP請求
![](https://i.imgur.com/864qPrF.png)
* setRequestHeader() 說明送出資料的格式
* send(data) 送出資料(請求本體)
* ![](https://i.imgur.com/FrpMxt7.png)
***
## open()方法
![](https://i.imgur.com/wAezdKN.png)

# 26 setRequestHeader()
![](https://i.imgur.com/pfjV3c6.png)
![](https://i.imgur.com/vlIAVLh.png)
* JSON格式

# 27 GET方法送出請求
![](https://i.imgur.com/AQTDZtH.png)
## POST方法送出請求
![](https://i.imgur.com/ckesOuO.png)

# 28 處理伺服器送回的回應資料(一)
![](https://i.imgur.com/CWKrUOB.jpg)
***
## 處理伺服器送回的回應資料(二)
![](https://i.imgur.com/ypMyWTM.jpg)
![](https://i.imgur.com/Juihua2.png)

#### ReadyStateChangeEvent.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' />" type="text/css" />
<meta charset="UTF-8">
<title>觀察XMLHttpRequest物件之readyState屬性的變化</title>
</head>
<body>
<div class='center'>
<h3>觀察readyState屬性的變化</h3>
<hr>
	<input type='Button' id='btnAsyn' value='送出非同步請求'>
	<hr>
	按下"送出非同步請求"按鈕後，瀏覽器向後端程式：ch01.Ch01Controller#helloAjax()發出非同步請求。
	<hr>
	<font color='red'>必須開啟Chrome瀏覽器之『開發人員工具』，進入Console頁面，觀察readyState屬性的變化</font>
	<hr>
	<script>
		var btnAsyn = document.getElementById("btnAsyn");
		btnAsyn.onclick = function() {
			// 步驟一: 新建XMLHttpRequest物件
			var xhr = new XMLHttpRequest();
			// 步驟二: 經由AJAX提出HTTP請求
			if (xhr != null) {
				xhr.onreadystatechange = function(){
					console.log(xhr.readyState);   // 
					if(xhr.readyState == 4){
						console.log("responseText="+xhr.responseText);
					}
				}
				xhr.open('GET', "<c:url value='/ch01/_01/HelloAjaxOO'  />", true);   // true: 表示非同步
				xhr.send();

			} else {
				div1.innerHTML = "<h3>您的瀏覽器不支援Ajax</h3>";
			}
		}
		
	</script>
	<a href="<c:url value='/ch03/' />">回前頁</a>
</div>    
</body>
</html>
```

#### ex02.jsp
```clike=
window.onload = function(){
	var btn21 = document.getElementById("btn21");
 	var dataArea = document.getElementById("dataArea");
	
	btn21.onclick = function(){
		//AJAX引擎 引擎發動 轟轟轟
		var xhr = new XMLHttpRequest();
		
		//非同步 true
		xhr.open("GET","<c:url value ='/localTime' />")
		xhr.send();
		xhr.onreadystatechange = function(){
			if(xhr.readyState == 4 ){
				if(xhr.status == 200){
					                    //網頁片段
					dataArea.innerHTML = "<font color='red'>"+ xhr.responseText + "</font>";
				} else {
					dataArea.innerHTML = "<font color='red'>程式發生錯誤</font>";
				}
			}
		}
	}
 	
}
```
#### Ex02Controller
```clike=
package ex02;


import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class Ex02Controller {

	@GetMapping("/localTime")
	public @ResponseBody String timeNow() {
		String now = "";
		//時間格式
		String pattern = "yyyy-MM-dd HH:mm:ss SSS";
		String pattern1 = "yyyy年MM月dd日 HH時mm分ss秒 SSS毫秒";
		//把時間=轉型
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		//取時間
		Date date = new Date();
		now = sdf.format(date);
		return now;
	}
	
}

```
#### index.jsp
```clike=
<a href="<c:url value='/ex02' />">練習二</a>
```
#### 路徑 ExerciseFindViewController
![](https://i.imgur.com/mUh0PfY.png)
```c=
package ex01;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class ExerciseFindViewController {

	
	@GetMapping("/ex01")
	public String ex01() {
		return "ex01/ex01";
	}
	
	@GetMapping("/ex02")
	public String ex02() {
		return "ex02/ex02";
	}
}

```
#### applicationContext.xml
![](https://i.imgur.com/Wr8mTEd.png)

# 口試考古題
* 受ioc容器控制反轉
* Ioc—Inversion of Control，即“控制反轉”
* DI(依賴注入)
* ![](https://i.imgur.com/qkjOSix.png)

[ajaxload](http://ajaxload.info/)
[Base64](https://zh.wikipedia.org/wiki/Base64)

# 39 JSON的資料表示法
![](https://i.imgur.com/lXdZL3e.png)

# 41 JSON資料的格式
![](https://i.imgur.com/5QUOFBT.jpg)
***
## JavaScript Object Notation
![](https://i.imgur.com/pM3Lm7j.png)
* []=陣列(array

# 42 JSON資料
![](https://i.imgur.com/dVebDeN.png)

#### ex02.jsp
#### data內容
![](https://i.imgur.com/lbQFHN5.png)
![](https://i.imgur.com/XVkBrHQ.png)
![](https://i.imgur.com/i4jynrH.png)

```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>
<meta charset="UTF-8">
<title>第二個練習</title>
<script type="text/javascript">
window.onload = function(){
	var btn21 = document.getElementById("btn21");
	var btn22 = document.getElementById("btn22");
 	var dataArea = document.getElementById("dataArea");
	
	btn21.onclick = function(){
		//AJAX引擎 引擎發動 轟轟轟
		var xhr = new XMLHttpRequest();
		
		//非同步 true
		xhr.open("GET","<c:url value ='/localTime' />")
		xhr.send();
		xhr.onreadystatechange = function(){
			if(xhr.readyState == 4 ){
				if(xhr.status == 200){
					                    //網頁片段
					dataArea.innerHTML = "<font color='red'>"+ xhr.responseText + "</font>";
				} else {
					dataArea.innerHTML = "<font color='red'>程式發生錯誤</font>";
				}
			}
		}
	}
	btn22.onclick = function(){
		var xhr = new XMLHttpRequest();
		xhr.open("GET","<c:url value ='/variousData' />")
		xhr.send();
		xhr.onreadystatechange = function(){
			if(xhr.readyState == 4 ){
				if(xhr.status == 200){
					//dataArea.innerHTML = "<font color='red'>"+ xhr.responseText + "</font>";
					displayVariousData(xhr.responseText);
				} else {
					dataArea.innerHTML = "<font color='red'>程式發生錯誤</font>";
				}
			}
		}
	}
 	
}
function displayVariousData(text){
	var data = JSON.parse(text);
	//物件裡面有物件
	var mem = data.memBean;
	//看mem是捨麼東東
	alert(JSON.stringify(mem));
	var pub = data.pubBean;
	alert(JSON.stringify(pub));
		
	var segment = "<table border = '1'><tr><th>屬性名稱</th><th>屬性值</th></tr>";
	segment += "<tr><td>Score</td><td>" + data.score + "</td></tr>";
	segment += "<tr><td>會員ID</td><td>" + mem.id + "</td></tr>";
	segment += "<tr><td>會員姓名</td><td>" + mem.name + "</td></tr>";
	segment += "<tr><td>餘額</td><td>" + mem.balance + "</td></tr>";
	segment += "<tr><td>出版社名稱</td><td>" + pub.name + "</td></tr>";
	segment += "<tr><td>出版社地址</td><td>" + pub.address + "</td></tr>";
	segment += "<tr><td>出版社網址</td><td>" + pub.url + "</td></tr>";
	segment += "<tr><td>樂透明牌</td><td>" + data.lottery + "</td></tr>";
	segment += mem;//測試
	segment += pub;//測試
	segment += "<table>";
	dataArea.innerHTML = segment;
}

function displayMember(text){ //回傳是文字型態
	var member = JSON.parse(text);//JSON變成物件型態
	var segment = "<table border='1'><tr><th>鍵值</th><th>會員代號</th><th>會員姓名</th><th>餘額</th><th>生日</th></tr>";
	
	segment += "<tr><td>" + member.pk + "</td><td>"+ member.id + "</td><td>" + member.name +"</td><td>" + member.balance +"</td><td>" + member.birthday +"</td></tr>" ; 
	segment += "</table>";
	//表格
	dataArea.innerHTML = segment;
	//windows畫面
	//alert(member.pk + "," + member.id + "," + member.name);
}
function displayAllMember(text){
	//視為陣列
	var members = JSON.parse(text);
	var segment = "<table border='1'><tr><th>鍵值</th><th>會員代號</th><th>會員姓名</th><th>餘額</th><th>生日</th></tr>";
	
	for(i = 0; i < members.length; i++){
		var member = members[i]
	segment += "<tr><td>" + member.pk + "</td><td>"+ member.id + "</td><td>" + member.name +"</td><td>" + member.balance +"</td><td>" + member.birthday +"</td></tr>" ; 
	}
	segment += "</table>";
	dataArea.innerHTML = segment;
}
</script>
</head>
<body>
<div align="center">
	<h3>練習二</h3>
	<hr>
	<button id='btn21'>現在本地時間</button>
 	<button id='btn22'>回應為多份格式不同的資料</button>
<!-- 	<button id='btn23'>回應為多個物件</button> -->
	<hr>
	<div id='dataArea'>
		&nbsp;
	</div>
	
	<a href="/">回前頁-A NG</a>
	<a href="<c:url value='/' />">回前頁-B</a>
</div>
</body>
</html>
```
#### Ex02Controller
```clike=
package ex02;


import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import ch04._02.model.Member;
import ch04._03.model.PublisherBean;

@Controller 
public class Ex02Controller {
	
	public Ex02Controller() {
		System.out.println("====>IoC容器正在建立本類別(Ex02Controller)的物件");
	}
	
	@GetMapping("/localTime")
	public @ResponseBody String timeNow() {
		String now = "";
		//時間格式
		String pattern = "yyyy-MM-dd HH:mm:ss SSS";
		String pattern1 = "yyyy年MM月dd日 HH時mm分ss秒 SSS毫秒";
		//把時間=轉型
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		//取時間
		Date date = new Date();
		now = sdf.format(date);
		return now;
	}
	
	@GetMapping("/variousData")
	public @ResponseBody Map<String, Object> variousData() {
		Map<String, Object> map = new HashMap<>();
		PublisherBean publisherBean = new PublisherBean();
		publisherBean.setAddress("客家資策會");
		publisherBean.setName("三民出版社");
		publisherBean.setUrl("http://www.sanming.com.tw");
		Member member = new Member("15", "吳柏毅", 3500.0, java.sql.Date.valueOf("1999-9-9"));
		List<Integer> lottery = Arrays.asList(25,18,37,6,16,40);
		
		map.put("pubBean", publisherBean);
		map.put("memBean", member);
		map.put("score", 80);
		map.put("lottery", lottery);
		
		return map;
	}
}

```

# 43 JavaScript 處理JSON資料
![](https://i.imgur.com/5FUpc6y.png)
* JSON 大寫

### 排版技巧(方便)
![](https://i.imgur.com/idsPKm4.png)

# 45 單一物件所組成的JSON資料
![](https://i.imgur.com/XJ1NWq7.png)
![](https://i.imgur.com/HlNUKm3.png)

#### QuerySingleBookAjax.jsp
![](https://i.imgur.com/J1ZFEqU.png)
![](https://i.imgur.com/Xxv1Ntx.png)
```clike=
<option value="-1">請挑選</option>
```
![](https://i.imgur.com/fIEESWE.png)

# 46 多筆相同類別之物件所組成的JSON資料
![](https://i.imgur.com/YGjWdAV.png)

# RESTful 

# 62 Web Service
![](https://i.imgur.com/TEwyVmZ.png)
* 跨平台 

# 63 REST
![](https://i.imgur.com/0Nagtm2.jpg)
* 表現呈狀態
* **物件**
    *  有狀態(狀態是會改變的) 
    *  有行為
***
## Resource
![](https://i.imgur.com/k9B2pXo.png)

# 64 RESTful Web Service 對外的介面
![](https://i.imgur.com/tuPekPX.png)
***
## 請求與回應
![](https://i.imgur.com/zNf5Tht.png)

# 66 HTTP Response架構
![](https://i.imgur.com/usPtfX5.png)

# 67 Spring MVC框架與REST
![](https://i.imgur.com/0IuuzPg.png)
* REST服務控制器

# 68 請求在Spring MVC框架下的處理流程
![](https://i.imgur.com/K6fooeV.png)
![](https://i.imgur.com/esnFTi9.png)
* 系統啟動 存取資料 路徑 HM
* 收集所有的控制器去處理請求 搭配的方法
### 同一個請求只能有一個對應方法(多個會報錯) 
![](https://i.imgur.com/eZ1oSO3.png)


# 69 Spring REST的運作流程
![](https://i.imgur.com/mEQXljd.png)

# 70 REST程式於Sprping框架下的運作要點
![](https://i.imgur.com/Zs0zlpb.png)

# 71設計控制類別與控制器方法的步驟
![](https://i.imgur.com/KIk9msN.png)

# 72 @RequestMapping註釋
![](https://i.imgur.com/aiZKp8Q.png)

# 73 Spring 4.3新增的註釋
![](https://i.imgur.com/TZ0hoQ6.png)

# 74 控制器方法可接收之參數類型
![](https://i.imgur.com/oSO2vEh.jpg)
***
## 控制器方法傳回值的型態
![](https://i.imgur.com/R4Leq41.png)
*  試圖解析器

# 75 多個請求路徑可對應同一個控制器方法
![](https://i.imgur.com/SQzFBbo.png)
***
## 同一請求路徑不能對應多個控制器方法
![](https://i.imgur.com/9gDUPbY.jpg)

# 76 @RequestParam 
![](https://i.imgur.com/ft4JlzO.png)

# 78 亂碼中文
![](https://i.imgur.com/5nc9huZ.png)

# 80 準備工作
![](https://i.imgur.com/vW4Ze3o.png)

#### 改密碼
![](https://i.imgur.com/LlHHqxq.png)
![](https://i.imgur.com/wPn6zLY.png)
#### sql
![](https://i.imgur.com/TbiBMo2.png)

# 1231231312
![](https://i.imgur.com/kXJOZLk.png)
