REST:Representational State Transfer 资源表现层状态转换

  Resources  资源

  Representation  资源表现层

  State Transfer  状态转换

RESTful的特点:

  • URL传参更加简洁

    传统的URL:http://localhost:7777/test?id=1

    RESTful:http://localhost:7777/test/1

  • 完成不同终端之间的资源共享,RESTful提供了一套规范,不同终端之间只需要遵守该规范,就可以实现数据的交互。

RESTful具体来讲就是4种表现形式,HTTP协议中的四种请求类型(GET、POST、PUT、DELETE)分别对应四种常规操作,CRUD。

  GET  用来获取资源

  POST  用来创建资源

  PUT  用来修改资源

  DELETE用来删除资源

  • 由于form表单不支持PUT、DELETE请求,需要想办法支持。SpringMVC通过添加过滤器的方式来完成这种处理的。

实现原理:

  检测请求参数中是否包含 _method 参数,如果包含则获取该参数的值,判断是哪种操作后完成请求类型的转换,然后继续传递。

示例一:
  1、在 form 表单中添加隐藏域标签, name="_method", value="PUT"/"DELETE"。

  2、在web.xml文件中配置HiddenHttpMethodFilter

  <!-- put/delete请求转换 -->
  <filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  3、编写Controller

package com.sunjian.controller;

import com.sunjian.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author sunjian
 * @date 2020/3/19 8:13
 */
@Controller
@RequestMapping("/rest")
public class RESTController {

    @RequestMapping("/get/{id}")
    @ResponseBody
    public String get(@PathVariable("id") int num){
        System.out.println("GET");
        if(num < 100){
            return "OK";
        }else
            return "没有这个编号的数据";
    }

    @RequestMapping(value = "/post", method = RequestMethod.POST)
    public ModelAndView post(){
        User user = new User();
        user.setId(123);
        user.setName("post");
        user.setAge(55);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("user", user);
        modelAndView.setViewName("show");
        return modelAndView;
    }

    @RequestMapping(value = "/put", method = RequestMethod.PUT)
    @ResponseBody // 返回json格式
    public String put(){
        System.out.println("put");
        return "put";
    }

    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    @ResponseBody
    public String delete(){
        System.out.println("delete");
        return "delete";
    }
}

  4、编写JSP页面

  rest.jsp

<%@page contentType="text/html; charset=UTF-8" language="java" %>
<%@page isELIgnored="false" %> <!-- 是否忽略解析el表达式 -->
<html>
<body>
<form action="/rest/put" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="submit" value="PUT">
</form>
<hr>
<form action="/rest/delete" method="POST">
    <input type="hidden" name="_method" value="DELETE">
    <input type="submit" value="DELETE">
</form>
<hr>
<form action="/rest/get/1" method="GET">
    <input type="submit" value="GET">
</form>
<hr>
<form action="/rest/post" method="POST">
    <input type="submit" value="POST">
</form>
</body>
</html>

  show.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${user}
</body>
</html>

  5、访问jsp页面,提交请求

   

   

  

  

  

 示例二:

  实现课程表的增删改查。

1、实体类

package com.sunjian.entity;

/**
 * @author sunjian
 * @date 2020/3/20 14:28
 */
public class Course {
    private Integer id;
    private String name;
    private Double price;

