SpringMVC使用记录

佐手、 提交于 2019-12-09 02:42:34

Spring笔记 下载SpringMVC SpringMVC优势 简单 快速

struts2-filter 一个action对应一个url 用类属性传递参数只能设计为多例 ValueStack OGNL&EL&JSTL
springmvc-servlet 一个controller中的方法对应一个url 可使用单例与多例 ModelAndView EL&JSTL

  • 单例情况下变量放在方法中 每次spring把方法当作模板 每来一个请求就通过该模板创建一个副本 实际运行操作的也是此副本
  • 多例情况下变量可放在方法或类中 每次spring把类当作模板 每来一个请求就通过该模板创建一个副本 实际运行操作的也是此副本
    在这里插入图片描述
    SpringMVC简约流程图
    在这里插入图片描述
    SpringMVC实例
    ①导包
//导入Core Container必需包
spring-beans-4.1.3.RELEASE.jar
spring-context-4.1.3.RELEASE.jar
spring-core-4.1.3.RELEASE.jar
spring-expression-4.1.3.RELEASE.jar
//日志包
commons-logging-1.1.1.jar
//spring aop包
spring-aop-4.1.3.RELEASE.jar
spring-aspects-4.1.3.RELEASE.jar
//web包
spring-web-4.1.3.RELEASE.jar
//springmvc核心包
spring-webmvc-4.1.3.RELEASE.jar

②在web.xml中配置springmvc前端控制器

	<!-- 处理POST提交乱码问题 -->
  <filter>
  	<filter-name>encoding</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>encoding</filter-name>
  	<url-pattern>*.action</url-pattern>
  </filter-mapping>

