单一拦截器执行流程图
SpringMvc中的拦截器:
a) SpringMvc拦截器帮我们按照一定规则拦截请求,后根据开发人员自定义的拦截逻辑进行处理;
b) 自定义拦截器需要实现HandlerInterceptor接口;
c) 自定义的拦截器实现类需要在SpringMvc配置文件中配置;
d) 可以配置多个拦截器,配置的顺序会影响到拦截器的执行顺序,配置在前的先执行;
e) HandlerInterceptor有3个接口:
i. preHandle 预处理:在拦截方法前执行;
ii. postHandle 后处理:在拦截方法后执行;
iii. afterCompletion 渲染后处理:在页面渲染后执行;
f) 拦截器也体现了AOP思想;
g) 拦截器的应用:权限检查,日志记录,性能检测等;
<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>
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的页面渲染后处理
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";
}
}
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"%>
登录/注册
Login \ Register
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风格开发:一种以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 改 往这个里边放点东西
//使用restFul开发
//查询一个游戏信息,并且显示在内容页
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
我是内容页
页面效果
当点击查询按钮时,页面url跳转到
//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);
}
});
}
//使用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;
}