1、SpringMVC简介
SpringMVC是目前主流的实现MVC设计模式的企业级开发框架,Spring框架是一个子模块,无需整合开发,开发起来更加方便。
其他语言的MVC框架
struts也是一种MVC框架,也适用于java。
go语言的MVC框架
什么是MVC设计模式?
将应用程序分为Controller Model View 三层,Controller层接收客户端请求,调用Model生成业务数据,传递给View。SpringMVC是对这一套代码的封装,屏蔽了很多的底层代码,开放出了接口,让开发者轻松的基于MVC设计模式的Web开发。
SpringMVC的核心组件
- DispatcherServlet: 前置控制器,使整个流程控制的核心,控制其他组件的执行,进行统一的调度,降低组件的耦合性,相当于总指挥。
- Handler: 处理器,完成具体业务逻辑,相当于Servlet或Action
- HandlerMapping: DispatcherServlet接收到请求之后,通过HandlerMapping将不同的请求映射到不同的Handler。
- HandlerInterceptor: 处理器拦截器,是一个接口,如果需要完成一些拦截请求处理,可以实现该接口。
- HandlerExecutionChain: 处理器执行链,包括Handler和HandlerInterceptor(系统会有一个默认的HandlerInterceptor,如果需要额外设置拦截请求,可以添加拦截器)
- HandlerAdapter: 处理器适配器,Handler执行业务方法之前,需要进行一系列的操作,包括表单数据的验证、数据类型的转换、将表单数据封装到JavaBean等,这些操作都需要HandlerAdapter来完成,开发者只要将注意力集中到业务逻辑处理上,DispatcherServlet通过HandlerAdapater执行不同的Handler。
- ModelAndView:装载了模型数据和视图信息,作为Handler的处理结果,返回给DispatcherServlet。
- ViewResolver:视图解析器,DispatcherServlet通过它将逻辑视图解析为物理视图,最终将渲染结果响应给客户端。
SpringMCV的工作流程
- 客户端请求被DispatcherServlet接收。
- 根据HandlerMapping映射到Handler。
- 生成Handler和HandlerInterceptor。
- Handler和HandlerInterceptor以HandlerExecutionChain的形式一并发给DispatcherServlet。
- DispatcherHandler通过HandlerAdaptor调用Handler的业务方法完成业务逻辑处理。
- Handler返回一个ModelAndView给DispatcherServlet.
- DispatcherServlet将接收来的ModeAandView对象传给视图解析器ViewResoler,将逻辑视图解析为物理视图View.
- ViewResoler返回一个View给DispatcherServlet.
- DispatcherServlet根据View进行视图渲染(将模型数据Model填充到视图View中)
- DispatcherServlet将渲染后的结果返回给客户端。
SpringMVC尽管流程复杂,但是开发简单。大部分组件不需要开发者创建、管理,只需要通过配置文件的方式完成配置即可,真正需要开发者进行开发处理的只有Handler\View.
2、如何使用SpringMVC
创建Maven工程,pom.xml中配置如下:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.11.RELEASE</version>
</dependency>
</dependencies>
在web.xml中配置DispatcherServlet
<servlet>
<servlet-name>dispatcherServlet</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>dispatcherServlet</servlet-name>
<!--dispatcherServlet拦截所有请求,所以这里的url设置为斜杠-->
<url-pattern>/</url-pattern>
</servlet-mapping>
在resoures文件夹中创建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.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>
创建HelloHandler实体类
package com.southwind.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloHandelr(){
@ResquestMapping("/index")
public String index(){
System.out.println("执行了index方法");
return "index";
}
}
SpringMVC注解
- @Controller: 在类定义处添加,将该类交个 IoC 容器来管理(结合 springmvc.xml 的⾃动扫描配置使⽤),同时使其成为⼀个控制器,可以接收客户端请求。
- @RequestMapping:
Spring MVC 通过 @RequestMapping 注解将 URL 请求与业务方法进行映射,在 Handler 的类定义处以及⽅法定义处都可以添加 @RequestMapping ,在类定义处添加,相当于客户端多了⼀层访问路径。
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";
}
}
**
@RequestMapping 相关参数**
- 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";
}
- method:指定请求的 method 类型,GET、POST、PUT、DELET。这里可以使用postman这个软件模拟客户端的请求。
@RequestMapping(value = "/index",method = RequestMethod.GET)
public String index(){
System.out.println("执⾏了index...");
return "index";
}
上述方法表示index方法只能接受GET请求。
- params:指定请求中必须包含某些参数,否则⽆法调⽤该⽅法。
@RequestMapping(value = "/index",method = RequestMethod.GET,params = {"name","id=10"})
public String index(){
System.out.println("执⾏了index...");
return "index";
}
上述代码表示请求中必须包含 name 和 id 两个参数,同时 id 的值必须是 10。此时客户端的请求是:http://localhost:8080/hello/index?name=zhangsan&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 来完成的。
使用javabean绑定参数
Spring MVC 会根据请求参数名和 JavaBean 属性名进⾏⾃动匹配,⾃动为对象填充属性值,同时⽀持及联属性。
这里要解释一下@Data注解,加之前要导入lombok.Data的jar包(在pom.xml中配置即可)。加了之后就不用写带参构造器以及成员变量的GET\SET方法,还有重写了toString()方法。
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;
}
创建register.jsp
<%--
Created by IntelliJ IDEA.
User: ASUS
Date: 2020/2/27
Time: 14:09
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<from action="/hello/save" method="post">
⽤户id:<input type="text" name="id"/><br/>
⽤户名:<input type="text" name="name"/><br/>
⽤户地址:<input type="text" name="address.value"/><br/>
<input type="submit" value="注册"/>
</from>
</body>
</html>
在HelloHandler中添加一个方法
//Spring MVC 会根据请求参数名和 JavaBean 属性名进⾏⾃动匹配,⾃动为对象填充属性值,同时⽀持及联属性。
@RequestMapping(value = "/save" ,method = RequestMethod.POST)
public String save(User user){
System.out.println(user);
return "index";
}
如果出现中⽂乱码问题,只需在 web.xml 添加 Spring MVC ⾃带的过滤器即可。
<!--解决中文乱码问题,在SpringMVC添加自带的过滤器-->
<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>