星空网 > 软件开发 > Java

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

 很多时候前端都需要调用后台服务实现交互功能,常见的数据交换格式多是JSON

一、JSON

1.1、概要

JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

在 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'}

示例:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)
<!DOCTYPE html><html> <head>  <meta charset="UTF-8">  <title></title><!--[if lte IE 8]> <script type="text/javascript" src='/images/loading.gif' data-original="http://www.cnblogs.com///res.wx.qq.com/a/wx_fed/webwx/res/json3.min.js"></script> <![endif]--> </head> <body>  <script type="text/javascript">   //js对象   var user = {    "name": "张学友",    "address": "中国香港"   };   //将对象转换成字符   var str = JSON.stringify(user);   alert(str);   //将字符串转换成json对象   var zxy = JSON.parse(str);   alert(zxy.name + "," + zxy.address);  </script> </body></html>
View Code

结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

1.2、使用ModelAndView

修改pom.

  <!-- https://mvnrepository.com/artifact/com.faster-->  <dependency>   <groupId>com.faster</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; }

运行结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

1.3、使用@ResponseBody与Jackson

修改pom.

  <!-- https://mvnrepository.com/artifact/com.faster-->  <dependency>   <groupId>com.faster</groupId>   <artifactId>jackson-databind</artifactId>   <version>2.9.2</version>  </dependency>

添加一个action,使用注解@ResponseBody,响应主体而不是路径

 @RequestMapping(value = "/userJson",produces = "application/json;charset=utf-8") @ResponseBody public String userJson(){  ObjectMapper mapper=new ObjectMapper();  try {   return mapper.writeValueAsString(userService.queryAllUsers());  } catch (JsonProcessingException e) {   e.printStackTrace();  }  return null; }

结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

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日到当前日期的毫秒数:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

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;

结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

1.5.2、方法二取消timestamps形式

如果只取消则会得到一个默认的日期格式,效果如下:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

当然自定义输出格式是允许的

 @RequestMapping(value = "/userJson",produces = "application/json;charset=utf-8") @ResponseBody public 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; }

运行结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

1.6、工具类

工具类可以复用代码,提高开发效率,如上文中的序列化JSON:

package com.zhangguo.springmvc08.utils;import com.fasterimport com.fasterimport com.fasterimport 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") @ResponseBody public String userJson(){  return JsonUtil.getJson(userService.queryAllUsers(),"yyyy-MM-dd"); }

