一、SpringMVC概述
- Spring 为展现层提供的基于 MVC 设计理念的优秀的 Web 框架,是目前最主流的
MVC 框架之一 。 - Spring3.0之后全面超越 Struts2,成为最优秀的 MVC 框架。
- Spring MVC 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任
何接口。 - 支持REST风格的URL请求。
- 采用了松散耦合可插拔组件结构,比其他MVC框架更据扩展性。
1、搭建SpringMVC的环境
配置好测试需要使用的Tomcat
在工程下自动生成的web.xml文件中配置SpringMVC所需要的前端控制器
<!--SpringMVC前端控制器/核心控制器:DispatcherServlet-->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--给DispatcherServlet配置初始化参数,指定DispatcherServlet的核心配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--
load-on-startup:设置DispatcherServlet在服务器启动时候加载
Servlet创建时机:
1、请求到达以后创建
2、服务器启动即创建
-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--指定请求的匹配-->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
接下来配置springmvc.xml
<!--1、组件扫描-->
<context:component-scan base-package="springmvc"></context:component-scan>
<!--2、视图解析器
工作机制:prefix + 请求处理方法的返回值 + suffix = 物理视图路径
/WEB-INF/views/success.jsp
WEB-INF : 服务器内部路径。不能从浏览器端访问该路径下的资源,但是可以内部转发进行访问。
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
2、入门小程序
/**
* 请求处理器/控制器
*/
@Controller
public class SpringMVCHandler {
/**
* 处理客户端请求:http://localhost:8080/SpringMVC/hello
*
* @RequestMapping : 完成请求与请求方法的映射
*/
@RequestMapping(value = "/hello")
public String handleHello(){
System.out.println("Hello SpringMVC");
return "success"; //通过视图解析器解析得到具体的视图,在转发去往该视图。
}
}
return返回的字符串会自动寻找同名的.jsp文件进行映射,所以我们需要在views视图文件夹下创建映射界面success.jsp文件。
<html>
<head>
<title>Title</title>
</head>
<body>
<h1 align="center">Success</h1>
</body>
</html>
简单描述原理:书写的index.jsp文件在发送请求的时候
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
中的 url-pattern会自动匹配发送过来的请求种类,通过servlet-name找到DispatcherServlet这时会读取springmvc.xml配置文件,进而创建springmvc的容器对象。同时springmvc.xml文件中的组件扫描会扫描@Controller和@RequestMapping注解,进而得到具体请求和请求方法的映射。
千万注意:在书写视图解析器的配置文件时prefix路径的views后面一定要加一个斜杠不然就会报错。
二、SpringMVC入门
1、@RequestMapping注解
<1>、value路径累加
当我们在类名前添加@RequestingMapping注解的时候,它所填的路径名是要加在方法上的@RequestingMapping前面的,然后在index.jsp里面做反射的视乎把路径写全才能做映射。
@Controller
@RequestMapping(value = "/springmvc")
public class SpringmvcHandler {
/**
*@RequestMapping 映射方式
*/
@RequestMapping(value = "/testRequestingMapping")
public String testRequesting(){
return "success";
}
}
<a href="/springmvc/testRequestMapping">Test RequestMapping</a>
<2>、method映射请求
在value后面可以以逗号的形式再写上method
/**
* @RequestMapping method 映射方式
*/
@RequestMapping(value = "/testRequestingMethod", method = RequestMethod.GET)
public String testRequestingMethod(){
return "success";
}
测试使用的是超链接,请求方式是GET,如果写POST就会包405请求方式不支持的错误,因此为了防止错误还可以这样写:
@RequestMapping(value = "/testRequestingMethod", method = {RequestMethod.GET, RequestMethod.POST})
还可以使用按钮的方式:
<form action="/testRequestingMappingMethod" method="post">
<input type="submit" value="POST"/>
</form>
<3>、params映射请求参数
/**
* @RequestMapping 映射请求参数、请求头信息
*
* params 请求参数
* headers 请求头信息
*/
@RequestMapping(value = "/testRequestingParamsAndHeaders", params = {"username", "age"})
public String testRequestingParamsAndHeaders(){
return "success";
}
<a href="/testRequestingParamsAndHeaders?username=tom&age=20">Test RequestMapping Params And Headers</a>
如果需要在提交的时候不含有这个参数,或者参数能等于这个值,可以在参数之前加上一个感叹号。
<4>、headers
@RequestMapping(value = "/testRequestingParamsAndHeaders", params = {"username", "age"},headers = "language")
public String testRequestingParamsAndHeaders(){
return "success";
}
<a href="/testRequestingParamsAndHeaders">Test RequestHeaders</a>
每一个网页中都包含许多Headers信息,爬虫的人很清楚Headers中含有很多的列表信息,所以这也可以成为我们提交信息的一种,当页面中包含Headers的信息才能成功跳转界面。
<5>、RequestMapping映射请求占位符PathVariable注解
带占位符的 URL 是 Spring3.0 新增的功能,该功能在 SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:
URL 中的 {xxx} 占位符可以通过 @PathVariable(“xxx”) 绑定到操作方法的入参中。
@RequestMapping(value = "testPathVariable/{id}/{name}")
public String testPathVariable(@PathVariable("id")String id, @PathVariable("name")String name){
System.out.println(id + " " + name + " forever");
return "success";
}
<a href="testPathVariable/1234/John">Test PathVariable</a>
2、REST
<1>、概述
(1)、URL风格
order/2 HTTP GET :得到 id = 2 的 order
order/2 HTTP DELETE:删除 id = 2的 order
order HTTP PUT:更新order
order HTTP POST:新增 order
(2)、HiddenHttpMethodFilter
浏览器 form 表单只支持 GET 与 POST 请求,而DELETE、PUT 等 method 并不
支持,Spring3.0 添加了一个过滤器,可以将这些请求转换为标准的 http 方法,使
得支持 GET、POST、PUT 与 DELETE 请求。
(3)、HiddenHttpMethodFilter工作机制
<2>、环境搭建
<!--配置REST过滤器 HiddenHttpMethodFilter
将满足转换条件的请求进行转换
1、必须是post请求
2、必须要通过_method能获取到一个请求参数值(要转换成的请求方式)
-->
<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>、四种方法的示例
/**
* REST GET
*/
@RequestMapping(value = "/order/{id}",method = RequestMethod.GET)
public String testRestGET(@PathVariable("id")Integer id){
System.out.println("REST GET :" + id);
return "success";
}
/**
* REST DELETE
*/
@RequestMapping(value = "/order/{id}", method = RequestMethod.DELETE)
public String testRestDELETE(@PathVariable("id")Integer id){
System.out.println("REST DELETE : " + id);
return "success";
}
/**
* REST POST
*/
@RequestMapping(value = "/order", method = RequestMethod.POST)
public String testRestPOST(){
System.out.println("REST POST");
return "success";
}
/**
* REST PUT
*/
@RequestMapping(value = "/order", method = RequestMethod.PUT)
public String testRestPUT(){
System.out.println("REST PUT");
return "success";
}
index.jsp文件中需要书写的:
<%--查询订单号是1001的订单--%>
<a href="order/1001">REST GET</a>
<%--删除订单号是1001的订单--%>
<form action="order/1001" method="post">
<%--隐藏域--%>
<input type="hidden" name="_method" value="delete">
<input type="submit" value="REST DELETE SUBMIT">
</form>
<%--添加一个订单--%>
<form action="order" method="post">
<input type="submit" value="REST POST">
</form>
<%--修改订单--%>
<form action="order" method="post">
<input type="hidden" name="_method" value="put">
<input type="submit" value="REST PUT">
</form>
3、处理请求数据
1)Spring MVC 通过分析处理方法的签名,HTTP请求信息绑定到处理方法的相应人参中。
2)Spring MVC 对控制器处理方法签名的限制是很宽松的,几乎可以按喜欢的任何方式对方法进行签名。
3)必要时可以对方法及方法入参标注相应的注解( @PathVariable 、@RequestParam、@RequestHeader 等)、
4)Spring MVC 框架会将 HTTP 请求的信息绑定到相应的方法入参中,并根据方法的返回值类型做出相应的后续处理。
<1>、@RequestParam
作用:映射请求参数映射到请求处理方法的形参中
<a href="/testRequestParam?username=mary&age=18">Test RequestParam</a>
/**
*@RequestParam 映射请求参数到请求处理方法的形参
* 1、如果请求参数名和形参名字一致,那么@RequestParam可以省略不写
* 2、@RequestParam注解标注的形参必须要赋值,必须要能从请求对象中获取到对应的请求参数
* 可以使用required来设置不是必须的
* 可以使用defaultValue来指定一个默认值取代null
* 客户端的请求:testRequestParam?username=mary&age=18
*/
@RequestMapping(value = "/testRequestParam")
public String testRequestParam(@RequestParam("username")String name, @RequestParam("age")Integer age){
System.out.println(name + " " + age);
return "success";
}
<2>、@RequestHeader
/**
*@RequestHeader 映射请求头信息到请求方法的形参中
*/
@RequestMapping(value = "/testRequestHeaders")
public String testRequestHeader(@RequestHeader("Accept-language")String acceptLanguage){
System.out.println(acceptLanguage);
return "success";
}
<a href="/testRequestHeaders">Test RequestHeader</a>
申请的网页会携带一个Headers请求,对信息进行一次信息筛选一次就可以了,有用法和RequestMapping一样
<3>、@CookieValue
/**
* @CookieValue 映射Cookie信息到请求方法形参中
*/
@RequestMapping(value = "/testCookieValue")
public String testCookieValue(@CookieValue("JSESSIONID")String sessionID){
System.out.println(sessionID);
return "success";
}
申请网页时会自动生成一个JSESSIONID,通过@CookieValue检验
<4>、使用POJO作为参数
1)使用 POJO 对象绑定请求参数值
2)Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。如:dept.deptId、dept.address.tel 等。
/**
* TESTPOJO
*/
@RequestMapping(value = "testPOJO")
public String testPOJO(User user){
System.out.println(user);
return "success";
}
@Controller
public class Address {
private String province;
private String city;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
", city='" + city + '\'' +
'}';
}
}
@Controller
public class User {
private String username;
private String password;
private Integer gender;
private Address address;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", gender=" + gender +
", address=" + address +
'}';
}
}
<form action="testPOJO" method="post">
用户名字:<input type="text" name="username">
<br>
密码:<input type="password" name="password">
<br>
性别: 男:<input type="radio" name="gender" value="1">
女:<input type="radio" name="gender" value="0">
<br>
省份:<input type="text" name="address.province">
<br>
城市:<input type="text" name="address.city">
<br>
<input type="submit" value="注册">
</form>
4、处理响应数据
<1>、ModelAndView
/**
* ModelAndView
* SpringMVC会把ModelAndView中模型数据存放到request域对象中
*/
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
ModelAndView modelAndView = new ModelAndView();
//添加模型数据
modelAndView.addObject("username", "Tom");
//设置视图信息
modelAndView.setViewName("success");
return modelAndView;
}
<a href="/testModelAndView">Test ModelAndView</a>
SpringMVC会将modelAndView中模型数据保存到request域对象中,提交申请用界面将参数展示出来。
<body>
<h1>OK</h1>
username:${requestScope.username}
</body>
<2>、Model
/**
* Module
*/
@RequestMapping("/testModel")
public String testModule(Model model){
model.addAttribute("loginMsg","用户名或者密码错误");
return "success";
}
<3>、Map
/**
* Map
* SpringMVC在调用玩请求处理方法之后,不管方法的返回值是什么类型都会处理成一个ModuleAndView对象
*/
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){
map.put("password", 123456);
return "success";
}