SSM第三季-SpringMVC-拦截器&静态资源放行&RestFul风格开发

SpringMVC

拦截器

配置拦截器

单一拦截器执行流程图

SSM第三季-SpringMVC-拦截器&静态资源放行&RestFul风格开发_第1张图片

SpringMvc中的拦截器:

a) SpringMvc拦截器帮我们按照一定规则拦截请求,后根据开发人员自定义的拦截逻辑进行处理;

b) 自定义拦截器需要实现HandlerInterceptor接口;

c) 自定义的拦截器实现类需要在SpringMvc配置文件中配置;

d) 可以配置多个拦截器,配置的顺序会影响到拦截器的执行顺序,配置在前的先执行;

e) HandlerInterceptor有3个接口:

​ i. preHandle 预处理:在拦截方法前执行;

​ ii. postHandle 后处理:在拦截方法后执行;

​ iii. afterCompletion 渲染后处理:在页面渲染后执行;

f) 拦截器也体现了AOP思想;

g) 拦截器的应用:权限检查,日志记录,性能检测等;

在applicationContext.xml中配置拦截器

		<mvc:interceptors>
			
		 	<mvc:interceptor>
				<mvc:mapping path="/**"/>
				<bean class="com.sikiedu.interceptor.MyInterceptor1"/>
			mvc:interceptor> 
			
			
			<mvc:interceptor>
				<mvc:mapping path="/**"/>
				<bean class="com.sikiedu.interceptor.MyInterceptor2"/>
			mvc:interceptor> 
			
		mvc:interceptors>

interceptor包

MyInterceptor1.java

package com.sikiedu.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 自定义拦截器1
 */
public class MyInterceptor1 implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		
		System.out.println(" 1 preHandle 预处理 ");
		
		return true;
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println(" 1 postHandle 后处理 ");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println(" 1 afterCompletion 页面渲染后处理 ");
	}
	
}

MyInterceptor2.java

package com.sikiedu.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * 自定义拦截器2
 */
public class MyInterceptor2 implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		
		System.out.println(" 2 preHandle 预处理 ");
		
		return false;//false就中断后续执行了
	}
	
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println(" 2 postHandle 后处理 ");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println(" 2 afterCompletion 页面渲染后处理 ");
	}
	
}

控制台打印

1 preHandle 预处理
2 preHandle 预处理
1 afterCompletion 页面渲染后处理

因为MyInterceptor2.java中的preHandle返回值是false,所以拦截器1预处理跑到拦截器2预处理这里时拦截器2就断开了,然后继续执行拦截器1的页面渲染后处理

使用拦截器完成用户登陆效验&登陆异常处理

在bean包下创建user类

package com.sikiedu.bean;

public class User {
	
	private String username;
	private String password;
	/*get和set方法*/
}

新建自定义异常类

MyLoginException.java

package com.sikiedu.exception;

/**
 * 登录异常处理
 */
public class MyLoginException extends Exception {
	
	private String msg;
	
	private Object obj;
	
	public Object getObj() {
		return obj;
	}

	public String getMsg() {
		return msg;
	}

	public MyLoginException(String msg) {
		super();
		this.msg = msg;
	}
	
	public MyLoginException(Object obj, String msg) {
		super();
		this.msg = msg;
		this.obj = obj;
	}	

}

MyGlobalExceptionHandler.java

package com.sikiedu.exception;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 自定义全局异常处理类
 * 
 */
@ControllerAdvice
public class MyGlobalExceptionHandler {
	//处理自定义异常
	@ExceptionHandler(MyLoginException.class)
	String loginException(MyLoginException e, Model model) {
		
		Object obj = e.getObj();
		if(obj != null)
		{
			model.addAttribute("username", obj.toString());
		}
		
		model.addAttribute("errorMsg", e.getMsg());
		
		//视图名
		return "login_page";	
	}
}

在controller包下新建LoginController类

LoginController.java

package com.sikiedu.controller;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.sikiedu.bean.User;
import com.sikiedu.exception.MyLoginException;

/**
 * 登录
 */
@Controller
@RequestMapping("/login/")
public class LoginController {

	//登录请求 
	
	//登录成功 重定向到列表页
	@RequestMapping(value = "login.do", method= RequestMethod.POST)
	public String login(User u, HttpSession session) throws MyLoginException{
		
		User user = new User();
		user.setUsername("xueleng");
		user.setPassword("123");
		
		if(u.getUsername().equals(user.getUsername())) {
			//用户名正确
			if(u.getPassword().equals(user.getPassword())) {
				session.setAttribute("user", u);
			}
			else {
				//throw new MyLoginException("密码错误");
				throw new  MyLoginException(u.getUsername(), "密码错误");
			}
		}
		else {
			throw new MyLoginException("用户名错误");
		}
		
		//判断用户
		/*if(u != null) {
			session.setAttribute("user", u);
		}*/
		
		//重定向到列表页
		return "redirect:/item/allList.do";
	}
	
	
	//登录失败 前往登录页面
	@RequestMapping(value = "login.do", method= RequestMethod.GET)
	public String login() {
		//前往登录页面
		return "login_page";
	}
	
}