<!-- 前端控制器 -->
  <servlet>
  	<servlet-name>springmvc</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<!-- 默认找 /WEB-INF/[servlet的名称(springmvc)]-servlet.xml -->
  	<init-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>classpath:springmvc.xml</param-value>
  	</init-param>
  </servlet>

  <servlet-mapping>
  	<servlet-name>springmvc</servlet-name>
  	<!-- 
		/* 拦截所有请求包括后缀jsp js png css等
		*.action *.do 拦截以do action结尾的请求
  		/ 拦截所有请求不包括后缀jsp

  		struts&原生servlet的'/*'为拦截所有请求不包括后缀jsp js png css等
  	 -->
  	<url-pattern>*.action</url-pattern>
  </servlet-mapping>

③创建controller类 即struts中action

@Controller
public class TestController {
	//@RequestMapping("/test/one.action")
	//映射多个路径 '.action'可省略 浏览器访问时需带上
	@RequestMapping({"test/one","test/two"})
	//方法访问修饰符权限为private也可使用
	public ModelAndView test() {
		ModelAndView mav = new ModelAndView();
		User one = new User();
		one.setName("ONE");
		User two = new User();
		two.setName("TWO");
		//类似request.setAttribute(String str, Object obj);
		mav.addObject("one", one);
		mav.addObject("two", two);
		//mav.setViewName("/WEB-INF/jsp/test.jsp");//设置跳转路径
		//在springmvc.xml中配置视图解析器前后缀后可简写成如下
		mav.setViewName("test");//再与xml中的前后缀拼接成跳转路径
		return mav;
	}
}

④创建springmvc配置文件

<?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:p="http://www.springframework.org/schema/p"
	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-4.0.xsd
	http://www.springframework.org/schema/mvc
	http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-4.0.xsd">

<!-- 扫描包以其子包下所有类的注解 @Controler @Service-->
<context:component-scan base-package="com.java"/>

<!-- 默认配置的处理器映射器已过时需要手动配置新的处理器映射器 -->
<!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> -->
<!-- 默认配置的处理器适配器已过时需要手动配置新的处理器适配器 -->
<!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> -->
<!-- 注解驱动 替代以上两个bean配置 -->
<mvc:annotation-driven/>

<!-- 视图解释器 使用前后缀拼接跳转页面路径 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<property name="prefix" value="/WEB-INF/jsp/"/>
	<property name="suffix" value=".jsp"/>
</bean>
</beans>

在WEB-INF/jsp/下创建test.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<p>success</p>
</body>
</html>
浏览器访问 http://localhost:8080/Test/ttest/one.action
Console打印 "Test Struts2" 浏览器显示 "success" -> 测试成功

在这里插入图片描述

  1. 客户端发送请求至前端控制器DispatcherServlet
  2. 前端控制器收到请求调用处理器映射器HandlerMapping(三大组件①)
  3. 处理器映射器根据请求url找到具体的处理器 生成处理器对象及处理器拦截器返回给前端控制器
  4. 前端控制器通过处理器适配器HandlerAdapter(三大组件②)调用处理器Controller
  5. 执行处理器
  6. 处理器执行完成返回ModelAndView
  7. 处理器适配器将ModelAndView返回给前端控制器
  8. 前端控制器将ModelAndView传给视图解析器ViewReslover(三大组件③)
  9. 视图解析器r解析后返回具体View
  10. 前端控制器对View进行渲染视图 将模型数据填充至视图
  11. 前端控制器响应用户

springmvc参数绑定

  1. springmvc 后台封装list 前台可以用数组的方式填写name值
  2. 当然 后台传过来的值 前台也可以使用获取数组的方式取值
Controller返回值类型 说明
ModelAndView 避免使用 设置路径 设置转发数据
String 推荐使用 设置路径 使用Model设置转发数据
void ajax使用 使用request设置路径 设置转发数据

// 使用双花括号语法初始化类 本质为匿名内部类 + 实例化代码块

// 既返回页面也包含json的方式1
return new ModelAndView() {{
	addObject("msg", "home");
	setViewName("home");
}};
// 既返回页面也包含json的方式2
return new ModelAndView("home") {{
	addObject("msg", "home");
}};

// 只返回页面 如上去除addObject方法即可
return new ModelAndView("home");

// 只返回json的方式
return new ModelAndView(new MappingJackson2JsonView()) {{
	addObject("msg", "home");
}};

//查询用户信息后修改用户信息
@Controller
public class TestController {

	@Autowired
	private UserService userService;

	//去修改页面方法 通过id查到user显示在跳转页面中 .action可省略
	@RequestMapping("/test/toEdit.action")
	public String toEdit(HttpServletRequest request,Model model) {
		String id = Integer.parseInt(request.getParameter("id"));
		//String id = Integer.valueOf(request.getParameter("id"));
		User user = userService.selectUserId(id);
		//数据和跳转路径
		model.addAttribute("user", user);//model返回数据模型
		return "user";//跳转到WEB-INF/jsp/user.jsp
	}

	// 限制访问类型为get也可直接使用@GetMapping或@PostMapping 默认默认不限制请求方式
	@GetMapping("/test/toEdit")
	//传入与表单name相同的实例名 springmvc自动获取值 转换值类型
	public String toEdit(Model model, Integer id) {
		User user = userService.selectUserId(id);
		model.addAttribute("user", user);//model返回数据模型
		return "user";//跳转到WEB-INF/jsp/user.jsp
	}

	// 使用枚举限制使用get和post请求方式
	@RequestMapping(value="/test/{id}.toEdit",
		method={RequestMethod.GET,RequestMethod.POST})
	//把请求url的id映射到参数上 @PathParam和@PathVariable作用用法一致
	public String toEdit(Model model, @PathVariable(value="id")Integer id) {
		User user = userService.selectUserId(id);
		model.addAttribute("user", user);//model返回数据模型
		return "user";//跳转到WEB-INF/jsp/user.jsp
	}

	@GetMapping("/test/toEdit")
	/*
	* @RequestParam功能
	* required是否必传参数默认true
	* defalutValue不传参数时使用此值
	* name绑定本次参数的名称 value是name别名 作用相同
	* @QueryParam和@RequestParam作用用法一致 AX-RS提供
	*/
	public String toEdit(Model model,
	//如参数为int或其它基本类型 required=false时 不传值时会赋值为null给int
	@RequestParam(value="id", required=true, defalutValue="1") Integer one) {
		User user = userService.selectUserId(id);
		model.addAttribute("user", user);//model返回数据模型
		return "user";//跳转到WEB-INF/jsp/user.jsp
	}

	@GetMapping("/test/toEdit")
	//实体类映射 表单的name要与实体类的属性对应
	public String toEdit(Model model, User user) {
		model.addAttribute("user", user);//model返回数据模型
		return "user";//跳转到WEB-INF/jsp/user.jsp
	}

	@GetMapping("/test/toEdit")//等同于上一行
	//包装类映射 表单的name要与实体类的属性对应
	/*
	* public class QueryVo {
	* 	private User user;
	* 	//getter setter
	* }
	*/
	/*
	* 使页面参数封装到包装类中 需要在修改表单name属性
	* UserName:<input type="text" name="user.name"/>
	*/
	public String toEdit(Model model, QueryVo vo) {
		model.addAttribute("user", vo.user);//model返回数据模型
		return "user";//跳转到WEB-INF/jsp/user.jsp
	}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户列表</title>
