Spring MVC 是目前主流的实现 MVC 设计模式的企业级开发框架,Spring 框架的一个子模块,无需整合,开发起来更加便捷。
将应用程序分为 Controller、Model、View 三层,Controller 接收客户端请求,调用 Model 生成业务数据,传递给 View。
Spring MVC 就是对这套流程的封装,屏蔽了很多底层代码,开放出接口,让开发者可以更加轻松、便捷地完成基于 MVC 模式的 Web 开发。
Spring MVC 流程非常复杂,实际开发中很简单,因为大部分的组件不需要开发者创建、管理,只需要通过配置文件的方式完成配置即可,真正需要开发者进行处理的只有 Handler 、View。
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.0.11.RELEASEversion>
dependency>
dependencies>
<web-app>
<display-name>Archetype Created Web Applicationdisplay-name>
<servlet>
<servlet-name>dispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>dispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
<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.southwind">context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/">property>
<property name="suffix" value=".jsp">property>
bean>
beans>
package com.southwind.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloHandler {
@RequestMapping("/index")
public String index(){
System.out.println("执行了index...");
return "index";
}
}
Spring MVC 通过 @RequestMapping 注解将 URL 请求与业务方法进行映射,在 Handler 的类定义处以及方法定义处都可以添加 @RequestMapping ,在类定义处添加,相当于客户端多了一层访问路径。
@Controller 在类定义处添加,将该类交个 IoC 容器来管理(结合 springmvc.xml 的自动扫描配置使用),同时使其成为一个控制器,可以接收客户端请求。
package com.southwind.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/hello")
public class HelloHandler {
@RequestMapping("/index")
public String index(){
System.out.println("执行了index...");
return "index";
}
}
1、value:指定 URL 请求的实际地址,是 @RequestMapping 的默认值。
@RequestMapping("/index")
public String index(){
System.out.println("执行了index...");
return "index";
}
等于
@RequestMapping(value="/index")
public String index(){
System.out.println("执行了index...");
return "index";
}
2、method:指定请求的 method 类型,GET、POST、PUT、DELET。
@RequestMapping(value = "/index",method = RequestMethod.GET)
public String index(){
System.out.println("执行了index...");
return "index";
}
上述代码表示 index 方法只能接收 GET 请求。
3、params:指定请求中必须包含某些参数,否则无法调用该方法。
@RequestMapping(value = "/index",method = RequestMethod.GET,params = {
"name","id=10"})
public String index(){
System.out.println("执行了index...");
return "index";
}
上述代码表示请求中必须包含 name 和 id 两个参数,同时 id 的值必须是 10。
关于参数绑定,在形参列表中通过添加 @RequestParam 注解完成 HTTP 请求参数与业务方法形参的映射。
@RequestMapping(value = "/index",method = RequestMethod.GET,params = {
"name","id=10"})
public String index(@RequestParam("name") String str,@RequestParam("id") int age){
System.out.println(str);
System.out.println(age);
System.out.println("执行了index...");
return "index";
}
上述代码表示将请求的参数 name 和 id 分别赋给了形参 str 和 age ,同时自动完成了数据类型转换,将 “10” 转为了 int 类型的 10,再赋给 age,这些工作都是由 HandlerAdapter 来完成的。
Spring MVC 也支持 RESTful 风格的 URL。
传统类型:http://localhost:8080/hello/index?name=zhangsan&id=10
REST:http://localhost:8080/hello/index/zhangsan/10
@RequestMapping("/rest/{name}/{id}")
public String rest(@PathVariable("name") String name,@PathVariable("id") int id){
System.out.println(name);
System.out.println(id);
return "index";
}
通过 @PathVariable 注解完成请求参数与形参的映射。
Spring MVC 通过映射可以直接在业务方法中获取 Cookie 的值。
@RequestMapping("/cookie")
public String cookie(@CookieValue(value = "JSESSIONID") String sessionId){
System.out.println(sessionId);
return "index";
}
Spring MVC 会根据请求参数名和 JavaBean 属性名进行自动匹配,自动为对象填充属性值,同时支持及联属性。
package com.southwind.entity;
import lombok.Data;
@Data
public class Address {
private String value;
}
package com.southwind.entity;
import lombok.Data;
@Data
public class User {
private long id;
private String name;
private Address address;
}
<%--
Created by IntelliJ IDEA.
User: southwind
Date: 2019-03-13
Time: 15:33
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
@RequestMapping(value = "/save",method = RequestMethod.POST)
public String save(User user){
System.out.println(user);
return "index";
}
如果出现中文乱码问题,只需在 web.xml 添加 Spring MVC 自带的过滤器即可。
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
Spring MVC 默认是以转发的形式响应 JSP。
1、转发
@RequestMapping("/forward")
public String forward(){
return "forward:/index.jsp";
// return "index";
}
2、重定向
@RequestMapping("/redirect")
public String redirect(){
return "redirect:/index.jsp";
}
数据绑定:在后端的业务方法中直接获取客户端 HTTP 请求中的参数,将请求参数映射到业务方法的形参中,Spring MVC 中数据绑定的工作是由 HandlerAdapter 来完成的。
@RequestMapping("/baseType")
@ResponseBody
public String baseType(int id){
return id+"";
}
@ResponseBody 表示 Spring MVC 会直接将业务方法的返回值响应给客户端,如果不加 @ResponseBody 注解,Spring MVC 会将业务方法的放回值传递给 DispatcherServlet,再由 DisptacherServlet 调用 ViewResolver 对返回值进行解析,映射到一个 JSP 资源。
@RequestMapping("/packageType")
@ResponseBody
public String packageType(@RequestParam(value = "num",required = false,defaultValue = "0") Integer id){
return id+"";
}
包装类可以接收 null,当 HTTP 请求没有参数时,使用包装类定义形参的数据类型,程序不会抛出异常。
@RequestParam
value = “num”:将 HTTP 请求中名为 num 的参数赋给形参 id。
requried:设置 num 是否为必填项,true 表示必填,false 表示非必填,可省略。
defaultValue = “0”:如果 HTTP 请求中没有 num 参数,默认值为0.
@RestController
@RequestMapping("/data")
public class DataBindHandler {
@RequestMapping("/array")
public String array(String[] name){
String str = Arrays.toString(name);
return str;
}
}
@RestController 表示该控制器会直接将业务方法的返回值响应给客户端,不进行视图解析。
@Controller 表示该控制器的每一个业务方法的返回值都会交给视图解析器进行解析,如果只需要将数据响应给客户端,而不需要进行视图解析,则需要在对应的业务方法定义处添加 @ResponseBody。
@RestController
@RequestMapping("/data")
public class DataBindHandler {
@RequestMapping("/array")
public String array(String[] name){
String str = Arrays.toString(name);
return str;
}
}
等同于
@Controller
@RequestMapping("/data")
public class DataBindHandler {
@RequestMapping("/array")
@ResponseBody
public String array(String[] name){
String str = Arrays.toString(name