如对MySQL数据库的访问封装:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)
package com.zhangguo.springmvc08.utils; import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.sql.Statement;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class JDBCUtil { public static String DRIVER="com.mysql.jdbc.Driver"; public static String URL="jdbc:mysql://127.0.0.1:3306/schoolmis?useUnicode=true&characterEncoding=UTF-8"; public static String USER_NAME="root"; public static String PASSWORD="pwd"; //加载驱动 static {  try {   Class.forName(DRIVER);  } catch (ClassNotFoundException e) {   e.printStackTrace();  } } private JDBCUtil() { } /**  * 获得连接  *  * @return  */ public static Connection getconnnection() {  Connection con = null;  try {   con = DriverManager.getConnection(URL, USER_NAME, PASSWORD);  } catch (SQLException e) {   e.printStackTrace();  }  return con; } /**  * 关闭连接  *  * @param rs  * @param st  * @param con  */ public static void close(ResultSet rs, Statement st, Connection con) {  try {   try {    if (rs != null) {     rs.close();    }   } finally {    try {     if (st != null) {      st.close();     }    } finally {     if (con != null)      con.close();    }   }  } catch (SQLException e) {   e.printStackTrace();  } } /**  * 关闭连接  *  * @param rs  */ public static void close(ResultSet rs) {  Statement st = null;  Connection con = null;  try {   try {    if (rs != null) {     st = rs.getStatement();     rs.close();    }   } finally {    try {     if (st != null) {      con = st.getConnection();      st.close();     }    } finally {     if (con != null) {      con.close();     }    }   }  } catch (SQLException e) {   e.printStackTrace();  } } /**  * 关闭连接  *  * @param st  * @param con  */ public static void close(Statement st, Connection con) {  try {   try {    if (st != null) {     st.close();    }   } finally {    if (con != null)     con.close();   }  } catch (SQLException e) {   e.printStackTrace();  } } /**  * insert/update/delete  * 增加/更新/删除  *  * @param sql 数据库语句  * @param args 可变参数(可以不带参数,可以带0-n个参数)  * @return  */ public static int update(String sql, Object... args) {  int result = 0;  Connection con = getconnnection();  PreparedStatement ps = null;  try {   ps = con.prepareStatement(sql);   if (args != null) {    for (int i = 0; i < args.length; i++) {     ps.setObject((i + 1), args[i]);    }   }   result = ps.executeUpdate();  } catch (SQLException e) {   e.printStackTrace();  } finally {   close(ps, con);  }  return result; } /**  * query, because need to manually close the resource, so not recommended  * for use it  *  * @param sql  * @param args  * @return ResultSet  */ @Deprecated //注解 public static ResultSet query(String sql, Object... args) {  ResultSet result = null;  Connection con = getconnnection();  PreparedStatement ps = null;  try {   ps = con.prepareStatement(sql);   if (args != null) {    for (int i = 0; i < args.length; i++) {     ps.setObject((i + 1), args[i]);    }   }   result = ps.executeQuery();  } catch (SQLException e) {   e.printStackTrace();  }  return result; } /**  * Query a single record  * 查询单个记录  * @param sql  * @param args  * @return Map<String,Object>  */ public static Map<String, Object> queryForMap(String sql, Object... args) {  Map<String, Object> result = new HashMap<String, Object>();  List<Map<String, Object>> list = queryForList(sql, args);  if (list.size() > 0) {   result = list.get(0);  }  return result; } /**  * Query a single record  * 查询单个记录返回强类型对象  * @param sql  * @param args  * @return <T> //泛型  */ public static <T> T queryForObject(String sql, Class<T> clz, Object... args) {  T result = null;  List<T> list = queryForList(sql, clz, args);  if (list.size() > 0) {   result = list.get(0);  }  return result; } /**  * Query a single record  *  * @param sql  * @param args  * @return List<Map<String,Object>>  */ public static List<Map<String, Object>> queryForList(String sql, Object... args) {  List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();  Connection con = null;  ResultSet rs = null;  PreparedStatement ps = null;  try {   con = getconnnection();   ps = con.prepareStatement(sql);   if (args != null) {    for (int i = 0; i < args.length; i++) {     ps.setObject((i + 1), args[i]);    }   }   rs = ps.executeQuery();   ResultSetMetaData rsmd = rs.getMetaData();   int columnCount = rsmd.getColumnCount();   while (rs.next()) {    Map<String, Object> map = new HashMap<String, Object>();    for (int i = 1; i <= columnCount; i++) {     map.put(rsmd.getColumnLabel(i), rs.getObject(i));    }    result.add(map);   }  } catch (SQLException e) {   e.printStackTrace();  } finally {   close(rs, ps, con);  }  return result; } /**  * Query records  * 查询多个对象,返回强类型集合  * @param sql  * @param args  * @return List<T>  */ public static <T> List<T> queryForList(String sql, Class<T> clz, Object... args) {  List<T> result = new ArrayList<T>();  Connection con = null;  PreparedStatement ps = null;  ResultSet rs = null;  try {   con = getconnnection();   ps = con.prepareStatement(sql);   if (args != null) {    for (int i = 0; i < args.length; i++) {     ps.setObject((i + 1), args[i]);    }   }   rs = ps.executeQuery();   ResultSetMetaData rsmd = rs.getMetaData();   int columnCount = rsmd.getColumnCount();   while (rs.next()) {    T obj = clz.newInstance();    for (int i = 1; i <= columnCount; i++) {     String columnName = rsmd.getColumnName(i);     String methodName = "set" + columnName.substring(0, 1).toUpperCase()       + columnName.substring(1, columnName.length());     Method method[] = clz.getMethods();     for (Method meth : method) {      if (methodName.equals(meth.getName())) {       meth.invoke(obj, rs.getObject(i));      }     }    }    result.add(obj);   }  } catch (InstantiationException e) {   e.printStackTrace();  } catch (IllegalAccessException e) {   e.printStackTrace();  } catch (SQLException e) {   e.printStackTrace();  } catch (IllegalArgumentException e) {   e.printStackTrace();  } catch (InvocationTargetException e) {   e.printStackTrace();  } finally {   close(rs, ps, con);  }  return result; }}
View Code

1.7、数据持久化

上一章的示例中并没有直接访问数据库,数据以集合的形式存放在内存中,这里使用MySQL将数据存储到数据库中。该示例基于第8章的示例,请先熟悉第8章的内容《Spring MVC 学习总结(八)——Spring MVC概要与环境配置(IDEA+Maven+Tomcat7+JDK8、示例与视频)》

1.7.1、创建数据库与表

开启MySQL服务

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

打开管理工具Navicat

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

创建数据库

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

新建表

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

/*Navicat MySQL Data TransferSource Server   : localhostMeSource Server Version : 50506Source Host   : localhost:3306Source Database  : mvcdbTarget Server Type : MYSQLTarget Server Version : 50506File 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、添加测试数据

 Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

insert into user(name,birthday,address,phone)select '张学友','1968-09-08','中国香港','18989890098' unionselect '张惠妹','1969-01-05','中国北京','13345678781' unionselect '张国立',SYSDATE(),'中国珠海','13567453422'select id,name,birthday,address,phone from user;

 

1.7.3、添加数据库驱动修改连接信息

在pom.

  <!--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;/**用户业务*/@Servicepublic 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 中文乱码

添加用户后发现有乱码,调试发现发送到服务器的数据已经是乱码

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(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.

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

3、配置过滤器,指定所有请求的编码

修改web.

 <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编码格式

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

最终运行结果正常:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

二、RESTful

2.1、概要

REST(英文:Representational State Transfer,简称REST,表述性状态转移)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。在目前主流的三种Web服务交互方案中,REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

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
  • 充分利用HTTP谓词(Verb)
  • 侧重数据的传输,业务逻辑交给客户端自行处理

REST是一种分布式服务架构的风格约束,像Java、.Net(WCF、WebAPI)都有对该约束的实现,使URL变得更加有意义,更加简洁明了,如:

post请求 表示添加一个产品

REST设计需要遵循的原则:

  • 网络上的所有事物都被抽象为资源(resource);
  • 每个资源对应一个唯一的资源标识符(resource identifier);
  • 通过通用的连接器接口(generic connector interface)对资源进行操作;
  • 对资源的各种操作不会改变资源标识符;
  • 所有的操作都是无状态的(stateless)

谓词
GET
表示查询操作,相当于Retrieve、Select操作
POST
表示插入操作,相当于Create,Insert操作
PUT
表示修改操作,相当于Update操作
DELETE
表示删除操作,相当于Delete操作

其它还有:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

2.2、@RestController

Spring 4.0重要的一个新的改进是@RestController注解,它继承自@Controller注解。4.0之前的版本,Spring MVC的组件都使用@Controller来标识当前类是一个控制器servlet。

@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Controller@ResponseBodypublic @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.

新增一个控制器,代码如下:

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; }}