</head>
<body>
	<h3>用户列表</h3>
	<table width="100%" border=1>
	<tr>
		<td>用户名称</td>
		<td>联系方式</td>
		<td>家庭住址</td>
	</tr>
	<c:forEach users="${userList}" var="user">
	<tr>
		<td>${user.name}</td>
		<td>${user.telephone}</td>
		<td>${user.address}</td>
		<!-- 点击修改超链接跳转到修改页面 -->
		<td><a href="${pageContext.request.contextPath}/userEdit.action?id=${user.id}">修改</a></td>
	</tr>
	</c:forEach>
	</table>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>修改用户信息</title>
</head>
<body>
	<h3>修改用户信息</h3>
	<form id="userForm"	action="${pageContext.request.contextPath }/updateuser.action" method="post">
		<!-- 隐藏域保存userid -->
		<input type="hidden" name="id" value="${user.id}"/>
		<table width="100%" border=1>
			<tr>
				<td>用户名称</td>
				<td><input type="text" name="name" value="${user.name}"/></td>
			</tr>
			<tr>
				<td>家庭住址</td>
				<td><input type="text" name="price" value="${user.address}"/></td>
			</tr>
		</table>
	</form>
</body>
</html>

SpringMVC类型转换器(自定义参数绑定)

<?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:p="http://www.springframework.org/schema/p"
	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-4.0.xsd
	http://www.springframework.org/schema/mvc
	http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-4.0.xsd">

<!-- 扫描包以其子包下所有类的注解 @Controler @Service等 -->
<context:component-scan base-package="com.java"/>

<!-- 注解驱动 将bean传递给适配器 -->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>

<!-- 配置Conveter转换器 通过过FactoryBean创建Converter -->
<!-- 使用@RequestMapping的方法参数 会自动将String按自定义格式转换为Date类型 -->
<bean id="conversionServiceFactoryBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
	<!-- 配置 多个转换器-->
	<property name="converters">
		<set>
			<!-- 自定义的转换器 -->
			<bean class="com.java.conversion.TestDateConveter"/>
		</set>
	</property>
</bean>

<!-- 视图解释器 使用前后缀拼接跳转页面路径 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<property name="prefix" value="/WEB-INF/jsp/"/>
	<property name="suffix" value=".jsp"/>
</bean>
</beans>
/* 转换日期类型的数据
 * S : 页面传递过来的类型
 * T : 转换后的类型
 */
public class TestDateConveter implements Converter<String, Date>{

	public Date convert(String source) {
		try {
			if (null != source) {//2019:2-15 00_00-00
				DateFormat df = new SimpleDateFormat("yyyy:MM-dd HH_mm-ss");
				return df.parse(source);
			}
		} catch (Exception e) {
			e.getStackTrace();
		}
		return null;
	}
}

在WEB-INF/jsp/下创建test.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>转换日期</title>
</head>
<body>
<!-- 其他页面已经提交 localhost:8080/Test/time?createtime=Fri+Feb+15+00:00:00+CST 2019 -->
EL表达式转换日期:<fmt:formatDate value="${user.converttime}"
	pattern="yyyy-MM-dd HH:mm:ss"/><!-- 2019-2-15 00:00:00 -->
Converter转换日期:${user.createtime}<!-- 2019:2-15 00_00-00 -->
</body>
@RequestMapping("/time")
public String conversiontest(Requestparam("createtime")Date d, Model model) {
model.addAttribute("converttime", d);
return test;//转发到WEB-INF/jsp/test.jsp
}

数组&集合绑定 文件绑定

<script>
    function deletes() {
		//document.("表单的name值").属性名
		//document.pay.action="test.jsp";
        document.items.action="{:U('${pageContext.request.contextPath }/deletes.action')}";
        document.items.submit();//提交name为item的表单
    }
    function updates() {
        document.items.action = "{:U('${pageContext.request.contextPath }/updates.action')}";
        document.items.submit();
    }
</script>
商品列表
<form name="items" method="post">
<table width="100%" border=1>
<tr>
	<td><input type="checkbox" name="ids" value=""></td>
	<td>商品名称</td>
	<td>商品价格</td>
	<td>生产日期</td>
	<td>商品描述</td>
	<td>操作</td>
