--- title: '用 Ajax 與 SpringMVC controller 傳值互動,附實際範例、程式碼' disqus: hackmd --- 用 Ajax 與 SpringMVC controller 傳值互動,包含實際範例、程式碼 === <br> ## 目錄 [TOC] :::info **友善提醒** 要嘗試並理解本篇範例,至少需先具備基本的 Java Dynamic Web 知識且有能力用 servelet 收值、回傳值 較理想的狀況是您本身已用過 Spring 專案,且理解設定 Reqeust Mapping 讓 controller 成功接受網頁的 request,能透過 ModelAndView 回傳頁面 ::: <br> ## 一句話說明什麼是 Ajax?? 傳統 HTML 傳資料導致頁面重整,Ajax 就是為了解決這件事而發明出來 <br> 認真簡介 Ajax --- AJAX(Asynchronous JavaScript and XML)的中文是非同步的 JavaScript 與 XML 開發技術,是 2005 年被提出來的概念,在生活中我們常看到它的影子: 1. FB 聊天小窗 2. 在網頁註冊時,隨著輸入的帳號名稱不同,即時告知使用者帳號是否已經被用過 3. Reddit 檢查使用者名稱是否用過: ![](https://i.imgur.com/ZRs1aB8.png) <br> 想像一下如果在 FB 每送出一則訊息網頁就要全部重整,或者要一直 F5 才能確認有沒有人發訊息給自己,那會多麼麻煩 不僅使用者體驗差,沒有 Ajax 的時代,HTML 與資料庫互動的主體是靠 <form> 表單來達成,不斷送出 form 讓整個頁面重整的操作都會造成網頁伺服器莫大的負擔 <br> 為了解決這些困擾,實際上曾經過這樣的發展: * 1995 年,JAVA1 中允許瀏覽器透過嵌入網頁的 Java applets 與伺服器進行非同步載入 * 1996 年,IE 支援 iframe 元素,可部分重整網頁(*註) * 1998 年,微軟 Exchange Server 專案中 Outlook Web Access 小組寫出首個 XMLHTTP 組件,允許 client 端指令碼傳送HTTP請求,該組件並很快地被加入 IE4.0 > 註: iframe 直到現在還是非常受歡迎的應用,例如 Twitch、YouTube 等平台都提供官方 iframe 語法,以利用戶將影音視窗鑲嵌到網頁上,豐富了 web 的內容及能提供的服務 延伸閱讀:[[Twitch API 系列 1] 如何將 Twitch 直播嵌入到你的網頁](https://bynum5566.blogspot.com/2020/07/twitch.html) <br> 伺服器對 AJAX 資料請求回應通常是三種資料格式之一(HTML、XML、JSON),而最常與 Javascript 做搭配就是 JSON,本篇筆記以 JSON 做示範 <br> 在前端 view 的 HTML 頁面上如何寫 Ajax --- 看個範例: ```HTML <body> <button id="buttonId">按我發動 Ajax</button> </body> ``` ```Java Script <script> //綁定特定按鈕id發生點擊事件時觸發,常見的做法還有監聽user在表單欄位的 input $(function() { $("#buttonId").bind("click", function() { //定義 Ajax 要發送的目的地,假設這次要用 GET 方法呼叫 checkStock 這個 controller,同時還想代入一個參數,值為整數 123 var destination = "http://yourWeb/product/checkStock?num1="+param1; var param1 = 123; //作為子 function,我們直接發動 Ajax 並照格式填寫必要資訊如下 $.ajax({ url: destination, type: 'GET', //若是POST方法,可多加入一行 data: JSON.stringify({ parameter: value }) 放置要傳的引數 dataType: 'json', contentType: 'application/json; charset=UTF-8', success: function(stock) { //回傳結果成功的話,do something //自定義變數 stock 代表請求成功後controller回傳的值,可以是json或String,但不可以是int(*註) //此區塊可直接跑Java Script、Jquery,就是他們的天下了 }, error: function() { //出錯的話,do something //通常會建議至少印個錯誤訊息,不然很難知道哪邊出錯,這就是為什麼很多網站會設定出錯時跳 alert 告知說 "Ajax error!",這也是蠻多人認識 Ajax 的開始 console.log('Ajax Error: Failing to update stock or purchase button, please refresh'); } }); }) }); </script> ``` 說明一下上面註解之處:由於 Ajax 天生期待你回傳的值是 String(某個意義上來說,Json也算是一種比較長的String),所以無法傳 Integer、會出錯 另外,傳HashMap似乎也收的到,只是會變 Object,還要研究一下怎麼處理 <br> 後端 Controller 如何接受處理 Ajax --- 看個範例: ```Java @Controller @RequestMapping("/product") public class ProductController { @Autowired private StockService stockService; //通常處理一個頁面的 controller 本身已經有主要的任務,頁面則會安排多個 Ajax 處理幾個細微的需求 //這裡也是如此假設,至於主任務內容是什麼請忽略,不影響功能 //唯一請注意主任務是呼叫 http://yourWeb/product/(數字) 來產生回應,所以前面已將這個 class Mapping 給 /product 而這邊主任務的 function 帶個參數 "/{productId}" 好等待網址列的數字傳入 @RequestMapping(value = "/{productId}", method = RequestMethod.GET) @ResponseBody public ModelAndView index(@PathVariable(value = "productId") String productId) { "do something" } //這邊示範如何擴充一個 controller,增加對一個 Ajax 的回應,回傳一個字串 //特別注意由於必須至少設定一個 Mapping 字串,所以我們設定一個 "/checkStock",且由於 controller 本身已帶一個 "/product",所以前端頁面 Ajax 呼叫時的 url 要把兩串連接起來設定為 http://yourWeb/product/checkStock @RequestMapping(value="/checkStock", method=RequestMethod.GET) public @ResponseBody String checkStock(Integer materialId) { int stock = stockService.getStock(materialId); if (stock > 0) return Integer.toString(stock); else return Integer.toString(0); } ``` 這次只在一個 controller 內添加對應 Ajax 的 function,這種簡單的 return String 可直接實做 至於比較複雜的需求,通常會 new 一個 Gson 物件,並用它的 toJson(value) 功能將 value(裡面包含各種想塞的資訊) 轉成 json,最後 return 這個 json 物件。當然,此類操作須先在 Java 專案裝 Gson 的 Jar 檔才能實踐 <br> ## 結語 學習網站開發是一個不斷堆砌的過程,從 HTML、CSS、Java Script、jQuery...,一路組合起來,到能應用 Ajax,才算是一個完整的里程碑 動態網站終究是當代主流,掌握 Ajax 至少就掌握一種與後端 API 互動的門道,能健全一位網路開發者的技能樹 至於後端如何建置並開發出 API,則因單位制宜而未必要用 Spring MVC,此處只是隨意舉例使用,並無強制搭配 **,看你!** :::info **Find this document incomplete?** Leave a comment! ::: ###### tags: `Ajax` `Spring` `Java` `JSON`