    public Course(Integer id, String name, Double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    @Override
    public String toString() {
        return "Course{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}

2、编写repository

package com.sunjian.repository;

import com.sunjian.entity.Course;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @author sunjian
 * @date 2020/3/20 14:29
 */
@Repository
public class CourseRepository {
    private static Map<Integer, Course> map;

    static {
        map = new HashMap<>();
        map.put(1, new Course(1, "java", 2000d));
        map.put(2, new Course(2, "python", 3000d));
        map.put(3, new Course(3, "c++", 4000d));
    }

    public void saveOrUpdate(Course course){
        map.put(course.getId(), course);
    }

    public Collection<Course> findAll(){
        return map.values();
    }

    public Course findId(Integer id){
        return map.get(id);
    }

    public void deleteById(Integer id){
        map.remove(id);
    }
}

3、编写controller

package com.sunjian.controller;

import com.sunjian.entity.Course;
import com.sunjian.repository.CourseRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author sunjian
 * @date 2020/3/20 14:34
 */
@Controller
@RequestMapping("/course")
public class CourseController {
    @Autowired
    private CourseRepository courseRepository;

    @PostMapping("/add")
    public String add(Course course){
        courseRepository.saveOrUpdate(course);
        return "redirect:/course/findAll";
    }

    @DeleteMapping("/deleteById/{id}")
    public String deleteById(@PathVariable("id") Integer id){
        courseRepository.deleteById(id);
        return "redirect:/course/findAll";
    }

    @PutMapping("/update")
    public String update(Course course){
        courseRepository.saveOrUpdate(course);
        return "redirect:/course/findAll";
    }

    @GetMapping("/findAll")
    public ModelAndView findAll(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("showCourse");
        modelAndView.addObject("list", courseRepository.findAll());
        return modelAndView;
    }

    @GetMapping("/findById/{id}")
    public ModelAndView findById(@PathVariable("id") Integer id){
        ModelAndView modelAndView = new ModelAndView("updateCourse");
        modelAndView.addObject("course", courseRepository.findId(id));
        return modelAndView;
    }
}

4、配置web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!--中文乱码处理-->
  <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>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- put/delete请求转换 -->
  <filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!--映射-->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!-- js -->
  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
  </servlet-mapping>
  <!-- jpg -->
  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
  </servlet-mapping>
</web-app>

5、配置springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

    <!-- 配置自动扫描 -->
    <context:component-scan base-package="com.sunjian"></context:component-scan>

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!-- 消息转换器 -->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"></bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 自定义数据类型转换器 -->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="com.sunjian.converter.DataConverter">
                    <constructor-arg type="java.lang.String" value="yyyy-MM-dd"></constructor-arg>
                </bean>
                <bean class="com.sunjian.converter.goodsConverter"></bean>
            </list>
        </property>
    </bean>

    <!--文件上传-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 处理文件名中文乱码 -->
        <property name="defaultEncoding" value="utf-8"></property>
        <!-- 多文件上传总⼤小的上限 10M -->
        <property name="maxUploadSize" value="10485760"></property>
        <!-- 单文件大小的上限 1M -->
        <property name="maxUploadSizePerFile" value="1048576"></property>
    </bean>
    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
</beans>

6、编写jsp页面

showCourse.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<table>
    <tr>
        <th>课程ID</th>
        <th>课程名称</th>
        <th>课程价格</th>
        <th>操作</th>
    </tr>
    <c:forEach items="${list}" var="course">
        <tr>
            <td>${course.id}</td>
            <td>${course.name}</td>
            <td>${course.price}</td>
            <td>
                <form action="/course/deleteById/${course.id}" method="post">
                    <input type="hidden" name="_method" value="DELETE"/>
                    <input type="submit" value="删除"/>
                </form>
                <a href="/course/findById/${course.id}">修改</a>
            </td>
        </tr>
    </c:forEach>
</table>
<a href="/addCourse.jsp">添加课程</a>
</body>
</html>

addCourse.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/course/add" method="post">
    课程编号:<input type="text" name="id"/><br/>
    课程名称:<input type="text" name="name"/><br/>
    课程价格:<input type="text" name="price"/><br/>
    <input type="submit" value="添加"/>
</form>
</body>
</html>

updateCourse.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/course/update" method="post">
    课程编号:<input type="text" value="${course.id}" name="id" readonly/><br/>
    课程名称:<input type="text" value="${course.name}" name="name"/><br/>
    课程价格:<input type="text" value="${course.price}" name="price"/><br/>
    <input type="hidden" name="_method" value="PUT"/>
    <input type="submit" value="修改"/>
</form>
</body>
</html>

7、访问页面操作

  

  

  

  

OK.

  

      

  

SpringMVC框架——集成RESTful架构的更多相关文章

  1. 8.springMVC中的RESTful架构风格

    RESTful架构:是一种设计的风格,并不是标准,只是提供了一组设计原则和约束条件,也是目前比较流行的一种互联网软件架构.它结构清晰.符合标准.易于理解.扩展方便,所以正得到越来越多网站的采用. 关于 ...

  2. springMVC 中的restful 架构风格

    RESTful架构 : 是一种设计的风格,并不是标准,只是提供了一组设计原则和约束条件,也是目前比较流行的一种互联网软件架构.它结构清晰.符合标准.易于理解.扩展方便,所以正得到越来越多网站的采用. ...

  3. springMVC框架集成tiles模板

    将tiles模板集成到springMVC框架下,大概流程如下: 1.在配置文件中加入tiles支持 我的servlet配置文件名为spring-mvc.xml.具体配置如下: <?xml ver ...

  4. SpringMVC框架04——RESTful入门

    1.RESTful的基本概念 REST(Representational State Transfer)表述性状态转移,REST并不是一种创新技术,它指的是一组架构约束条件和原则,符合REST的约束条 ...

  5. springMvc框架之Restful风格

    method: @Controller @RequestMapping("/test") public String MyController{ @RequestMapping(& ...

  6. RabittMQ实践(二): RabbitMQ 与spring、springmvc框架集成

    一.RabbitMQ简介 1.1.rabbitMQ的优点(适用范围)1. 基于erlang语言开发具有高可用高并发的优点,适合集群服务器.2. 健壮.稳定.易用.跨平台.支持多种语言.文档齐全.3. ...

  7. Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试 (转)

    环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到下面的代码 LoadModule rewrite_module modules/mod_ ...

  8. Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试

    环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到下面的代码 LoadModule rewrite_module modules/mod_ ...

  9. Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试【转】

    环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到下面的代码 LoadModule rewrite_module modules/mod_ ...

随机推荐

  1. 吴裕雄--天生自然 R语言开发学习:基本统计分析(续三)

    #---------------------------------------------------------------------# # R in Action (2nd ed): Chap ...

  2. Typescript - 变量类型

    原文:TypeScript基本知识点整理 一.number let num1 : number = 20; let num2 : number = 175.5; let a1 : number = I ...

  3. 吴裕雄--天生自然KITTEN编程:掉金币

  4. python基础之文件操作1

    文件操作:os.mknod("test.txt")        创建空文件fp = open("test.txt",w)     直接打开一个文件,如果文件不 ...

  5. 用Express 4和 MongoDB打造Todo List

    本篇文章主要參考自DreamersLab - 用Express和MongoDB寫一個todo list.原文的教學內容是使用Express 3.x版,在這邊做簡單Express 4.12.1的todo ...

  6. GeoMesa-单机搭建

    系统安装 CentOS部署 新建虚拟电脑 类型:Linux 版本:Red Hat(64-bit) 创建虚拟硬盘 [x] 动态分配(磁盘占用较小) [ ] 固定大小(使用起来较快) 安装设置(设置roo ...

  7. array, matrix, list and dataframe

    总结一下"入门3R"(Reading, 'Riting, 'Rrithmetic)中的读和写,不同的数据结构下的读写还是有点区别的. vector 命名 12 month.days ...

  8. 没有admin权限如何免安装使用Node和NPM

    此教程只针对于在windows系统上没有admin权限和软件安装权限,但是又希望能像安装版一样使用Node和NPM的用户. 步骤一: 下载压缩版node 访问https://nodejs.org/en ...

  9. Requests功能整理

    import requests # GET r = requests.get('https://api.github.com/events') # POSTr = requests.post('htt ...

  10. 攻防世界Mobile6 app1 XCTF详解

    XCTF_app1 先安装看看 点击芝麻开门之后会弹出“年轻人不要耍小聪明噢” 这大概就能看懂是点击之后进行判断,那就直接去看JEB,看看判断条件是什么 V1是输入的字符串,V2获取包信息(百度的), ...