SpringMVC
Spring MVC 是Spring为表现层提供的基于 MVC 设计理念的优秀的 Web 框架。
它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful 编程风格的请求。
一、主要组件
-
DispatcherServlet:这是 Spring MVC 的核心组件,前端控制器。它接收所有的 HTTP 请求,并将请求分发给相应的处理器进行处理。它负责协调各个组件的工作,包括处理器映射、视图解析等。
-
Controllers:控制器负责处理具体的业务逻辑。它们接收用户请求,调用相应的服务层方法,并决定返回给用户的视图。
-
HandlerAdapter:主要功能:使用不同的适配器来执行handler,返回ModelAndView(模型和视图对象);
-
ModelAndView:用于封装处理结果和视图信息。它包含了模型数据和视图名称,以便 DispatcherServlet 将数据传递给视图进行渲染。
-
View Resolvers:视图解析器负责将逻辑视图名称解析为实际的视图对象。例如,将一个字符串形式的视图名称转换为 JSP 文件、Thymeleaf 模板等具体的视图实现。
二、工作流程
1、客户端发送请求给前端控制器(DispatcherServlet)
2、dispatcherServlet接收到请求调用HandlerMapping处理器映射器
3、处理器映射器根据请求的url找对应的处理器,找到并生成处理器对象(handler)返回
4、dispatchServlet将handler传入处理器适配器,使用合适的适配器执行
5、处理器适配器执行handler
6、执行完成最终封装一个ModelAndView(模型和视图)
7、将ModelAndView返回给前端控制器
8、前端控制器将请求的路径交给视图解析器进行解析
9、视图解析器解析完毕后封装一个View对象给dispatcherServlet,此View对象封装了响应参数
10、View对象对其进行渲染
11、响应客户端
三、优势
-
松耦合架构:各个组件之间的耦合度低,易于扩展和维护。可以方便地替换或添加新的组件,而不影响其他部分的代码。
-
强大的表单处理:提供了方便的表单绑定和验证功能,可以轻松地处理用户提交的表单数据。
-
灵活的视图技术支持:支持多种视图技术,如 JSP、Thymeleaf、FreeMarker 等,可以根据项目需求选择合适的视图技术。
-
易于测试:可以方便地对控制器进行单元测试,提高代码的质量和可靠性。
-
集成其他 Spring 功能:由于是 Spring 框架的一部分,可以很容易地与其他 Spring 功能(如事务管理、安全管理等)集成。
SpringMVC环境搭建
创建一个web项目,引入依赖
Maven依赖
<dependencies>
<!--包含Spring环境和SpringMVC环境-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-api</artifactId>
<version>8.5.71</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
</dependencies>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!--spring核心(前端控制器)-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--
拦截规则:
1) `.xxx`:后缀拦截,只要符合这个后缀的请求都会交给SpringMVC
2) `/`: 除了JSP之外,所有的请求都交给SpringMVC管理(包括静态资源)
3) `/*`: 所有的请求都交给SpringMVC管理
-->
<!--只有*.form后缀的请求才会进入springmvc-->
<url-pattern>*.form</url-pattern>
</servlet-mapping>
</web-app>
SpringMVC配置
<?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.xsd">
<context:component-scan base-package="cn.xxx"/>
<!--开启springmvc注解驱动-->
<mvc:annotation-driven/>
</beans>
注意:默认的SpringMVC配置文件放在WEB-INF下,名为{servlet-name}-servlet.xml
{servlet-name}指的是,核心控制器配置的名字
当请求被springmvc处理时,springmvc会去默认路径下加载xxxx-servlet.xml核心配置文件
但是我们在开发中一般都是把配置文件写在classes下的,我们可以在web.xml中设置springmvc配置文件的路径
<!--spring核心(前端控制器)-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置springmvc配置文件的位置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--只有*.form后缀的请求才会进入springmvc-->
<url-pattern>*.form</url-pattern>
</servlet-mapping>
Controller
@Controller
public class HelloController{
// 代表此方法的访问路径为/hello.form
@RequestMapping("/hello.form")
public ModelAndView hello(){
ModelAndView mav=new ModelAndView();
mav.addObject("msg","Hello SpringMVC!");
mav.setViewName("/hello.jsp");
return mav;
}
}
视图
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
System.out.println("JSP脚本渲染了!");
%>
<h1>${msg},欢迎您!</h1>
</body>
</html>
Controller方法返回值
跳转
Controller
@Controller
@RequestMapping("/demo") // 为此Controller命名一个请求路径,以后访问此Controller下的任意方法都需要加上/demo
public class DemoController {
@RequestMapping("/demo01") // 后台请求可以不写.from
public String demo01(){
return "hello";
}
}
访问:http://localhost:8080/demo/demo01.form
客户端请求的URL未发生改变,请求却转到了/demo/hello,说明服务器内部发生跳转;
返回字符串的情况下,SpringMVC默认当做视图进行跳转;
设置视图解析器
通常来说,我们的视图(页面)都是放在某个文件夹进行管理的,并且后缀通常都是固定的,要么是.html或者是.jsp再或者是其他的
因此我们希望可以固定好前缀(存放页面的文件夹名称)和后缀(文件名的后缀)
一般来说,存放页面的目录为WEB-INF下的views文件夹
在dispatcher-servlet.xml中配置InternalResourceViewResolver:
<?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.xsd">
<context:component-scan base-package="cn.xxx"/>
<!--配置视图解析器-->
<mvc:view-resolvers>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置页面统一前缀-->
<property name="prefix" value="/WEB-INF/views/"/>
<!--配置页面统一后缀-->
<property name="suffix" value=".jsp"></property>
</bean>
</mvc:view-resolvers>
<!--开启springmvc注解支持-->
<mvc:annotation-driven/>
</beans>
Controller
@RequestMapping("/demo02")
public String demo02() {
return "index02"; // 自动跳转到 /WEB-INF/views/index02.jsp
}
返回ModelAndView
ModelAndView:翻译过来就是模型和视图的意思,该对象保存了我们我们填充的数据(在request域中)和要跳转的视图地址;
普通视图
通过ModelAndView设置的视图,SpringMVC默认将其跳转到这个视图,并且该视图会经过视图解析的前后缀处理;
Controller
@RequestMapping("/demo03")
public ModelAndView demo03() {
ModelAndView mv=new ModelAndView();
// 跳转到/WEB-INF/views/index03.jsp
mv.setViewName("index03");
mv.addObject("msg","index03~~");
return mv;
}
/WEB-INF/views/index03.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1取出的数据${msg}</h1>
</body>
</html>
RedirectView
RedirectView是一种特殊的视图,SpringMVC会将其重定向到这个视图,并且RedirectView允许携带重定向参数
@RequestMapping("/hello")
public ModelAndView hello() {
RedirectView redirectView = new RedirectView();
// RedirectView不会参与视图解析器的前后缀处理
redirectView.setUrl("/hello.jsp");
redirectView.addStaticAttribute("name","xiaohui");
redirectView.addStaticAttribute("age",20);
//使用RedirectView视图进行重定向
return new ModelAndView(redirectView);
}
hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>name: ${param.name}</h1>
<h1>age: ${param.age}</h1>
</body>
</html>
Tips:params是jsp的内置参数,用于获取请求该JSP所携带的参数;
请求hello.jsp时会将参数携带在URL后面
返回特殊字符串
在返回普通字符串时SpringMVC默认是将其作为视图进行跳转,并且可以收视图解析器的前缀/后缀所控制
但有时我们的某个跳转不需要加上前缀后缀,也就是不需要经过视图解析器
在SpringMVC提供了两个特殊字符串前缀:
-
forwrad:进行页面的跳转,该跳转不经过前缀和后缀处理
-
redirect:进行页面的重定向,该重定向不经过前缀和后缀处理
@RequestMapping("/demo04")
public String demo04() {
return "forward:/index04.jsp"; // 转发到http://localhost:8080/index04.jsp
}
@RequestMapping("/demo05")
public String demo05() {
return "redirect:/index05.jsp"; // 重定向到http://localhost:8080/index05.jsp
}
返回void
SpringMVC把方法的返回值当做视图进行跳转,如果返回void代表的就是不需要提供视图
一般用于ajax请求,只需要响应数据,不需要返回视图
@RequestMapping("/demo06")
public void demo06(HttpServletResponse response) throws IOException { // 接收request和response
// 写出数据给前端
response.getWriter().write("hello springmvc!");
}
Tips:只要是Controller中的方法,都可以自动绑定request、response、session这些servlet的原生api;
数据绑定
SpringMVC里面,所谓的数据绑定就是将请求带过来的表单数据绑定到执行方法的参数变量中
SpringMVC除了能够绑定前端提交过来的数据还可以绑定Servlet的一套API,例如HttpServletRequest和HttpServletResponse
自动绑定的数据类型
-
普通类型:基本数据类型+String+包装类
-
包装数据类型(POJO):包装实体类
-
数组和集合类型:List、Map、Set、数组等数据类型
基本数据类型
Controller
@Controller
@RequestMapping("/demo")
public class DemoController {
@RequestMapping(value = "/demo01") //跳转
public void demo01(Integer id,
String cityName,
Double GDP,
Boolean capital,
HttpServletResponse response
) throws IOException {
response.setContentType("text/html;charset=utf8");
response.getWriter().write("id= " + id + "<hr>");
response.getWriter().write("cityName= " + cityName + "<hr>");
response.getWriter().write("GDP= " + GDP + "<hr>");
response.getWriter().write("capital= " + capital + "<hr>");
}
}
Demo01.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>测试参数类型绑定</h3>
<form action="/demo/demo01.form" method="post">
<input type="text" name="id" placeholder="城市id">
<input type="text" name="cityName" placeholder="城市名称">
<input type="text" name="GDP" placeholder="城市GDP">
<input type="text" name="capital" placeholder="是否省会城市(true/false)">
<input type="submit" value="测试参数类型绑定">
</form>
</body>
</html>
普通实体类
lombok依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class City {
private Integer id; // 城市id
private String cityName; // 城市名称
private Double GDP; // 城市GDP,单位亿元
private Boolean capital; // 是否省会城市
}
Controller
RequestMapping("/demo02")
public void demo02(City city, HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf8");
response.getWriter().write("id= " + city.getId() + "<hr>");
response.getWriter().write("cityName= " + city.getCityName() + "<hr>");
response.getWriter().write("GDP= " + city.getGDP() + "<hr>");
response.getWriter().write("capital= " + city.getCapital() + "<hr>");
}
Demo02.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>测试对象参数绑定</h3>
<form action="/demo/demo02.form" method="post">
<input type="text" name="id" placeholder="城市id">
<input type="text" name="cityName" placeholder="城市名称">
<input type="text" name="GDP" placeholder="城市GDP">
<input type="text" name="capital" placeholder="是否省会城市(true/false)">
<input type="submit" value="测试参数类型绑定">
</form>
<br>
<hr>
</body>
</html>
数组和集合
数组
Controller
@RequestMapping("/demo03")
public void demo03(Integer[] ids, HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf8");
response.getWriter().write(Arrays.toString(ids));
}
Demo03.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>测试数组类型绑定</h3>
<form action="/demo/demo03.form" method="post">
<input type="checkbox" value="1" name="ids">
<input type="checkbox" value="2" name="ids">
<input type="checkbox" value="3" name="ids">
<input type="submit" value="数组类型绑定">
</form>
<br>
<hr>
</body>
</html>
SpringMVC默认不支持集合类型来接收前端参数(我们可以使用@RequestParam注解解决这个问题)
List集合
Controller
@RequestMapping("/demo04")
// public void demo04(@RequestParam List<Integer> ids, HttpServletResponse response) throws IOException {
public void demo04(@RequestParam Set<Integer> ids, HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf8");
response.getWriter().write(ids.toString());
}
Map集合
Controller
@RequestMapping("/demo05")
public void demo05(@RequestParam Map<String,Object> cityMap, HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf8");
response.getWriter().write(cityMap.toString());
}
Demo05.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>测试Map数据绑定</h3>
<hr>
<form action="/demo/demo05.form" method="post">
<input type="text" name="id" placeholder="城市id">
<input type="text" name="cityName" placeholder="城市名称">
<input type="text" name="GDP" placeholder="城市GDP">
<input type="text" name="capital" placeholder="是否省会城市(true/false)">
<input type="submit" value="测试Map数据绑定">
</form>
</body>
</html>
Pojo类型
Pojo包装类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Pojo {
// List<T> 类型
private List<City> cityList;
// List<Map> 类型
private List<Map<String,Object>> cityMapList;
// 对象类型
private City city;
// List<普通> 类型
private List<Integer> ids;
// 数组类型
private String[] cityNames;
}
Controller
@RequestMapping("/demo06")
public void demo06(Pojo pojo, HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf8");
System.out.println(pojo);
response.getWriter().write(pojo.toString());
}
Demo06.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>测试参数类型绑定</h3>
<form action="/demo/demo06.form" method="get">
<h3>数组类型: cityNames</h3>
<input type="checkbox" name="cityNames" value="广州">
<input type="checkbox" name="cityNames" value="佛山">
<input type="checkbox" name="cityNames" value="东莞">
<hr>
<h3>集合类型List cityList </h3>
<input type="text" name="cityList[0].id" placeholder="请输入城市id" value="1">
<input type="text" name="cityList[0].cityName" placeholder="请输入城市名称" value="南宁">
<input type="text" name="cityList[0].GDP" placeholder="请输入城市GDP" value="30000.0D">
<input type="text" name="cityList[0].capital" placeholder="是否省会城市" value="true">
<hr>
<input type="text" name="cityList[1].id" placeholder="请输入城市id" value="2">
<input type="text" name="cityList[1].cityName" placeholder="请输入城市名称" value="柳州">
<input type="text" name="cityList[1].GDP" placeholder="请输入城市GDP" value="20000.0D">
<input type="text" name="cityList[1].capital" placeholder="是否省会城市" value="true">
<hr>
<h3>List(Map) 类型 cityMapList</h3>
<input type="text" name="cityMapList[0]['id']" placeholder="请输入城市id" value="1">
<input type="text" name="cityMapList[0]['cityName']" placeholder="请输入城市名称" value="昆明">
<input type="text" name="cityMapList[0]['GDP']" placeholder="请输入城市GDP" value="30000.0D">
<input type="text" name="cityMapList[0]['capital']" placeholder="是否省会城市" value="true">
<hr>
<input type="text" name="cityMapList[1]['id']" placeholder="请输入城市id" value="2">
<input type="text" name="cityMapList[1]['cityName']" placeholder="请输入城市名称" value="香格里拉">
<input type="text" name="cityMapList[1]['GDP']" placeholder="请输入城市GDP" value="30000.0D">
<input type="text" name="cityMapList[1]['capital']" placeholder="是否省会城市" value="false">
<hr>
<h3>对象类型:City</h3>
<input type="text" name="city.id" placeholder="请输入城市id" value="1">
<input type="text" name="city.cityName" placeholder="请输入城市名称" value="福州">
<input type="text" name="city.GDP" placeholder="请输入城市GDP" value="10000.0D">
<input type="text" name="city.capital" placeholder="是否省会城市" value="true">
<h3>List普通类型:ids</h3>
<input type="text" name="ids" placeholder="请输入城市id" value="1">
<input type="text" name="ids" placeholder="请输入城市id" value="2">
<input type="text" name="ids" placeholder="请输入城市id" value="3">
<input type="submit" value="测试参数类型绑定">
</form>
</body>
</html>
内置参数自动绑定
ServletAPI
-
HttpServletRequest
-
HttpServletResponse
-
HttpSession
SpringMVC在处理一个handler时,会默认准备好request、response、session这些原生的ServletAPI,我们可以直接传递进Handler方法
Controller
@RequestMapping("/demo07")
public void demo07(
HttpServletRequest request,
HttpServletResponse response,
HttpSession session) throws IOException {
session.setAttribute("sessionVal","hello session!");
response.sendRedirect("/hello.jsp");
}
SpringMVC内置对象
-
Model:是一个接口,存储的数据存放在request域
-
ModelMap:是一个类,存储的数据存放在request域
-
ModelAndView:包含数据和视图;
Model和ModelMap默认都是存储了Request请求作用域的数据的对象,这个两个对象的作用是一样,就将数据返回到页面
Controller
@RequestMapping("/demo08")
public String demo08(
Map<String, Object> map,
Model model,
ModelMap modelMap) throws IOException {
map.put("mapMsg", "hello map!");
model.addAttribute("modelMsg", "hello model!");
modelMap.addAttribute("modelMapMsg", "hello modelMap!");
System.out.println(map.getClass()); // BindingAwareModelMap
System.out.println(model.getClass()); // BindingAwareModelMap
System.out.println(modelMap.getClass()); // BindingAwareModelMap
return "forward:/Demo02.jsp";
}
Demo02.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>map-${requestScope.mapMsg}</h1>
<h1>model-${requestScope.modelMsg}</h1>
<h1>modelMap-${requestScope.modelMapMsg}</h1>
</body>
</html>
乱码的处理
我们知道Tomcat在处理Post请求时,中文会出现乱码,我们一般是通过request.setCharacterEncoding(true)来解决Post乱码问题
在SpringMVC中,提供有专门的Filter过滤器来帮我们处理Post请求乱码问题
web.xml
<filter>
<filter-name>characterEncodingFilter</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>
<!--解决response乱码问题-->
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
<!--解决request乱码 问题-->
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<!--拦截所有的请求,统一处理乱码问题-->
<url-pattern>/*</url-pattern>
</filter-mapping>
RESTFUL
REST(英文:Representational State Transfer,即表述性状态传递,简称REST)
RESTful是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。
它主要用于客户端和服务器交互类的软件。
RESTFUL示例
示例 | 请求方式 | 效果 |
---|---|---|
/user/1 | GET | 获取id=1的User |
/user/1 | DELETE | 删除id为1的user |
/user/1 | PUT | 修改user |
/user | POST | 添加user |
请求方式共有七种,其中对应的就是HttpServlet中的七个方法:
Delete、Get、Head、Options、Post、Put、Trance
Tips:目前我们的jsp、html,都只支持get、post。
基于restful风格的url
增(Post)
URL:
http://localhost:8080/user
请求体
{"username":"zhangsan","age":20}
删(Delete)
URL:
http://localhost:8080/user/1
改(Put)
URL:
http://localhost:8080/user/1
请求体
{"username":"lisi","age":30}
查(Get)
URL:
http://localhost:8080/user/1
基于Rest风格的方法
依赖
<dependencies>
<!--包含Spring环境和SpringMVC环境-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-api</artifactId>
<version>8.5.71</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
</dependencies>
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class City {
private Integer id; // 城市id
private String cityName; // 城市名称
private Double GDP; // 城市GDP,单位亿元
private Boolean capital; // 是否省会城市
}
测试代码Controller
@Controller
@RequestMapping("/city")
public class CityController {
//增
@PostMapping
public void save(HttpServletResponse response) throws IOException {
response.getWriter().write("save...");
}
//删
@DeleteMapping("/{id}")
public void delete(@PathVariable Integer id, HttpServletResponse response) throws IOException {
response.getWriter().write("delete...id: " + id);
}
//改
@PutMapping("/{id}")
public void update(@PathVariable Integer id, HttpServletResponse response) throws IOException {
response.getWriter().write("update...id: " + id);
}
//查
@GetMapping("/{id}")
public void findById(@PathVariable Integer id, HttpServletResponse response) throws IOException {
response.getWriter().write("findById...id: " + id);
}
}
注意:restful风格的请求显然与我们之前的.form后置的请求相悖,我们把拦截规则更换为:/
Demo01.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>新增</h3>
<form action="/city" method="post">
<input type="submit">
</form>
<h3>删除</h3>
<form action="/city/1" method="delete">
<input type="submit">
</form>
<h3>修改</h3>
<form action="/city/1" method="put">
<input type="submit">
</form>
<h3>查询</h3>
<form action="/city/1" method="get">
<input type="submit">
</form>
</body>
</html>
配置HiddenHttpMethodFilter
默认情况下,HTML页面中的表单并不支持提交除GET/POST之外的请求,但SpringMVC提供有对应的过滤器来帮我们解决这个问题;
web.xml
<filter>
<filter-name>methodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>methodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Demo01.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>新增</h3>
<form action="/city" method="post">
<input type="submit">
</form>
<h3>删除</h3>
<form action="/city/1" method="post">
<%--建立一个名为_method的一个表单项--%>
<input type="hidden" name="_method" value="delete">
<input type="submit">
</form>
<h3>修改</h3>
<form action="/city/1" method="post">
<input type="hidden" name="_method" value="put">
<input type="submit">
</form>
<h3>查询</h3>
<form action="/city/1" method="get">
<input type="submit">
</form>
</body>
</html>
Restful相关注解
-
@GetMapping:接收get请求
-
@PostMapping:接收post请求
-
@DeleteMapping:接收delete请求
-
@PutMapping:接收put请求