目录
一、什么是MVC设计模式?
分为三层1.Controlle(控制层):负责接收并处理请求,响应客户端
2.Model(模型层):用于处理具体的业务逻辑,产生模型数据,业务逻辑
3.View(视图层):将模型数据展示给用户
- ①.客户端向服务端发出请求, 会被Controller层接收。
- ②.Controller层根据请求去调用Model层相应的方法。
- ③④⑤.Model层的方法会对数据库进行增删改查并产生模型数据,将此模型数据传递给View层。
- ⑥.最终由View层进行视图渲染返回给请求的用户
二、什么是SpringMVC
1.是目前最好的实现MVC设计模式的框架,会对整个MVC设计模式进行封装,将很对底层代码进行屏蔽,开发者可以更加方便、快捷的进行开发。
2.是Spring框架的一个后续产品,以SpringIOC为基础,利用容器特性简化配置,相当于Spring框架的一个子模块,与Spring可以很好的结合使用,不需要使用中间层整合。
三、SpringMVC核心组件
- 1.DispatcherServlet:前置控制器,整个流程控制的核心,用来控制其他组件执行,进行统一的调度,降低各个组件的耦合性,相当于一个总指挥。
- 2.Handler:处理器,完成具体业务逻辑。
- 3.HandlerMapping:将请求映射到Handler(根据不同的请求找到对应的Handler)。
- 4.HandlerInterceptor:是一个接口,如果需要进行拦截处理可以实现该接口进行一些处理。
- 5.HandlerExecutionChain:处理器执行链,包含了Handler和HandlerInterceptor两部分,有默认的拦截器,如果要额外添加拦截器可以实现该接口进行添加。
- 6.HandlerAdapter:处理器适配器,前置控制器通过HandlerAdapter执行不同的Handler。
- 7.ModelAndView:装载模型数据和视图信息(是Handler的处理结果)。
- 8.ViewResolver:视图解析器,负责将Handler的处理结果进行渲染返回给客户端。
四、SpringMVC执行流程
- 1.客户端请求被DispatcherServlet接收
- 2.DispatcherServlet将请求映射到Handler
- 3.生成Handler以及HandlerInterceptor
- 4.返回HandlerExecutionChain(将第三部的Handler和HandlerInterceptor返回)
- 5.DispatcherServlet通过HandlerAdapter执行Handler
- 6.返回一个ModelAndView给DispatcherServlet
- 7.DispatcherServlet通过ViewResolver进行解析
- 8.View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。
五、SpringMVC的使用
由于大部分组件由框架提供,开发者只需要通过配置去使用,所以开发者只需要手动编写Handler(业务处理)和View(展示数据)
首先需要导入需要的jar包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xyz</groupId>
<artifactId>SpringmvcTest</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--导入springMVC需要的jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.22.RELEASE</version>
</dependency>
<!--导入servlet相关jar包-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
</project>
①:基于XML配置的开发
1.配置前端控制器
在web.xml文件中进行配置,首先先配置DispatcherServlet并指定配置文件路径,然后通过servlet-mapping进行映射,当访问任意路径时都会转向DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<display-name>Archetype Created Web Application</display-name>
<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>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.编写Handler,需实现Controller接口
public class MyHandler implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView();
//添加模型数据
modelAndView.addObject("name","Tom");
//将数据传到“show"视图中
modelAndView.setViewName("show");
return modelAndView;
}
}
3.配置处理器映射器
在classpath下的springmvc.xml配置文件中配置,当访问/test时会调用上面MyHandler类
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置HandlerMapping,将url请求映射到Handler-->
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<!--配置mapping-->
<property name="mappings">
<props>
<!--配置test请求对应的handler-->
<prop key="/test">testHandler</prop>
</props>
</property>
</bean>
<!--配置handler-->
<bean id="testHandler" class="com.xyz.handler.MyHandler"></bean>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置前缀-->
<property name="prefix" value="/"></property>
<!--配置后缀-->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
4.编写show.jsp
当请求为/test后,进入MyHandler类中进行处理,将数据设置到show视图上,最后由show.jsp返回给请求数据。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${name}
</body>
</html>
②:基于注解配置的开发
1.配置前端控制器
在web.xml文件中进行配置,首先先配置DispatcherServlet并指定配置文件路径,然后通过servlet-mapping进行映射,当访问任意路径时都会转向DispatcherServlet
<!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>
<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>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.配置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/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!--配置自动扫描-->
<context:component-scan base-package="com.xyz.handler"/>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置前缀-->
<property name="prefix" value="/"></property>
<!--配置后缀-->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
3. 编写Handler,须在类上使用@Controller注解,然后在方法上使用@RequestMapping注解将请求与方法对应起来
@Controller
public class AnnotationHandler {
@RequestMapping("/test")
public ModelAndView modelAndViewTest(){
//1.创建ModelAndView对象
ModelAndView modelAndView = new ModelAndView();
//2.填充模型数据
modelAndView.addObject("name","jack");
//3.设置逻辑视图
modelAndView.setViewName("show");
return modelAndView;
}
}
4.编写jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${name}
</body>
</html>
5.测试
对比XML和注解方式,明显注解方式更加的简洁, 那是因为注解方式不需要在配置文件中配置相关的Bean。
③:基于注解配置的开发其他方法
@RequestMapping("/test")
public String ModelTest(Model model){
//1.填充模型数据
model.addAttribute("name","jerry");
//2.设置逻辑视图
return "show";
}
/**
* 业务方法:Map传值,String进行视图解析
*/
@RequestMapping("/MapTest")
public String MapTest(Map<String,String> map){
//填充模型数据
map.put("name","Cat");
//设置逻辑视图
return "show";
}
五、拦截器
Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器必须实现Handlerlnterceptor接口
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o) throws Exception {
return false;
}
@Override
public void postHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
prehandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求request进行处理。如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回true;如果程序员决定不需要再调用其他的组件去处理请求,则返回false。
posthandle():这个方法在业务处理器处理完请求后,但是Dispatcherservlet向客户端返回响应前被调用,在该方法中对用户请求request进行处理。
aftercompletion():这个方法在Dispatcherservlet完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。
拦截器肯定是在特定的地方进行拦截,所以需要在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/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 配置自定义扫描包 -->
<context:component-scan base-package="com.xyz.*"></context:component-scan>
<!-- 拦截器的注册 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/person/*"></mvc:mapping>
<mvc:mapping path="/user/**"></mvc:mapping>
<!--exclude-mapping在所有拦截中进行排除,一般在通配符会有意义。-->
<mvc:exclude-mapping path="/user/updatepwd"></mvc:exclude-mapping>
<mvc:exclude-mapping path="/user/updatebackground/*"></mvc:exclude-mapping>
<bean class="com.xyz.core.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
<!-- 映射物理路径 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>