1. 添加依赖
spring-context spring-webmvc
2. web.xml
配置:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<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>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherServletservlet-name>
<url-pattern>*.dourl-pattern>
servlet-mapping>
web-app>
注意:
load-on-startup
时,前端控制器在启动的时候创建,且控制器类也在启动时创建;如果没有配置,则控制器类在请求到达的时候才创建;
只在当前有效,
是全局有效;
中间不能写/*,可以写/。3. 控制器
/**
* 处理请求的控制器类(相当于servlet)
*/
@Controller // 创建对象加入容器
public class HelloController {
/**
* 处理请求的方法
* 1)请求要来到hello()方法
* @RequestMapping("/hello") 表示当前方法处理的请求路径,举例:http://localhost:8080/hello.do
* 2)处理完请求后,需要跳转
* 跳转的路径:http://localhost:8080/pages/success.jsp
*/
@RequestMapping("/hello")
public String hello(){
System.out.println("处理请求开始。。。。。");
// 返回的就是跳转后的文件的名称
// 路径缺少前缀: /pages/ 路径缺少后缀: .jsp
// 前缀与后缀在springMVC.xml中指定。
return "success";
}
}
4. springmvc.xml
<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="com.itheima"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/"/>
<property name="suffix" value=".jsp"/>
bean>
<mvc:annotation-driven/>
beans>
5. 测试
访问地址:http://localhost:8080/hello.do
6. 小结:
2. 项目执行过程时序图
3. 执行流程
1)服务器启动,应用被加载,读取到 web.xml 中的配置创建 spring 容器并且初始化容器中的对象;
2)浏览器发送请求,被 DispatherServlet 捕获,该 Servlet 并不处理请求,而是把请求转发出去。转发的路径是根据请求 URL匹配@RequestMapping 中的内容;
3)匹配后,执行对应方法,该方法有一个返回值;
4)根据方法的返回值,借助 InternalResourceViewResolver
找到对应的结果视图。
SpringMVC框架 – 请求参数的获取方式
SpringMVC – 常用注解标签详解
1. 过滤器
依赖于servlet容器,在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码、在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。
2. 拦截器
依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。谈到拦截器,不得不提拦截器链( Interceptor Chain)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
3. 相同点和区别
都能对请求进行拦截,但是过滤器在url-pattern
中配置/*
能够拦截所有请求,拦截器只会拦截访问的控制器方法,如果访问的是 jsp, html,css,image或者js
是不会进行拦截的;
在请求之前都能做一些工作,请求处理完毕后,也能做一些后续功能;
过滤器是servlet规范中的一部分,任何JavaWeb先项目都能使用,拦截器依赖于SpringMVC框架,只有使用了SpringMVC框架的工程才能用。
4. 多个自定义拦截器的执行步骤
第一步:编写控制器
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/find")
public String find(Model model) {
//int i = 1 / 0;
System.out.println("2.find...");
return "success";
}
}
第二步:编写类实现 HandlerInterceptor 接口
编写拦截器HandlerInterceptorDemo:
public class HandlerInterceptorDemo implements HandlerInterceptor {
// 在请求进入控制器方法之前,先执行这里。(如果配置了拦截器,这里肯定执行)
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("1.HandlerInterceptorDemo.preHandle()");
// 返回true相当于放行;false不放行
return true;
}
/**
* 1. preHandle()必须返回为true时候这里才可能执行。
* 2. 执行完控制器方法,且没有异常时候,再执行这里
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("3.HandlerInterceptorDemo.postHandler()");
}
/**
* 1.preHandle()必须返回为true时候这里才能执行。
* 2.无论控制器方法有没有异常,这里都会执行。(finally)
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println("4.最后执行HandlerInterceptorDemo.afterCompletion()");
}
}
编写拦截器HandlerInterceptorDemo2:
public class HandlerInterceptorDemo2 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("1.HandlerInterceptorDemo2.preHandle()");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("3.HandlerInterceptorDemo2.postHandler()");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println("4.最后执行HandlerInterceptorDemo2.afterCompletion()");
}
}
第三步:配置拦截器
<context:component-scan base-package="com.zz" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/pages/"/>
<property name="suffix" value=".jsp" />
bean>
<mvc:annotation-driven />
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.zz.controller.HandlerInterceptorDemo"/>
mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.zz.controller.HandlerInterceptorDemo2"/>
mvc:interceptor>
mvc:interceptors>