Spring MVC 学习总计(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供劳动)

 很多时候前端都亟待调用后台服务完结互动作效果能,常见的数据沟通格式多是JSON或XML,那里根本教学Spring
MVC为前端提供JSON格式的数码并促成与前台交互。RESTful则是一种软件架构风格、设计风格,而不是正统,只是提供了一组陈设原则和封锁规范。它至关心重视要用以客户端和服务器交互类的软件。基于那么些风格设计的软件能够更简明,更有层次,更便于得以实现缓存等机制。

一、JSON

1.1、概要

JSON(JavaScript Object Notation, JS 对象标记)
是一种轻量级的数据调换格式。它依据 ECMAScript
(w3c制定的js规范)的3个子集,选拔完全部独用立于编制程序语言的文本格式来储存和表示数据。简洁和明晰的层次结构使得
JSON 成为可以的数据沟通语言。
易于人读书和编排,同时也易于机器解析和扭转,并实用地升高网络传输效能。

ECMAScript 1

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

示例:

ECMAScript 2ECMAScript 3

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
<!--[if lte IE 8]>
    <script type="text/javascript" src="//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

结果:

ECMAScript 4

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控制器中添加2个action

    @RequestMapping(value = "/users")
    public ModelAndView users(){
        ModelAndView mav=new ModelAndView(new MappingJackson2JsonView());
        mav.addObject(userService.queryAllUsers());
        return mav;
    }

运维结果:

