知识点
1、@RequestMapping注解的使用
2、重定向及转发
3、Springmvc中异常处理
4、图片上传处理
5、Json数据交互
6、Springmvc实现Restful
7、拦截器
1、@RequestMapping注解的使用
- @RequestMapping
在class上添加@RequestMapping(url)指定通用请求前缀, 限制此类下的所有方法请求url必须以请求前缀开头,通过此方法对url进行分类管理。
方法名上边设置请求映射url:@RequestMapping放在方法名上边
http://localhost:8080/springmvc02/items/list.action
2、重定向及转发
在转发情况下,共享request域对象,会将参数从第一个业务控制方法传入第二个业务控制方法,
反之,重定向则不行 (sprigmvc033)
1) edit.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
1 哈哈 7000
<a href="${pageContext.request.contextPath}/emp/find.action?id=1" style="text-decoration:none">编辑</a>
</body>
</html>
2) EmpAction.java
package cn.atcast.controler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping(value="/emp")
public class EmpAction {
@RequestMapping(value="/find")
public String findEmpById(int id,Model model) throws Exception{
System.out.println("查询"+id+"号员工信息");
//转发到EmpAction的另一个方法中去,即再次发送请求
return "forward:/emp/update.action";
//重定向到EmpAction的另一个方法中去,即再次发送请求
//return "redirect:/emp/update.action?id=" + id;
}
@RequestMapping(value="/update")
public String updateEmpById(int id,Model model) throws Exception{
System.out.println("更新" + id +"号员工信息");
model.addAttribute("message","更新员工信息成功");
return "/jsp/ok.jsp";
}
}
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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
<!-- 映射器(框架),可选配置 -->
<!-- BeanNameUrlHandlerMapping表示将bean标签的name属性当作URL请求,即将上面的bean name="/find.action"当作URL请求 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!-- 适配器(框架),可选配置 -->
<!-- SimpleControllerHandlerAdapter用于寻找实现了Controller接口的Action类 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<!-- 视图解析器(框架),可选配置-->
<!-- InternalResourceViewResolver表示通过ModelAndView对象中封装的视图名找到真正的页面 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>
<!-- Action,让springioc容器去扫描带@Controller的类 -->
<context:component-scan base-package="cn.atcast.controler"/>
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
4)ok.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
/ok.jsp<br/>
成功<br/>
${message}<br/>
</body>
</html>
3、Springmvc中异常处理
3.1 异常处理思路
系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。
系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。(springmvc04)
3.2 自定义异常类
为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如
果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。
cn.atcast.exception/CustomerException.java
package cn.atcast.exception;
//自定义异常类,用来处理自定义异常
public class CustomException extends Exception{
//保存异常信息
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
3.3 自定义异常处理器 --全局异常处理
cn.atcast.exception/CustomGlobalExceptionResolver.java
package cn.atcast.exception;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
//自定义全局异常处理---springmvc.xml
public class CustomGlobalExceptionResolver implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
Object arg2, Exception exc) {
//保存异常信息
String msg = "";
//判断异常类型
if(exc instanceof CustomException){
//处理业务级别异常
msg = ((CustomException)exc).getMessage();
} else {
//处理运行时异常
msg = "系统异常, 请及时联系管理员!";
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg", msg);
modelAndView.setViewName("error");
return modelAndView;
}
}
3.4 错误页面
WebRoot/WEB-INF/sp/error.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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>查询商品列表</title>
</head>
<body>
${msg}
</body>
</html>
3.5 异常处理器配置
springmvc.xml
<!-- 配置全局异常处理器 -->
<bean class="cn.atcast.exception.CustomGlobalExceptionResolver"></bean>
3.6 异常测试
cn.atcast.controller/ItemsController.java
public String itemsList(Model model) throws Exception{
//测试运行时异常
//int i= 0/0;
//测试自定义异常
// if(true){
// CustomException customException = new CustomException();
// customException.setMessage("对不起哦, 您已经抢购过, 不要太贪心哦!");
// throw customException;
// }
List<Items> list = itmesService.list();
model.addAttribute("itemList", list);
return "itemList";
}
4、图片上传处理
小心拦截器 拦截图片,小心框架拦截图片
4.1 Springmvc中关于图片显示的问题
testimg.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%=basePath+"/upload/" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'a.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<img src="${pageContext.request.contextPath }/image/test.jpg" />
</body>
</html>
没有springmvc框架可以访问图片,但使用springmvc后无法访问
原因:
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
通过上面url-pattern的配置,所有URL请求都将被Spring MVC的DispatcherServlet截获。
这样的配置,会造成js文件、css文件、图片文件等静态资源无法访问。
解决:
激活Tomcat的defaultServlet来处理静态文件,要配置多个,每种文件配置一个
要写在DispatcherServlet的前面, 让defaultServlet先拦截,这个就不会进入Spring了。
方式一
web.xml
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
方式二
springmvc.xml
<!-- 静态资源访问<mvc:resources> -->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
<mvc:resources location="/image/" mapping="/image/**"/>
4.2 导入jar包
CommonsMultipartResolver解析器依赖commons-fileupload和commons-io,
4.3 商品更新页面
jsp/editItem.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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>修改商品信息</title>
</head>
<body>
<!-- 上传图片是需要指定属性 enctype="multipart/form-data" -->
<form id="itemForm" action="${pageContext.request.contextPath }/items/updateitem"
method="post" enctype="multipart/form-data">
<%-- <form id="itemForm" action="${pageContext.request.contextPath }/items/updateitem.action" method="post"> --%>
<input type="hidden" name="id" value="${item.id }" /> 修改商品信息:
<table width="100%" border=1>
<tr>
<td>商品名称</td>
<td><input type="text" name="name" value="${item.name }" /></td>
</tr>
<tr>
<td>商品价格</td>
<td><input type="text" name="price" value="${item.price }" /></td>
</tr>
<tr>
<td>商品生产日期</td>
<td><input type="text" name="createtime"
value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" /></td>
</tr>
<tr>
<td>商品简介</td>
<td><textarea rows="3" cols="30" name="detail">${item.detail }</textarea>
</td>
</tr>
<tr>
<td>商品图片</td>
<td>
<img style='max-width:68px;width:68px;width:expression(width>68?"68px":width "px");max-width: 68px;'
src="${pageContext.request.contextPath }/image/${item.pic }" />
<input type="file" name="pictureFile"/>
</td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="提交" />
</td>
</tr>
</table>
</form>
</body>
</html>
4.4 配置解析器
springmvc.xml
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为5MB -->
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
4.5 图片上传
//更新商品
@RequestMapping("/updateitem")
public String update(MultipartFile pictureFile, Items items, Model model,
HttpServletRequest request) throws Exception {
// 1. 获取图片完整名称 pictureFile--<input name="pictureFile" type="file"/>
String fileStr = pictureFile.getOriginalFilename();
// 2. 使用随机生成的字符串+源图片扩展名组成新的图片名称,防止图片重名
String newfileName = UUID.randomUUID().toString()+ fileStr.substring(fileStr.lastIndexOf("."));
// 3. 将图片保存到硬盘
// 项目路径
String realPath = request.getSession().getServletContext().getRealPath("/image");
//保存文件的路径
String filePath=realPath+ File.separator +newfileName;//上传路径要指定全路径
pictureFile.transferTo(new File(filePath)); //上传
items.setPic(newfileName);
itmesService.updateItems(items);
//返回显示页面
List<Items> list = itmesService.list();
model.addAttribute("itemList", list);
return "itemList";
}
5、Json数据交互
5.1 @RequestBody
作用:
@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。
List.action?id=1&name=zhangsan&age=12
5.2 @ResponseBody
作用:
该注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数
据如:json,xml等,通过Response响应给客户端
5.3 请求json,响应json实现
5.3.1 环境准备 (springmvc05)
Springmvc默认用MappingJacksonHttpMessageConverter对json数据进行转换,需要加入jackson的包,如下:
5.3.2 配置json转换器
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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
<!-- EmpAction类 -->
<context:component-scan base-package="cn.atcast.controler"/>
<!-- 如果使用<mvc:annotation-driven /> 则不用定义注册适配器。 -->
<mvc:annotation-driven />
<!-- 注册适配器
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</list>
</property>
</bean>
-->
</beans>
5.3.3 测试页面
bean2json.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type="text/javascript" src="js/jquery-1.8.2.js"></script>
</head>
<body>
<input type="button" value="Emp转JSON"/><p>
<input type="button" value="List<Emp>转JSON"/><p>
<input type="button" value="Map<String,Object>转JSON"/><p>
<!-- Emp转JSON -->
<script type="text/javascript">
$(":button:first").click(function(){
var url = "${pageContext.request.contextPath}/emp/bean2json.action";
var sendData = null;
$.post(url,sendData,function(backData,textStaut,ajax){
//alert(ajax.responseText);
var hiredate = backData.hiredate;
var date = new Date(hiredate);
alert(date.getFullYear()+"年"+(date.getMonth()+1)+"月"+(date.getDate())+"日");
});
});
</script>
<!-- List<Emp>转JSON -->
<script type="text/javascript">
$(":button:eq(1)").click(function(){
var url = "${pageContext.request.contextPath}/emp/listbean2json.action";
var sendData = null;
$.post(url,sendData,function(backData,textStaut,ajax){
alert(ajax.responseText);
});
});
</script>
<!-- Map<String,Object>转JSON -->
<script type="text/javascript">
$(":button:last").click(function(){
var url = "${pageContext.request.contextPath}/emp/map2json.action";
var sendData = null; //不发送数据用null
//backData返回的数据 ,textStaut状态码
$.post(url,sendData,function(backData,textStaut,ajax){
alert(ajax.responseText);
});
});
</script>
</body>
</html>
5.3.4 Controler层处理
Emp.java
package cn.atcast.controler;
import java.util.Date;
public class Emp {
private Integer id;
private String username;
private Double salary;
private Date hiredate;
public Emp() {
}
public Emp(Integer id, String username, Double salary, Date hiredate) {
this.id = id;
this.username = username;
this.salary = salary;
this.hiredate = hiredate;
}
}
EmpAction.java
package cn.atcast.controler;
import java.io.IOException;
@Controller
@RequestMapping(value="/emp")
public class EmpAction {
/**
* @ResponseBody Emp 表示让springmvc将Emp对象转成json文本
*/
@RequestMapping(value="/bean2json")
public @ResponseBody Emp bean2json() throws Exception{
//创建Emp对象
Emp emp = new Emp();
emp.setId(1);
emp.setUsername("哈哈");
emp.setSalary(7000D);
emp.setHiredate(new Date());
return emp;
}
@RequestMapping(value="/listbean2json")
public @ResponseBody List<Emp> listbean2json() throws Exception{
//创建List对象
List<Emp> empList = new ArrayList<Emp>();
//向List对象中添加三个Emp对象
empList.add(new Emp(1,"哈哈",7000D,new Date()));
empList.add(new Emp(2,"呵呵",8000D,new Date()));
empList.add(new Emp(3,"嘻嘻",9000D,new Date()));
//返回需要转JSON文本的对象
return empList;
}
@RequestMapping(value="/map2json")
public @ResponseBody Map<String,Object> map2json() throws Exception{
//创建List对象
List<Emp> empList = new ArrayList<Emp>();
//向List对象中添加三个Emp对象
empList.add(new Emp(1,"哈哈",7000D,new Date()));
empList.add(new Emp(2,"呵呵",8000D,new Date()));
empList.add(new Emp(3,"嘻嘻",9000D,new Date()));
//创建Map对象
Map<String,Object> map = new LinkedHashMap<String,Object>();
//向Map对象中绑定二个变量
map.put("total",empList.size());
map.put("rows",empList);
//返回需要转JSON文本的对象
return map;
}
}
5.3.5 Ajax验证
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<script type="text/javascript" src="js/jquery-1.8.2.js"></script>
<script type="text/javascript">
function ajaxTest(){
//alert($("#name").val());
$.ajax({
data:"name="+$("#name").val(),
type:"GET",
dataType: 'json',
url:"${pageContext.request.contextPath}/emp/login.action",
error:function(data){
alert("出错了!!:"+data.msg);
},
success:function(data){
alert("success:"+data.msg);
$("#result").html(data.msg) ;
}
});
}
</script>
<body>
<input type="text" name="name" id="name"/>
<input type="submit" value="登录" onclick="ajaxTest();"/>
<div id="result"></div>
</body>
</html>
EmpAction.java
@RequestMapping(value="/login")
public @ResponseBody Map<String,Object> login(HttpServletRequest request,HttpServletResponse response) throws IOException{
System.out.println(request.getParameter("name"));
Map<String,Object> map = new HashMap<String,Object>();
if(request.getParameter("name").equals("tom")){
System.out.println("成功");
map.put("msg", "成功");
}else{
System.out.println("失败");
map.put("msg", "失败");
}
return map;
}
6、Springmvc实现Restful
6.1 什么是restful?
一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户
端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。(强调以资源为导向)
所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。你可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或独一无二的识别符。
资源定位:互联网所有的事物都是资源,要求url中没有动词,只有名词。没有参数
Url格式:http://blog.csdn.net/beat_the_world/article/details/45621673
(使用restful后,url中不能用?传参或.action)
资源操作:使用delete、post、put、get,使用不同方法对资源进行操作。分别对应添加、删除、修改、查询。一般使用时还是post和get。
客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。
它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。
URI 的设计只要负责把资源通过合理方式暴露出来就可以了。对资源的操作与它无关,操作是通过 HTTP动词来体现,所以REST 通过 URI 暴露资源时,会强调不要在 URI 中出现动词。
比如:左边是错误的设计,而右边是正确的
GET /rest/api/getDogs --> GET /rest/api/dogs 获取所有小狗狗 GET /rest/api/addDogs --> POST /rest/api/dog 添加一个小狗狗
GET /rest/api/editDogs/:dog_id --> PUT /rest/api/dogs/dog_id 修改一个小狗狗
GET /rest/api/deleteDogs/:dog_id --> DELETE /rest/api/dogs/dog_id 删除一个小狗狗
左边的这种设计,很明显不符合REST风格,上面已经说了,URI 只负责准确无误的暴露资源,而 getDogs/addDogs…已经包含了对资源的操作,这是不对的。相反右边却满足了,它的操作是使用标准的HTTP动词来体现。
6.2 需求
RESTful方式实现商品信息查询,返回json数据
6.3 添加DispatcherServlet的rest配置
EmpAction.java
<servlet>
<servlet-name>springMvc</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>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
6.4 修改itemList.jsp为restful风格
itemList.jsp
原来
<td><a href="${pageContext.request.contextPath }/items/itemEdit.action?id=${item.id}">修改</a></td>
restful风格
<td><a href="${pageContext.request.contextPath }/items/itemEdit/${item.id}">修改</a></td>
6.5 URL 模板模式映射
@RequestMapping(value="/itemEdit/{id}"):{×××}占位符,请求的URL可以是“/viewItems/1”或“/viewItems/2”,通过在方法中使用@PathVariable获取{×××}中的×××变量。
@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上。
EmpAction.java
//编辑商品(restful风格)
/*
* 传多个参数
* 页面: <td><a href="${pageContext.request.contextPath }/items/itemEdit/${item.id}/${item.name}">修改</a></td>
* @RequestMapping("/itemEdit/{id}/{name}")
* public String itemEdit(@PathVariable("id") Integer id, @PathVariable("name") String name,HttpServletRequest reuqest,
Model model) throws Exception{
}
*/
@RequestMapping("/itemEdit/{id}")
public String itemEdit(@PathVariable("id") Integer id, HttpServletRequest reuqest,
Model model) throws Exception{
Items items = itmesService.findItemsById(id);
//Model模型:模型中放入了返回给页面的数据
//model底层其实就是用的request域来传递数据,但是对request域进行了扩展.
model.addAttribute("item", items);
//如果springMvc方法返回一个简单的string字符串,那么springMvc就会认为这个字符串就是页面的名称
return "editItem";
}
如果RequestMapping中表示为"/viewItems/{id}",id和形参名称一致,@PathVariable不用指定名称。
6.6 静态资源访问mvc:resources
如果在DispatcherServlet中设置url-pattern为 /则必须对静态资源进行访问处理。
spring mvc 的<mvc:resources mapping="" location="">实现对静态资源进行映射访问。
如下是对js文件访问配置:
springmvc.xml 此方法也可以解决更新时无法访问图片的问题。
<!-- 静态资源访问<mvc:resources> -->
<mvc:resources location="/js/" mapping="/js/**"/>
<mvc:resources location="/image/" mapping="/image/**"/>
7、拦截器
7.1 定义
Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。
7.2 拦截器定义
实现HandlerInterceptor接口,如下:
cn.atcast.interceptor/ Interceptor1.java
package cn.atcast.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class Interceptor1 implements HandlerInterceptor {
//返回布尔值:如果返回true放行,返回false则被拦截住
//执行时机:controller方法没有被执行,ModelAndView没有被返回
//使用场景: 权限验证
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("====Interceptor1=====preHandle======");
return true;
}
//执行时机:Controller方法已经执行,ModelAndView没有返回
//使用场景: 可以在此方法中设置全局的数据处理业务
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("====Interceptor1=====postHandle=====");
}
//执行时机:controller已经执行,modelAndview已经返回
//使用场景: 记录操作日志,记录登录用户的ip,时间等.
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("====Interceptor1====afterCompletion=");
}
}
cn.atcast.interceptor/Interceptor2.java
package cn.atcast.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class Interceptor2 implements HandlerInterceptor {
//返回布尔值:如果返回true放行,返回false则被拦截住
//执行时机:controller方法没有被执行,ModelAndView没有被返回
//使用场景: 权限验证
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("======Interceptor==preHandle========");
return true;
}
//执行时机:Controller方法已经执行,ModelAndView没有返回
//使用场景: 可以在此方法中设置全局的数据处理业务
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("====Interceptor2====postHandle====");
}
//执行时机:controller已经执行,modelAndview已经返回
//使用场景: 记录操作日志,记录登录用户的ip,时间等.
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("====Interceptor2===afterCompletion==");
}
}
7.3 拦截器配置
springMvc.xml
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 多个拦截器的执行顺序等于springMvc.xml中的配置顺序 -->
<mvc:interceptor>
<!-- 拦截请求的路径 要拦截所有必需配置成/** -->
<mvc:mapping path="/**"/>
<!-- 指定拦截器的位置 -->
<bean class="cn.atcast.interceptor.Interceptor1"></bean>
</mvc:interceptor>
<mvc:interceptor>
<!-- 拦截请求的路径 要拦截所有必需配置成/** -->
<mvc:mapping path="/**"/>
<!-- 指定拦截器的位置 -->
<bean class="cn.atcast.interceptor.Interceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
总结:
preHandle按拦截器定义顺序调用
postHandler按拦截器定义逆序调用
afterCompletion按拦截器定义逆序调用
7.4 拦截器应用
7.4.1 处理流程
1、有一个登录页面,需要写一个controller访问页面
2、登录页面有一提交表单的动作。需要在controller中处理。
a) 判断用户名密码是否正确
b) 如果正确向session中写入用户信息
c) 返回登录成功,或者跳转到商品列表
3、拦截器。
a) 拦截用户请求,判断用户是否登录
b) 如果用户已经登录。放行
c) 如果用户未登录,跳转到登录页面。
.
7.4.2 用户身份认证
cn.atcast.interceptor/ LoginInterceptor.java
package cn.atcast.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
//判断当前访问路径是否为登录的路径,如果是则放行
if(request.getRequestURI().indexOf("/login") > 0){
return true;//放行
}
//判断session中是否有登录信息,如果没有则跳转到登录页面,如果有则放行
HttpSession session = request.getSession();
if(session.getAttribute("username") != null){
return true;
}
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}
}
7.4.3 用户登陆controller
cn.atcast.controller/LoginController.java
package cn.atcast.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/login")
public class LoginController {
//跳转到登录页面
@RequestMapping("/login")
public String login() throws Exception{
return "login";
}
@RequestMapping("/submit")
public String submit(String username, String pwd ,HttpServletRequest request) throws Exception{
HttpSession session = request.getSession();
//判断用户名密码的正确性,如果正确则将登录信息放入session中
//这里简写,真正项目中需要去数据库中校验用户名和密码
if(username != null){
session.setAttribute("username", username);
}
//跳转到列表页
return "redirect:/items/list";
}
}
7.4.4 拦截器配置
springMvc.xml
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="cn.atcast.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
大家好,我是凯凯!
大家看完觉得不错 请点个赞呗! 评论一句也可以! 整理不易, 请转发加我的名字哦!
你的支持 使我更有动力!