</tr>
<c:forEach items="${itemList}" var="item" varStatus="s">
<tr>
	<td><input type="checkbox" name="ids" value="${item.id}"></td>
	<td><input type="text" name="itemsList[${s.index}].name" value="${item.name}"></td>
	<td><input type="text" name="itemsList[${s.index }].price" value="${item.price}"></td>
	<td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
	<td>${item.detail }</td>

	<td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td>
</tr>
</c:forEach>
</table>
<button onclick="deletes()"/>删除</button>
<button onclick="updates()"/>修改</button>
</form>
public class TestController {
	//批量删除 接收数据数组
	/*@RequestMapping(value = "/deletes.action")
	public String deletes(Integer[] ids) {
		itemsService.delete(ids);
		return "success";
	}*/

	@ResponseBody
	@RequestMapping(value = "/deletes.action")
	/*
	* public class QueryVo {
	* 	private Integer[] ids;
	* 	//getter setter
	* }
	*/
	//使页面参数封装到包装类ids中
	public String deletes(QueryVo vo) {
		itemsService.delete(ids);
		return "success";
	}

	//批量修改 接收数据数组的list集合
	//不能直接在形参中传List集合 springmvc不能直接封装List<Items>只能包装成vo封装
	/*
	* public class QueryVo {
	* 	private List<Items> itemsList;
	* 	//getter setter
	* }
	*/
	//使页面参数封装到包装类itemsList中
	@RequestMapping(value = "/updates.action", method = {RequestMethod.POST,RequestMethod.GET})
	public String updates(Model model, QueryVo vo) {
		itemsService.update(vo.getItemsList());
		//避免刷新页面表单重复提交
		return "redirect:/itemEdit.action";
		//return "forward:/item/itemlist.action";
	}
}

异常处理
在这里插入图片描述

public class MessageException extends Exception{
	private String msg;
	public MessageException(String msg) {
		super();
		this.msg = msg;
	}
	public String getMsg() { return msg; }
	public void setMsg(String msg) { this.msg = msg; }
}
public class TestExceptionResolver implements HandlerExceptionResolver{

	public ModelAndView resolveException(HttpServletRequest request, 
	//形参obj运行时为出错的类的方法名 即包名.类名.方法名(参数类全名, 参数类全名)
			HttpServletResponse response, Object obj,
			Exception e) {
		ModelAndView mav = new ModelAndView();
		//判断异常为类型
		if (e instanceof MessageException) {
			MessageException me = (MessageException)e;//预期异常
			mav.addObject("error", me.getMsg());
		} else {
			mav.addObject("error", "未知异常");
		}
		mav.setViewName("error");//发生错误时跳转到WEB-INF/jsp/error.jsp页面
		return mav;
	}
}

springmvc.xml中配置

<!-- 配置异常处理器 -->
<bean class="com.java.exception.TestExceptionResolver"/>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>ERROE PAGE</title>
</head>
<body> 
	${error}
</body>
</html>

json数据交互

//导入spingmvc的json必需包
jackson-annotations-2.4.0.jar
jackson-core-2.4.2.jar
jackson-databind-2.4.2.jar
<script type="text/javascript">
$(function) {
var test='{"name":"leige","age":18}';
	$.ajax({
		url:"${pageContext.request.contextPath }/json.action",//访问地址
		async:true,//是否同步 默认为true异步
		type:"POST",//请求方式
		data:test,//请求内容
		contentType:"application/json;charset=UTF-8"//请求数据格式
		success:function(data) {alert(data.name);},//成功后回调
		error:function() {alert("访问失败");},//失败后回调
		dataType:"json"//响应数据格式
	});
}
<script>

后台代码

//@ResponseBody//该注解放在此处表示此类中所有方法都返回数据而不是跳转页面
//@Controller+@ResponseBody简写为 -> #@RestController
public class TestController {
	/* json数据交互 返回值为void不需要跳转路径
	* java接收的为json格式的字符串返回的也是json格式的字符串
	* @RequestBody(同于@ModelAttribute) 把json的参数封装成Items
	*/
	@RequestMapping(value = "/json.action")
	public void json(@RequestBody Items items, HttpServletResponse response) {
		//System.out.println(items);
		response.getWriter()
			.write("{\"name\":\"" +name+ "\",\"age\":" +age+ "\"}");
	}