新建一个拦截器

LoginInterceptor.java

package com.sikiedu.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;

/**
 * 登录拦截器
 */
public class LoginInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		
		//获取请求
		String URI = request.getRequestURI();
		
		if(!URI.contains("login")) {
			//不是登录请求 拦截
			Object user = request.getSession().getAttribute("user");
			
			if(user == null) {
				//没有登录 重定向到登录页面 / 请求
				response.sendRedirect(request.getContextPath()+"/login/login.do");
				return false;
			}
		}
		
		return true;
	}

}

配置拦截器

<mvc:interceptors>
			
			<mvc:interceptor>
				<mvc:mapping path="/**"/>
				<bean class="com.sikiedu.interceptor.LoginInterceptor"/>
			mvc:interceptor>
		mvc:interceptors>

登陆页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>


    
        
        登录/注册
        
        

        
        
        
        
        
		

        
        

    
    
        
        

        
    

静态资源放行

a) 在web.xml配置DispatcherServlet的url-pattern以扩展名结尾,例如*.do*.html 等;

b) 在web.xml配置default servlet-mapping的url-pattern,以目录形式和扩展名形式;

  

c) 在springmvc.xml中配置,该方法需要注意以下几点:

		
		<mvc:resources location="/css/" mapping="/css/**"/>
		<mvc:resources location="/fonts/" mapping="/fonts/**"/>
		<mvc:resources location="/js/" mapping="/js/**"/>
		<mvc:resources location="/picture/" mapping="/picture/**"/>

​ i. 需要开启mvc:annotation-driven注解驱动;

		
	

​ ii. 如果配置了拦截器,需要在拦截器中进行过滤,否则会被拦截

			
			
				
				
				
				
				
				
				
				
			

​ iii. 路径名不要打错 ;

RestFul风格开发

RESTful风格开发:一种以URL定位资源的开发风格。使用RESTful开发URL会变得一目了然,更有层次,它不是标准或者协议;

使用RESTful前:

http://127.0.0.1/item/save POST 新增物品
http://127.0.0.1/item/delete GET/POST 删除物品
http://127.0.0.1/item/update POST 修改物品

http://127.0.0.1/item/query.do?id=1 GET 根据id查询物品

使用RESTful后:

http://127.0.0.1/item POST 新增物品
http://127.0.0.1/item/1 DELETE 根据id删除物品
http://127.0.0.1/item PUT 修改物品
http://127.0.0.1/item/1 GET 根据id查询物品

RESTful风格开发对Http协议中的基本方法的使用

POST INSERT 增 邮寄一个新的

DELETE DELETE 删 仍了,不要了

GET SELECT 查 获取一个

PUT UPDATE 改 往这个里边放点东西

使用Springmvc实现RESTful风格开发;

使用物品id当作请求路径,点击按钮,跳转到具体的页面;

在ItemController.java中添加一个方法
//使用restFul开发
	//查询一个游戏信息,并且显示在内容页
	 
新建一个item_info.jsp用于跳转页面测试
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




Insert title here


	

我是内容页

修改主页面部分代码,添加一个input查询按钮用于跳转页面测试

查询

页面效果

SSM第三季-SpringMVC-拦截器&静态资源放行&RestFul风格开发_第2张图片

当点击查询按钮时,页面url跳转到

当使用ajax时,页面不会跳转,需要到ajax回调中处理

修改主页面部分代码,添加一个input查询按钮和函数用于跳转页面测试

查询

//restFul
		function restFul(id) {
			$.ajax({
				type : "get",
				url : "${pageContext.request.contextPath }/item/" + id,
				success : function(data) {
					//window.location="${pageContext.request.contextPath }/item/"+id;
					alert(data.item_name);
				}
			});
		}
修改controller中的方法
//使用restFul开发
	//查询一个游戏信息,并且显示在内容页
	@RequestMapping(value = "{item_id}", method=RequestMethod.GET)
	@ResponseBody
	public ItemInfo restFul(@PathVariable("item_id") String id, Model model) {
		System.out.println("ajax " + id);
		//查询
		ItemInfo item = itemService.selectItemInfoById(id);
		
		model.addAttribute("item", item);
		
		//返回页面
		//return "item_info";
		return item;
	}

你可能感兴趣的:(SSM,SSM-SpringMVC,拦截器,静态资源放行,RestFul风格开发)