Springmvc框架---知识点(03)实训 2019/10/31

知识点
1、@RequestMapping注解的使用
2、重定向及转发
3、Springmvc中异常处理
4、图片上传处理
5、Json数据交互
6、Springmvc实现Restful
7、拦截器


1、@RequestMapping注解的使用

  1. @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
    &nbsp;&nbsp;&nbsp;&nbsp;
    <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>

大家好,我是凯凯!

大家看完觉得不错 请点个赞呗! 评论一句也可以! 整理不易, 请转发加我的名字哦!

你的支持 使我更有动力!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值