	/*
	* 返回值为@ResponseBody Items 则ajax回调时自动封装成json格式的字符串
	* @ResponseBody Items items将json格式字符串转成items对象返回到页面
	*/
	@RequestMapping(value = "/json.action")
	//@ResponseBody//该注解也可放在此处
	public @ResponseBody Items json(@RequestBody Items items) {
		//System.out.println(items);
		return items;
	}

	// 返回前端图片
	@RequestMapping(value = "image_1", produces = MediaType.IMAGE_JPEG_VALUE)
    @ResponseBody
    public byte[] getImage() throws IOException {
        File file = new File("D:/image_1.jpg");
        FileInputStream inputStream = new FileInputStream(file);
        byte[] bytes = new byte[inputStream.available()];
        inputStream.read(bytes, 0, inputStream.available());
        return bytes;
    }

	// 返回前端图片 使用spring api简写
	@RequestMapping(value = "image_2", produces = MediaType.IMAGE_JPEG_VALUE)
    @ResponseBody
    public BufferedImage getImage() throws IOException {
        return ImageIO.read(new FileInputStream(new File("D:/image_2.jpg")));
    }
}

public class TestController {
	//RESTful风格常用注解
	@RequestMapping(value = "/item/{id}.action")
	//@PathVariable Integer id把访问路径中的{id}封装到形参中
	public String json(@PathVariable Integer id) {
		System.out.println(id);
		return "success";
	}
}

拦截器

页面请求->Interceptor方法前->Controller方法->Interceptor方法后->视图解析器->Intercepto页面渲染后

springmvc.xml中配置

<mvc:interceptors>
	<!-- 多个拦截器 -->
	<mvc:interceptor>
		<!-- 拦截所有路径 -->
		<mvc:mapping path="/**"/>
		<!-- 自定义的拦截器类 -->
		<bean class="com.java.interceptor.InterceptorOne"/>
	</mvc:interceptor>
	<!-- 
	<mvc:interceptor>
		<mvc:mapping path="/**"/>
		<bean class="com.java.interceptor.InterceptorTwo"/>
	</mvc:interceptor>
	 -->
</mvc:interceptors>
public class InterceptorOne implements HandlerInterceptor{
	//判断用户是否登陆 未登陆->重定向到登陆页面且不放行 已登陆->放行
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
		System.out.println("方法前 1");
		//url http://localhost:8080/login.action
		//uri /login.action
		String requestURI = request.getRequestURI();
		//判断访问地址是否为'/login' 不为'/login'时进入
		if (!requestURI.contains("/login")) {
			String username = (String) request.getSession().getAttribute("USER_SESSION");
			//判断当前访问用户是否登录 未登录时进入
			if (null == username) {
				//重定向到登陆页面
				response.sendRedirect(request.getContextPath() + "/login.action");
				return false;//不放行
			}
		}
		return true;
	}

	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("方法后 1");
	}

	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("页面渲染后 1");
	}
}
public class InterceptorTwo implements HandlerInterceptor{

	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		System.out.println("方法前 2");
		return true;
	}

	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("方法后 2");
	}

	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("页面渲染后 2");
	}
}
全部放行 方法前1->方法前2->方法后2->方法后1->页面渲染后2->页面渲染后1
放行控制 运行顺序
方法前1不放行 方法前1
方法前2不放行 方法前1->方法前2->页面渲染后1
方法后1不放行 方法前1
方法后2不放行 方法前1->方法前2->页面渲染后1
页面渲染后1不放行 方法前1->方法前2->页面渲染后2->页面渲染后1
页面渲染后2不放行 方法前1->方法前2->页面渲染后1
preHandle方法前 按拦截器定义顺序调用
postHandler方法后 按拦截器定义逆序调用
afterCompletion页面渲染后 按拦截器定义逆序调用

postHandler方法后 在拦截器链内所有拦截器返回成功调用
afterCompletion页面渲染后 只有preHandle返回true才调用
public class TestController {
	//去登陆的页面
	@RequestMapping(value = "/login.action", method = RequestMethod.GET)
	public String login() {
		return "login";
	}

	//登录方法
	@RequestMapping(value = "/login.action", method = RequestMethod.POST)
	public String login(HttpSession httpSession, String username) {
		//假设现在已经登录成功
		httpSession.setAttribute("USER_SESSION", username);
		return "redirect:/item/itemlist.action";
	}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>修改商品信息</title>
</head>
<body> 
<form action="${pageContext.request.contextPath }/login.action" method="post">
	用户名:<input type="text" name="username" value="test">
	<input type="submit" value="提交">
</form>
</body>
</html>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!