ECMAScript 5

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")
    @ResponseBody
    public String userJson(){
        ObjectMapper mapper=new ObjectMapper();
        try {
          return  mapper.writeValueAsString(userService.queryAllUsers());
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

结果:

ECMAScript 6

1.肆 、乱码难题

1.4.壹 、方法一在action上申明编码格式

@RequestMapping(path="/json",produces = "application/json;charset=UTF-8")

1.4.② 、方法二修改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.伍 、日期格式化难点

默许日期格式会化为1个数字,是一九六七年7月一日到眼下些天子的微秒数:

ECMAScript 7

杰克逊 暗中认可是转成timestamps形式

1.5.一 、方法一表明字段

在实业字段上应用@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;

结果:

ECMAScript 8

1.5.② 、方法二裁撤timestamps情势

只要只收回则会赢得三个默许的日期格式,效果如下:

ECMAScript 9

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

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

运转结果:

ECMAScript 10

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

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

ECMAScript 11ECMAScript 12

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.⑦ 、数据持久化

上一章的示范中并不曾一向访问数据库,数据以聚众的花样存放在内部存款和储蓄器中,那里运用MySQL将数据存款和储蓄到数据库中。该示例基于第八章的示范,请先熟谙第捌章的剧情《Spring
MVC 学习总计(八)——Spring
MVC概要与环境安排(IDEA+Maven+汤姆cat7+JDK⑧ 、示例与摄像)》

1.7.壹 、成立数据库与表

开启MySQL服务

ECMAScript 13

开拓管理工科具Navicat

ECMAScript 14

创立数据库

ECMAScript 15

ECMAScript 16

新建表

ECMAScript 17

/*
Navicat MySQL Data Transfer

Source Server         : localhostMe
Source Server Version : 50506
Source Host           : localhost:3306
Source Database       : mvcdb

Target Server Type    : MYSQL
Target Server Version : 50506
File Encoding         : 65001

Date: 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.贰 、添加测试数据

 ECMAScript 18

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.③ 、添加数据库驱动修改连接音信

在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.伍 、修改用户业务类

因为系统中有五个类实现了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.陆 、彻底消除Spring MVC 中文乱码

累加用户后发觉有乱码,调节和测试发现发送到服务器的数量已经是乱码

ECMAScript 19

壹 、页面编码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>

贰 、U途锐L中的乱码

改tomcat中server.xml中Connector的port=“8080”,加上贰个ULANDIEncoding=”utf-8”

ECMAScript 20

三 、配置过滤器,钦赐全体请求的编码

修改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>

肆 、文件编码

将文件另存为utf-8格式

五 、数据库编码

接连字符串钦命编码格式

public static String URL="jdbc:mysql://127.0.0.1:3306/mvcdb?useUnicode=true&characterEncoding=UTF-8"

创建数据库时钦赐utf-8编码格式

ECMAScript 21

末了运行结果平常:

ECMAScript 22

二、RESTful

2.1、概要

REST(英文:Representational State
Transfer,简称REST,表述性状态转移)描述了2个框架结构样式的网络种类,比如
web 应用程序。它第二次面世在 3000 年 罗伊 Fielding 的硕士随想中,他是 HTTP
规范的严重性编者之一。在此时此刻主流的三种Web服务交互方案中,REST相比较于SOAP(Simple
Object Access
protocol,容易对象访问协议)以及XML-LX570PC越发简单明了,无论是对U大切诺基L的拍卖恐怕对Payload的编码,REST都援助于用更为简便易行轻量的法子设计和贯彻。值得注意的是REST并没有三个强烈的正统,而更像是一种设计的品格。

ECMAScript 23

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)都有对该约束的实现,使UTiggoL变得进一步有含义,特别简洁,如:

http://www.zhangguo.com/products/1 get请求 表示收获全数成品的第贰个

http://www.zhangguo.com/products/product post请求 表示添加1个产品

http://www.zhangguo.com/products/1/price get请求 表示收获第③个产品的标价

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操作

其余还有:

ECMAScript 24

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

运维结果:

ECMAScript 25

ECMAScript 26

从上边的示范能够看出,使用@RestController后回去的字符串不再是途径,假若回到的是指标则会直接类别化,能够是JSON或XML;尽管回到的是指标类型则一向系列化成JSON格式,请留意添加对Jackson的依靠。

2.③ 、RESTful职员和工人管理示范

一经要为员工(emp)提供对外的REST服务,接口如下:

/emps  get 获得全数的职员和工人信息

/emps/1 get 得到号码为1的职工信息

/emps post 添加

/emps put 修改

/emps/1 delete 删除

2.3.壹 、获得全体的职工消息服务

/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();
    }

}

 结果:

ECMAScript 27

2.3.二 、获得钦命编号的职员和工人信息服务

/emps/1 get 获得号码为1的职工音讯

代码:

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

结果:

ECMAScript 28

2.3.叁 、新增职员和工人服务

/emps post 添加

代码:

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

请求:

ECMAScript 29

返回true

结果:

ECMAScript 30

表达:参数中的json格式一定要运用专业格式,注意引号,注意Content-Type,暗许的Content-Type类型是:application/x-www-form-urlencoded

因为大家应用json,则Content-Type的值应该为application/json;charset=utf-8

2.3.④ 、修改职员和工人服务

/emps  修改 put请求

代码:

    @RequestMapping(path = "", method = RequestMethod.PUT)
    public boolean updateEmp(@RequestBody User user) {
        return userService.editUser(user);
    }

测试:

ECMAScript 31

结果:

ECMAScript 32

2.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(){}
}

测试:

ECMAScript 33

结果:

ECMAScript 34

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

ECMAScript 35

2.四 、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.① 、用户列表

示例:

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

结果:

ECMAScript 36

2.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);
            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>

结果:

ECMAScript 37

2.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);
            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>

结果:

ECMAScript 38

2.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>

结果:

ECMAScript 39

③ 、示例下载

https://git.coding.net/zhangguo5/SpringMVC08.git

四、视频

https://www.bilibili.com/video/av16991874/

五、作业

5.壹 、请练习上课示例

5.2、请使用Spring MVC对外提供商品(Product)的保管接口,如:

product/list 获得全体商品 get

product/1 获得号码为1的货品 get

product/delete/1 删除编号为1的商品 get

product/insert 新增商品 post

product/edit 编辑商品 post

选取AJAX调用发表的服务,达成如下效果,验证、搜索、多删除功效选作。

ECMAScript 40

ECMAScript 41

ECMAScript 42

5.③ 、请实现多少个前后台分离的小车辆管理理种类(CarSystem),必要管住汽车的(车牌、颜色、价格、出厂日期、排量),需要形成CRUD功效,界面雅观大方。

a)、请使用MySQL数据库创造库与表(CarSystem)

ECMAScript,b)、使用Spring
MVC定义5个RESTful服务,注意路径格式,先用fiddler测试通过。

c)、定义car.html页面,使用jQuery插件中的ajax作用消费RESTful服务完毕效益,反复测试。

6、工具下载

Fiddler2(汉化版) 链接: https://pan.baidu.com/s/1mhNTg1M 密码:
qiib