运行结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

从上面的示例可以看出,使用@RestController后返回的字符串不再是路径,如果返回的是对象则会直接序列化,可以是JSON或

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 { @Autowired UserService userService; @RequestMapping(path = "", method = RequestMethod.GET) public List<User> getAllemps() {  return userService.queryAllUsers(); }}

 结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

2.3.2、获得指定编号的员工信息服务

/emps/1 get 获得编号为1的员工信息

代码:

 @RequestMapping(path = "/{id}", method = RequestMethod.GET) public User getEmpById(@PathVariable int id) {  return userService.getUserById(id); }

结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

2.3.3、新增员工服务

/emps post 添加

代码:

 @RequestMapping(path = "", method = RequestMethod.POST) public boolean addEmp(@RequestBody User user) {  return userService.addUser(user); }

请求:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

返回true

结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

说明:参数中的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); }

测试:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

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 { @Autowired UserService 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(){}}

测试:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

已删除成功,delete请求不需要正文与get请求类似

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

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 { @Autowired UserService 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='/images/loading.gif' data-original="img/loading.gif" align="absmiddle">努力加载中...</p><p class="message"></p><script src='/images/loading.gif' data-original="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: "",  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 (+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>

结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

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='/images/loading.gif' data-original="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='/images/loading.gif' data-original="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: "",  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 (+ 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>

结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

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='/images/loading.gif' data-original="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='/images/loading.gif' data-original="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: "",  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 (+ 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>

结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

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='/images/loading.gif' data-original="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='/images/loading.gif' data-original="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: "",  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 (+ 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>

结果:

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

三、示例下载

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调用发布的服务,实现如下功能,验证、搜索、多删除功能选作。

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

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

原标题:Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

关键词:JS

JS
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

fba费用美国:https://www.goluckyvip.com/tag/19476.html
fba费用明细:https://www.goluckyvip.com/tag/19477.html
fba费用哪里看:https://www.goluckyvip.com/tag/19478.html
fba费用哪些:https://www.goluckyvip.com/tag/19479.html
返校季营销:https://www.goluckyvip.com/tag/1948.html
fba费用欧洲:https://www.goluckyvip.com/tag/19480.html
在古巴做游轮 古巴旅游项目:https://www.vstour.cn/a/363194.html
西藏旅游攻略自驾游需要多少天 去西藏旅游自驾游要多久时间:https://www.vstour.cn/a/363195.html
相关文章
我的浏览记录
最新相关资讯
海外公司注册 | 跨境电商服务平台 | 深圳旅行社 | 东南亚物流