Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)...
Spring MVC 學習總結(九)——Spring MVC實現RESTful與JSON(Spring MVC為前端提供服務)
目錄
- 一、JSON
- 1.1、概要
- 1.2、使用ModelAndView
- 1.3、使用@ResponseBody與Jackson
- 1.4、亂碼問題
- 1.4.1、方法一在action上聲明編碼格式
- 1.4.2、方法二修改Spring配置文件
- 1.5、日期格式化問題
- 1.5.1、方法一注解字段
- 1.5.2、方法二取消timestamps形式
- 1.6、工具類
- 1.7、數據持久化
- 1.7.1、創建數據庫與表
- 1.7.2、添加測試數據
- 1.7.3、添加數據庫驅動修改連接信息
- 1.7.4、新增UserDAOPro
- 1.7.5、修改用戶業務類
- 1.7.6、徹底解決Spring MVC 中文亂碼
- 二、RESTful
- 2.1、概要
- 2.2、@RestController
- 2.2.1、Hello World
- 2.3、RESTful員工管理示例
- 2.3.1、獲得所有的員工信息服務
- 2.3.2、獲得指定編號的員工信息服務
- 2.3.3、新增員工服務
- 2.3.4、修改員工服務
- 2.3.3、刪除員工服務
- 2.4、AJAX客戶端調用RESTful
- 2.4.1、用戶列表
- 2.4.2、新增用戶
- 2.4.3、刪除用戶
- 2.4.4、更新數據
- 三、示例下載
- 四、視頻
- 五、作業
- 六、工具下載
?很多時候前端都需要調用后臺服務實現交互功能,常見的數據交換格式多是JSON或XML,這里主要講解Spring MVC為前端提供JSON格式的數據并實現與前臺交互。RESTful則是一種軟件架構風格、設計風格,而不是標準,只是提供了一組設計原則和約束條件。它主要用于客戶端和服務器交互類的軟件。基于這個風格設計的軟件可以更簡潔,更有層次,更易于實現緩存等機制。
一、JSON
1.1、概要
JSON(JavaScript Object Notation, JS 對象標記) 是一種輕量級的數據交換格式。它基于 ECMAScript (w3c制定的js規范)的一個子集,采用完全獨立于編程語言的文本格式來存儲和表示數據。簡潔和清晰的層次結構使得 JSON 成為理想的數據交換語言。 易于人閱讀和編寫,同時也易于機器解析和生成,并有效地提升網絡傳輸效率。
在 JS 語言中,一切都是對象。因此,任何支持的類型都可以通過 JSON 來表示,例如字符串、數字、對象、數組等。但是對象和數組是比較特殊且常用的兩種類型。
要實現從對象轉換為 JSON 字符串,使用 JSON.stringify() 方法:
var json = JSON.stringify({a: 'Hello', b: 'World'}); //結果是 '{"a": "Hello", "b": "World"}'
要實現從 JSON 轉換為對象,使用 JSON.parse() 方法:
var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //結果是 {a: 'Hello', b: 'World'}
示例:
?View Code結果:
1.2、使用ModelAndView
修改pom.xml添加對jackson的依賴
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.2</version></dependency>在user控制器中添加一個action
@RequestMapping(value = "/users")public ModelAndView users(){ModelAndView mav=new ModelAndView(new MappingJackson2JsonView());mav.addObject(userService.queryAllUsers());return mav;}運行結果:
1.3、使用@ResponseBody與Jackson
修改pom.xml添加對jackson的依賴
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.2</version></dependency>添加一個action,使用注解@ResponseBody,響應主體而不是路徑
@RequestMapping(value = "/userJson",produces = "application/json;charset=utf-8")@ResponseBodypublic String userJson(){ObjectMapper mapper=new ObjectMapper();try {return mapper.writeValueAsString(userService.queryAllUsers());} catch (JsonProcessingException e) {e.printStackTrace();}return null;}結果:
1.4、亂碼問題
1.4.1、方法一在action上聲明編碼格式
@RequestMapping(path="/json",produces = "application/json;charset=UTF-8")1.4.2、方法二修改Spring配置文件
上一種方法比較麻煩,如果項目中有許多action則每一個都要添加,可以通過Spring配置統一指定
<mvc:annotation-driven><mvc:message-converters register-defaults="true"><bean class="org.springframework.http.converter.StringHttpMessageConverter"><constructor-arg value="UTF-8"/></bean><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"><property name="objectMapper"><bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"><property name="failOnEmptyBeans" value="false"/></bean></property></bean></mvc:message-converters> </mvc:annotation-driven>1.5、日期格式化問題
默認日期格式會變成一個數字,是1970年1月1日到當前日期的毫秒數:
Jackson 默認是轉成timestamps形式
1.5.1、方法一注解字段
在實體字段上使用@JsonFormat注解格式化日期
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")
代碼:
/*** 出生日期*/@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")private Date birthday;結果:
1.5.2、方法二取消timestamps形式
如果只取消則會得到一個默認的日期格式,效果如下:
當然自定義輸出格式是允許的
@RequestMapping(value = "/userJson",produces = "application/json;charset=utf-8")@ResponseBodypublic String userJson(){ObjectMapper mapper=new ObjectMapper();//不使用時間差的方式mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);//自定義日期格式對象SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//指定日期格式mapper.setDateFormat(sdf);try {return mapper.writeValueAsString(userService.queryAllUsers());} catch (JsonProcessingException e) {e.printStackTrace();}return null;}運行結果:
1.6、工具類
工具類可以復用代碼,提高開發效率,如上文中的序列化JSON:
package com.zhangguo.springmvc08.utils;import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature;import java.text.SimpleDateFormat;/*** JSON工具類,輔助類* */ public class JsonUtil {public static String getJson(Object object) {return getJson(object,"yyyy-MM-dd HH:mm:ss");}public static String getJson(Object object,String dateFormat) {ObjectMapper mapper = new ObjectMapper();//不使用時間差的方式mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);//自定義日期格式對象SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);//指定日期格式mapper.setDateFormat(sdf);try {return mapper.writeValueAsString(object);} catch (JsonProcessingException e) {e.printStackTrace();}return null;} }調用:
@RequestMapping(value = "/userJson",produces = "application/json;charset=utf-8")@ResponseBodypublic String userJson(){return JsonUtil.getJson(userService.queryAllUsers(),"yyyy-MM-dd");}如對MySQL數據庫的訪問封裝:
?View Code1.7、數據持久化
上一章的示例中并沒有直接訪問數據庫,數據以集合的形式存放在內存中,這里使用MySQL將數據存儲到數據庫中。該示例基于第8章的示例,請先熟悉第8章的內容《Spring MVC 學習總結(八)——Spring MVC概要與環境配置(IDEA+Maven+Tomcat7+JDK8、示例與視頻)》
1.7.1、創建數據庫與表
開啟MySQL服務
打開管理工具Navicat
創建數據庫
新建表
/* Navicat MySQL Data TransferSource Server : localhostMe Source Server Version : 50506 Source Host : localhost:3306 Source Database : mvcdbTarget Server Type : MYSQL Target Server Version : 50506 File Encoding : 65001Date: 2017-12-07 14:08:35 */SET FOREIGN_KEY_CHECKS=0;-- ---------------------------- -- Table structure for `user` -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '編號',`name` varchar(32) NOT NULL COMMENT '姓名',`birthday` datetime DEFAULT NULL COMMENT '生日',`address` varchar(128) DEFAULT NULL COMMENT '地址',`phone` varchar(11) DEFAULT NULL COMMENT '電話',PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ---------------------------- -- Records of user -- ----------------------------1.7.2、添加測試數據
?
insert into user(name,birthday,address,phone) select '張學友','1968-09-08','中國香港','18989890098' union select '張惠妹','1969-01-05','中國北京','13345678781' union select '張國立',SYSDATE(),'中國珠海','13567453422'select id,name,birthday,address,phone from user;?
1.7.3、添加數據庫驅動修改連接信息
在pom.xml中依賴MySQL驅動包
<!--mysql驅動包--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.35</version></dependency>修改工具類的中數據庫連接信息
public static String DRIVER="com.mysql.jdbc.Driver";public static String URL="jdbc:mysql://127.0.0.1:3306/mvcdb?useUnicode=true&characterEncoding=UTF-8";public static String USER_NAME="root";public static String PASSWORD="pwd";1.7.4、新增UserDAOPro
?新增UserDAOPro類,實現MySQL數據庫訪問,代碼如下:
package com.zhangguo.springmvc08.dao;import com.zhangguo.springmvc08.entity.User; import com.zhangguo.springmvc08.utils.JDBCUtil; import org.springframework.stereotype.Repository;import java.util.List;@Repository("mysql") public class UserDAOPro implements IUserDAO {public List<User> getAll() {return JDBCUtil.queryForList("select id,name,birthday,address,phone from user", User.class);}public User getUserById(int id) {return JDBCUtil.queryForObject("select id,name,birthday,address,phone from user where id=?", User.class, id);}public boolean add(User user) {return JDBCUtil.update("insert into user(name,birthday,address,phone) values(?,?,?,?)", user.getName(), user.getBirthday(), user.getAddress(), user.getPhone()) > 0;}public boolean delete(int id) {return JDBCUtil.update("delete from user where id=?", id) > 0;}public boolean update(User user) {return JDBCUtil.update("update user set name=?,birthday=?,address=?,phone=? where id=?", user.getName(), user.getBirthday(), user.getAddress(), user.getPhone(), user.getId()) > 0;} }1.7.5、修改用戶業務類
因為系統中有兩個類實現了IUserDAO,指定名稱:
package com.zhangguo.springmvc08.service;import com.zhangguo.springmvc08.dao.IUserDAO; import com.zhangguo.springmvc08.dao.UserDAO; import com.zhangguo.springmvc08.entity.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service;import javax.annotation.Resource; import java.util.List;/**用戶業務*/ @Service public class UserService {@Resource(name="mysql")IUserDAO userdao;public List<User> queryAllUsers(){return userdao.getAll();}public User getUserById(int id){return userdao.getUserById(id);}public boolean deleteUser(int id){return userdao.delete(id);}public boolean addUser(User user){return userdao.add(user);}public boolean editUser(User user){return userdao.update(user);}}1.7.6、徹底解決Spring MVC 中文亂碼
添加用戶后發現有亂碼,調試發現發送到服務器的數據已經是亂碼
1、頁面編碼
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>2、URL中的亂碼
改tomcat中server.xml中Connector的port=“8080”,加上一個 URIEncoding=”utf-8”
3、配置過濾器,指定所有請求的編碼
修改web.xml,添加編碼過濾器
<filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>4、文件編碼
將文件另存為utf-8格式
5、數據庫編碼
連接字符串指定編碼格式
public static String URL="jdbc:mysql://127.0.0.1:3306/mvcdb?useUnicode=true&characterEncoding=UTF-8"創建數據庫時指定utf-8編碼格式
最終運行結果正常:
二、RESTful
2.1、概要
REST(英文:Representational State Transfer,簡稱REST,表述性狀態轉移)描述了一個架構樣式的網絡系統,比如 web 應用程序。它首次出現在 2000 年 Roy Fielding 的博士論文中,他是 HTTP 規范的主要編寫者之一。在目前主流的三種Web服務交互方案中,REST相比于SOAP(Simple Object Access protocol,簡單對象訪問協議)以及XML-RPC更加簡單明了,無論是對URL的處理還是對Payload的編碼,REST都傾向于用更加簡單輕量的方法設計和實現。值得注意的是REST并沒有一個明確的標準,而更像是一種設計的風格。
RESTful架構,就是目前最流行的一種互聯網軟件架構。它結構清晰、符合標準、易于理解、擴展方便,所以正得到越來越多網站的采用。
GET /tickets # 獲取ticket列表
GET /tickets/12 # 查看某個具體的ticket
POST /tickets # 新建一個ticket
PUT /tickets/12 # 更新ticket 12.
DELETE /tickets/12 #刪除ticekt 12
REST特點如下:
- 基于HTTP協議
- 是另一種服務架構
- 傳遞是JSON、POX(Plain Old XML)而不是SOAP格式的數據
- 充分利用HTTP謂詞(Verb)
- 側重數據的傳輸,業務邏輯交給客戶端自行處理
REST是一種分布式服務架構的風格約束,像Java、.Net(WCF、WebAPI)都有對該約束的實現,使URL變得更加有意義,更加簡潔明了,如:
http://www.zhangguo.com/products/1 get請求 表示獲得所有產品的第1個
http://www.zhangguo.com/products/product post請求 表示添加一個產品
http://www.zhangguo.com/products/1/price get請求 表示獲得第1個產品的價格
http://www.zhangguo.com/products/1 delete請求 刪除編號為1的產品
REST設計需要遵循的原則:
- 網絡上的所有事物都被抽象為資源(resource);
- 每個資源對應一個唯一的資源標識符(resource identifier);
- 通過通用的連接器接口(generic connector interface)對資源進行操作;
- 對資源的各種操作不會改變資源標識符;
- 所有的操作都是無狀態的(stateless)
謂詞
GET
表示查詢操作,相當于Retrieve、Select操作
POST
表示插入操作,相當于Create,Insert操作
PUT
表示修改操作,相當于Update操作
DELETE
表示刪除操作,相當于Delete操作
其它還有:
2.2、@RestController
Spring 4.0重要的一個新的改進是@RestController注解,它繼承自@Controller注解。4.0之前的版本,Spring MVC的組件都使用@Controller來標識當前類是一個控制器servlet。
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Controller @ResponseBody public @interface RestController {String value() default ""; }使用這個注解,我們可以開發REST服務的時候不需要使用@Controller而專門的@RestController。
當你實現一個RESTful web services的時候,response將一直通過response body發送。為了簡化開發,Spring 4.0提供了一個專門版本的controller。
添加了AsyncRestTemplate類,當開發REST客戶端時允許非阻塞異步支持。
2.2.1、Hello World
默認控制器與Action
package com.zhangguo.springmvc08.controller;import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping;@Controller //聲明為控制器 @RequestMapping(path = {"/","Home","First"}) //請求映射 public class HomeController {@RequestMapping(path = "/index") //請求映射public String index(Model model){model.addAttribute("message","Hello Spring MVC!");return "home/index";}@RequestMapping(path = "/") //請求映射public String first(Model model){model.addAttribute("message","Hello Spring MVC,Welcome Page!");return "home/index";} }修改pom.xml添加jackson的引用
新增一個控制器,代碼如下:
package com.zhangguo.springmvc08.controller;import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping(path="/users") public class UsersController {@RequestMapping(path = "/{name}",method = RequestMethod.GET)public String hello(@PathVariable String name){return "Hello "+name;}@RequestMapping(path = "/stu/{name}",method = RequestMethod.GET)public Student student(@PathVariable String name){return new Student("Hello "+name);}}/**學生*/ class Student{public Student(String name) {this.name = name;}private String name;public String getName() {return name;}public void setName(String name) {this.name = name;} }運行結果:
從上面的示例可以看出,使用@RestController后返回的字符串不再是路徑,如果返回的是對象則會直接序列化,可以是JSON或XML;如果返回的是對象類型則直接序列化成JSON格式,請注意添加對Jackson的依賴。
2.3、RESTful員工管理示例
假定要為員工(emp)提供對外的REST服務,接口如下:
/emps? get 獲得所有的員工信息
/emps/1 get 獲得編號為1的員工信息
/emps post 添加
/emps put 修改
/emps/1 delete 刪除
2.3.1、獲得所有的員工信息服務
/emps? get 獲得所所有的員工信息
package com.zhangguo.springmvc08.controller;import com.zhangguo.springmvc08.entity.User; import com.zhangguo.springmvc08.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController @RequestMapping(path = "/emps") public class EmpController {@AutowiredUserService userService;@RequestMapping(path = "", method = RequestMethod.GET)public List<User> getAllemps() {return userService.queryAllUsers();}}?結果:
2.3.2、獲得指定編號的員工信息服務
/emps/1 get 獲得編號為1的員工信息
代碼:
@RequestMapping(path = "/{id}", method = RequestMethod.GET)public User getEmpById(@PathVariable int id) {return userService.getUserById(id);}結果:
2.3.3、新增員工服務
/emps post 添加
代碼:
@RequestMapping(path = "", method = RequestMethod.POST)public boolean addEmp(@RequestBody User user) {return userService.addUser(user);}請求:
返回true
結果:
說明:參數中的json格式一定要使用標準格式,注意引號,注意Content-Type,默認的Content-Type類型是:application/x-www-form-urlencoded
因為我們使用json,則Content-Type的值應該為application/json;charset=utf-8
2.3.4、修改員工服務
/emps? 修改 put請求
代碼:
@RequestMapping(path = "", method = RequestMethod.PUT)public boolean updateEmp(@RequestBody User user) {return userService.editUser(user);}測試:
結果:
2.3.3、刪除員工服務
/emps/1 delete 刪除
代碼:
package com.zhangguo.springmvc08.controller;import com.zhangguo.springmvc08.entity.User; import com.zhangguo.springmvc08.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;import java.util.List;@RestController @RequestMapping(path = "/emps") public class EmpController {@AutowiredUserService userService;@RequestMapping(path = "", method = RequestMethod.GET)public List<User> getAllEmps() {return userService.queryAllUsers();}@RequestMapping(path = "/{id}", method = RequestMethod.GET)public User getEmpById(@PathVariable int id) {return userService.getUserById(id);}@RequestMapping(path = "", method = RequestMethod.POST)public boolean addEmp(@RequestBody User user) {return userService.addUser(user);}@RequestMapping(path = "", method = RequestMethod.PUT)public boolean updateEmp(@RequestBody User user) {return userService.editUser(user);}@RequestMapping(path = "/{id}", method = RequestMethod.DELETE)public AjaxState deleteEmpById(@PathVariable int id) {Boolean result=userService.deleteUser(id);return new AjaxState(result?"success":"error",id,result?"刪除成功!":"刪除失敗");}}class AjaxState{public String state;public Object data;public String message;public AjaxState(String state, Object data, String message) {this.state = state;this.data = data;this.message = message;}public AjaxState(){} }測試:
結果:
已刪除成功,delete請求不需要正文與get請求類似
2.4、AJAX客戶端調用RESTful
ajax傳送json格式數據,關鍵是指定contentType,data要是json格式
如果是restful接口,把type改成對應的post(增)、delete(刪)、put(改)、get(查)即可
var post_data={"name":"test001","pass":"xxxx"}; $.ajax({ url: "http://192.168.10.111:8080/uc/login", type: 'post', contentType: "application/json; charset=utf-8", data:JSON.stringify(post_data), success:function (data) { //調用成功 }, error: function(data, textStatus, errorThrown){ //調用失敗 } });為了前端統一調用,修改后的控制器如下:
package com.zhangguo.springmvc08.controller;import com.zhangguo.springmvc08.entity.User; import com.zhangguo.springmvc08.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;import java.util.List;@RestController @RequestMapping(path = "/emps") public class EmpController extends BaseController {@AutowiredUserService userService;@RequestMapping(path = "", method = RequestMethod.GET)public AjaxState getAllEmps() {List<User> users=userService.queryAllUsers();boolean result=users!=null;return new AjaxState(result?"success":"error",users,result?"獲得數據成功!":"獲得數據失敗!");}@RequestMapping(path = "/{id}", method = RequestMethod.GET)public AjaxState getEmpById(@PathVariable int id) {User user=userService.getUserById(id);boolean result=user!=null;return new AjaxState(result?"success":"error",user,result?"獲得數據成功!":"獲得數據失敗!");}@RequestMapping(path = "", method = RequestMethod.POST)public AjaxState addEmp(@RequestBody User user) {boolean result=userService.addUser(user);return new AjaxState(result?"success":"error",user,result?"添加成功!":"添加失敗");}@RequestMapping(path = "", method = RequestMethod.PUT)public AjaxState updateEmp(@RequestBody User user) {boolean result=userService.editUser(user);return new AjaxState(result?"success":"error",user,result?"修改成功!":"修改失敗");}@RequestMapping(path = "/{id}", method = RequestMethod.DELETE)public AjaxState deleteEmpById(@PathVariable int id) {Boolean result=userService.deleteUser(id);return new AjaxState(result?"success":"error",id,result?"刪除成功!":"刪除失敗");}}class AjaxState{public String state;public Object data;public String message;public AjaxState(String state, Object data, String message) {this.state = state;this.data = data;this.message = message;}public AjaxState(){} }2.4.1、用戶列表
示例:
<!DOCTYPE html> <html> <head><meta charset="UTF-8"/><title>Title</title> </head> <body> <h2>員工管理</h2> <table border="1" width="100%" id="tabEmps"><tr><th>編號</th><th>姓名</th><th>生日</th><th>地址</th><th>電話</th><th>操作</th></tr> </table> <p></p> <p class="loading" style="display: none;"><img src="img/loading.gif" align="absmiddle">努力加載中... </p> <p class="message"></p> <script src="js/jquery-1.11.3.min.js"></script> <script> // var data = { // "state": "success", // "data": {"id": 1, "name": "張學友", "birthday": -41500800000, "address": "中國香港", "phone": "18989890098"}, // "message": "獲得數據成功!" // }var app = {url: "http://localhost:8080/mvc08/emps",init:function(){this.binddata();},ajax: function (actionType, callback, path, data) {$.ajax({url: app.url + (path||""),contentType: "application/json;charset=utf-8",data: data || {},type: actionType||"get",dataType: "json",success: function (data) {if(data&&data.state=="success"){app.info(data.message);}else if(data&&data.state=="error"){app.info(data.message);}else{app.info(data);}if(callback){callback(data);}},error: function (XMLHttpRequest, textStatus, errorThrown) {info(textStatus+errorThrown);},beforeSend: function () {$(".loading").show(200);},complete: function () {$(".loading").hide(200);}});},binddata: function () {this.ajax("get",function(data){$.each(data.data,function(index,emp){var tr=$("<tr/>").appendTo("#tabEmps");$("<td/>").text(emp.id).appendTo(tr);$("<td/>").text(emp.name).appendTo(tr);$("<td/>").text(emp.birthday).appendTo(tr);$("<td/>").text(emp.address).appendTo(tr);$("<td/>").text(emp.phone).appendTo(tr);$("<td/>").html("<a>刪除</a>").appendTo(tr);});});},info:function(msg){$(".message")[0].innerHTML+=msg+"<br/>";}};app.init(); </script> </body> </html>結果:
2.4.2、新增用戶
示例:
<!DOCTYPE html> <html> <head><meta charset="UTF-8"/><title>Title</title> </head> <body> <h2>員工管理</h2> <table border="1" width="100%" id="tabEmps"><tr><th>編號</th><th>姓名</th><th>生日</th><th>地址</th><th>電話</th><th>操作</th></tr> </table> <p class="loading" style="display: none;"><img src="img/loading.gif" align="absmiddle">努力加載中... </p> <form id="formEmps"><fieldset><legend>用戶信息</legend><p><label for="name">姓名:</label><input name="name" id="name" type="text" required="required" maxlength="32"/></p><p><label for="birthday">生日:</label><input name="birthday" id="birthday" type="date" required="required" maxlength="8"/></p><p><label for="address">地址:</label><input name="address" id="address" type="text" required="required" maxlength="128"/></p><p><label for="phone">電話:</label><input name="phone" id="phone" type="text" required="required" maxlength="11"/></p><p><input id="id" type="hidden" name="id" value=""/><button type="button" id="btnSubmit">保存</button></p></fieldset> </form> <p class="message"> </p> <script src="js/jquery-1.11.3.min.js"></script> <script>// var data = {// "state": "success",// "data": {"id": 1, "name": "張學友", "birthday": -41500800000, "address": "中國香港", "phone": "18989890098"},// "message": "獲得數據成功!"// }var app = {url: "http://localhost:8080/mvc08/emps",init: function () {$("#btnSubmit").click(app.save);this.binddata();},ajax: function (actionType, callback, path, data) {$.ajax({url: app.url + (path || ""),contentType: "application/json;charset=utf-8",data:JSON.stringify(data)||"{}",type: actionType || "get",dataType: "json",success: function (data) {if (data && data.state == "success") {app.info(data.message);} else if (data && data.state == "error") {app.info(data.message);} else {app.info(data);}if (callback) {callback(data);}},error: function (XMLHttpRequest, textStatus, errorThrown) {app.info(textStatus + errorThrown);},beforeSend: function () {$(".loading").show(200);},complete: function () {$(".loading").hide(200);}});},binddata: function () {$("#tabEmps tr:gt(0)").remove();this.ajax("get", function (data) {$.each(data.data, function (index, emp) {var tr = $("<tr/>").appendTo("#tabEmps");$("<td/>").text(emp.id).appendTo(tr);$("<td/>").text(emp.name).appendTo(tr);$("<td/>").text(emp.birthday).appendTo(tr);$("<td/>").text(emp.address).appendTo(tr);$("<td/>").text(emp.phone).appendTo(tr);$("<td/>").html("<a>刪除</a>").appendTo(tr);});});},getEmp:function(){return {"id":$("#id").val(),"name":$("#name").val(),"birthday":$("#birthday").val(),"address":$("#address").val(),"phone":$("#phone").val()};},save:function(){var emp=app.getEmp();if(emp.id){app.update(emp);}else{app.add(emp);}},add:function(emp){app.ajax("POST",function (data) {app.binddata();},"",emp);},update:function(emp){app.ajax("Put",function (data) {app.binddata();},"",emp);},info: function (msg) {$(".message")[0].innerHTML += msg + "<br/>";}};app.init(); </script> </body> </html>結果:
2.4.3、刪除用戶
示例:
<!DOCTYPE html> <html> <head><meta charset="UTF-8"/><title>Title</title> </head> <body> <h2>員工管理</h2> <table border="1" width="100%" id="tabEmps"><tr><th>編號</th><th>姓名</th><th>生日</th><th>地址</th><th>電話</th><th>操作</th></tr> </table> <p class="loading" style="display: none;"><img src="img/loading.gif" align="absmiddle">努力加載中... </p> <form id="formEmps"><fieldset><legend>用戶信息</legend><p><label for="name">姓名:</label><input name="name" id="name" type="text" required="required" maxlength="32"/></p><p><label for="birthday">生日:</label><input name="birthday" id="birthday" type="date" required="required" maxlength="8"/></p><p><label for="address">地址:</label><input name="address" id="address" type="text" required="required" maxlength="128"/></p><p><label for="phone">電話:</label><input name="phone" id="phone" type="text" required="required" maxlength="11"/></p><p><input id="id" type="hidden" name="id" value=""/><button type="button" id="btnSubmit">保存</button></p></fieldset> </form> <p class="message"> </p> <script src="js/jquery-1.11.3.min.js"></script> <script>// var data = {// "state": "success",// "data": {"id": 1, "name": "張學友", "birthday": -41500800000, "address": "中國香港", "phone": "18989890098"},// "message": "獲得數據成功!"// }var app = {url: "http://localhost:8080/mvc08/emps",init: function () {$("#btnSubmit").click(app.save);$("#tabEmps").on("click", ".del", app.delete);this.binddata();},ajax: function (actionType, callback, path, data) {$.ajax({url: app.url + (path || ""),contentType: "application/json;charset=utf-8",data: JSON.stringify(data) || "{}",type: actionType || "get",dataType: "json",success: function (data) {if (data && data.state == "success") {app.info(data.message);} else if (data && data.state == "error") {app.info(data.message);} else {app.info(data);}if (callback) {callback(data);}},error: function (XMLHttpRequest, textStatus, errorThrown) {app.info(textStatus + errorThrown);},beforeSend: function () {$(".loading").show(200);},complete: function () {$(".loading").hide(200);}});},binddata: function () {$("#tabEmps tr:gt(0)").remove();this.ajax("get", function (data) {$.each(data.data, function (index, emp) {var tr = $("<tr/>").data("emp", emp).appendTo("#tabEmps");$("<td/>").text(emp.id).appendTo(tr);$("<td/>").text(emp.name).appendTo(tr);$("<td/>").text(emp.birthday).appendTo(tr);$("<td/>").text(emp.address).appendTo(tr);$("<td/>").text(emp.phone).appendTo(tr);$("<td/>").html("<a class='del' href='#'>刪除</a>").appendTo(tr);});});},getEmp: function () {return {"id": $("#id").val(),"name": $("#name").val(),"birthday": $("#birthday").val(),"address": $("#address").val(),"phone": $("#phone").val()};},save: function () {var emp = app.getEmp();if (emp.id) {app.update(emp);} else {app.add(emp);}},add: function (emp) {app.ajax("POST", function (data) {app.binddata();}, "", emp);},update: function (emp) {app.ajax("Put", function (data) {app.binddata();}, "", emp);},delete: function () {if (confirm("刪除嗎?")) {var tr = $(this).closest("tr");var emp = tr.data("emp");app.ajax("DELETE", function (data) {tr.remove();}, "/" + emp.id);}},info: function (msg) {$(".message")[0].innerHTML += msg + "<br/>";}};app.init(); </script> </body> </html>結果:
2.4.4、更新數據
示例:
<!DOCTYPE html> <html> <head><meta charset="UTF-8"/><title>Title</title> </head> <body> <h2>員工管理</h2> <table border="1" width="100%" id="tabEmps"><tr><th>編號</th><th>姓名</th><th>生日</th><th>地址</th><th>電話</th><th>操作</th></tr> </table> <p class="loading" style="display: none;"><img src="img/loading.gif" align="absmiddle">努力加載中... </p> <form id="formEmps"><fieldset><legend>用戶信息</legend><p><label for="name">姓名:</label><input name="name" id="name" type="text" required="required" maxlength="32"/></p><p><label for="birthday">生日:</label><input name="birthday" id="birthday" type="date" required="required" maxlength="8"/></p><p><label for="address">地址:</label><input name="address" id="address" type="text" required="required" maxlength="128"/></p><p><label for="phone">電話:</label><input name="phone" id="phone" type="text" required="required" maxlength="11"/></p><p><input id="id" type="hidden" name="id" value=""/><button type="button" id="btnSubmit">保存</button></p></fieldset> </form> <p class="message"> </p> <script src="js/jquery-1.11.3.min.js"></script> <script>// var data = {// "state": "success",// "data": {"id": 1, "name": "張學友", "birthday": -41500800000, "address": "中國香港", "phone": "18989890098"},// "message": "獲得數據成功!"// }var app = {url: "http://localhost:8080/mvc08/emps",init: function () {$("#btnSubmit").click(app.save);$("#tabEmps").on("click", ".del", app.delete);$("#tabEmps").on("click", ".edit", app.edit);this.binddata();},ajax: function (actionType, callback, path, data) {$.ajax({url: app.url + (path || ""),contentType: "application/json;charset=utf-8",data: JSON.stringify(data) || "{}",type: actionType || "get",dataType: "json",success: function (data) {if (data && data.state == "success") {app.info(data.message);} else if (data && data.state == "error") {app.info(data.message);} else {app.info(data);}if (callback) {callback(data);}},error: function (XMLHttpRequest, textStatus, errorThrown) {app.info(textStatus + errorThrown);},beforeSend: function () {$(".loading").show(200);},complete: function () {$(".loading").hide(200);}});},binddata: function () {$("#tabEmps tr:gt(0)").remove();this.ajax("get", function (data) {$.each(data.data, function (index, emp) {var tr = $("<tr/>").data("emp", emp).appendTo("#tabEmps");$("<td/>").text(emp.id).appendTo(tr);$("<td/>").text(emp.name).appendTo(tr);$("<td/>").text(emp.birthday).appendTo(tr);$("<td/>").text(emp.address).appendTo(tr);$("<td/>").text(emp.phone).appendTo(tr);$("<td/>").html("<a class='del' href='#'>刪除</a> | <a class='edit' href='#'>編輯</a>").appendTo(tr);});});},getEmp: function () {return {"id": $("#id").val(),"name": $("#name").val(),"birthday": $("#birthday").val(),"address": $("#address").val(),"phone": $("#phone").val()};},save: function () {var emp = app.getEmp();if (emp.id) {$("#id").val("");app.update(emp);} else {app.add(emp);}},add: function (emp) {app.ajax("POST", function (data) {app.binddata();}, "", emp);},update: function (emp) {app.ajax("Put", function (data) {app.binddata();}, "", emp);},delete: function () {if (confirm("刪除嗎?")) {var tr = $(this).closest("tr");var emp = tr.data("emp");app.ajax("DELETE", function (data) {tr.remove();}, "/" + emp.id);}},edit:function(){var emp = $(this).closest("tr").data("emp");$("#id").val(emp.id);$("#name").val(emp.name);$("#birthday").val(emp.birthday);$("#address").val(emp.address);$("#phone").val(emp.phone);},info: function (msg) {$(".message")[0].innerHTML += msg + "<br/>";}};app.init(); </script> </body> </html>結果:
三、示例下載
https://git.coding.net/zhangguo5/SpringMVC08.git
四、視頻
https://www.bilibili.com/video/av16991874/
五、作業
5.1、請練習上課示例
5.2、請使用Spring MVC對外提供商品(Product)的管理接口,如:
product/list 獲得所有商品 get
product/1 獲得編號為1的商品 get
product/delete/1 刪除編號為1的商品 get
product/insert 新增商品 post
product/edit 編輯商品 post
使用AJAX調用發布的服務,實現如下功能,驗證、搜索、多刪除功能選作。
5.3、請完成一個前后臺分離的汽車管理系統(CarSystem),需要管理汽車的(車牌、顏色、價格、出廠日期、排量),要求完成CRUD功能,界面美觀大方。
a)、請使用MySQL數據庫創建庫與表(CarSystem)
b)、使用Spring MVC定義5個RESTful服務,注意路徑格式,先用fiddler測試通過。
c)、定義car.html頁面,使用jQuery插件中的ajax功能消費RESTful服務實現功能,反復測試。
六、工具下載
Fiddler2(漢化版)?鏈接: https://pan.baidu.com/s/1mhNTg1M 密碼: qiib
轉載于:https://www.cnblogs.com/liujiandejava/p/9359647.html
總結
以上是生活随笔為你收集整理的Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: scipy的一些函数名
- 下一篇: 小红帽(RedHat)按装