# RESTful&AJAX 3/9上課內容
###### tags: `RESTful&AJAX`
# 21 AJAX的運作方式

* 送出請求 收到回應

# 22 XMLHttpRequest物件

* 建立AJAX引擎物件
***
## XMLHttpRequest物件提供的方法

# 23 XMLHttpRequest物件的屬性


* **onreadystatechange**
* 事件如果發生了 會執行這個程式碼 程式碼會放到這個屬性裡面

```clike=
function displayMember(text){ //回傳是文字型態
var member = JSON.parse(text);//JSON變成物件型態
```
***
## HTTP請求與HTTP回應

# 24 請求架構範例 GET

* 藍色地方:查詢字串
***
## 請求架構範例 POST

* 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
类型名 / 子类型名 [ ; 可选参数 ]
```

* plain=純文字格式
[MediaType](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/MediaType.html)
# 25 經由AJAX提出HTTTP請求

* setRequestHeader() 說明送出資料的格式
* send(data) 送出資料(請求本體)
* 
***
## open()方法

# 26 setRequestHeader()


* JSON格式
# 27 GET方法送出請求

## POST方法送出請求

# 28 處理伺服器送回的回應資料(一)

***
## 處理伺服器送回的回應資料(二)


#### 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

```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

# 口試考古題
* 受ioc容器控制反轉
* Ioc—Inversion of Control,即“控制反轉”
* DI(依賴注入)
* 
[ajaxload](http://ajaxload.info/)
[Base64](https://zh.wikipedia.org/wiki/Base64)
# 39 JSON的資料表示法

# 41 JSON資料的格式

***
## JavaScript Object Notation

* []=陣列(array
# 42 JSON資料

#### ex02.jsp
#### data內容



```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'>
</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資料

* JSON 大寫
### 排版技巧(方便)

# 45 單一物件所組成的JSON資料


#### QuerySingleBookAjax.jsp


```clike=
<option value="-1">請挑選</option>
```

# 46 多筆相同類別之物件所組成的JSON資料

# RESTful
# 62 Web Service

* 跨平台
# 63 REST

* 表現呈狀態
* **物件**
* 有狀態(狀態是會改變的)
* 有行為
***
## Resource

# 64 RESTful Web Service 對外的介面

***
## 請求與回應

# 66 HTTP Response架構

# 67 Spring MVC框架與REST

* REST服務控制器
# 68 請求在Spring MVC框架下的處理流程


* 系統啟動 存取資料 路徑 HM
* 收集所有的控制器去處理請求 搭配的方法
### 同一個請求只能有一個對應方法(多個會報錯)

# 69 Spring REST的運作流程

# 70 REST程式於Sprping框架下的運作要點

# 71設計控制類別與控制器方法的步驟

# 72 @RequestMapping註釋

# 73 Spring 4.3新增的註釋

# 74 控制器方法可接收之參數類型

***
## 控制器方法傳回值的型態

* 試圖解析器
# 75 多個請求路徑可對應同一個控制器方法

***
## 同一請求路徑不能對應多個控制器方法

# 76 @RequestParam

# 78 亂碼中文

# 80 準備工作

#### 改密碼


#### sql

# 1231231312
