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