Spring MVC拦截器流程图:
第一步:在springmvc.xml里面配置拦截器
<mvc:interceptors>
<!-- 定义在这里的,所有的都会拦截-->
<mvc:interceptor>
<!--manage/a.do /manage/*-->
<!--manage/b.do /manage/*-->
<!--manage/product/save.do /manage/**-->
<!--manage/order/detail.do /manage/**-->
<mvc:mapping path="/manage/**"/>
<!--<mvc:exclude-mapping path="/manage/user/login.do"/>-->
<bean class="com.mmall.controller.common.interceptor.AuthorityInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
第二步:在controller包下的common包里面书写AuthorityInterceptor类并实现HandlerInterceptor类
package com.mmall.controller.common.interceptor;
import com.google.common.collect.Maps;
import com.mmall.common.Const;
import com.mmall.common.ServerResponse;
import com.mmall.pojo.User;
import com.mmall.util.CookieUtil;
import com.mmall.util.JsonUtil;
import com.mmall.util.RedisShardedPoolUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
@Slf4j
public class AuthorityInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
log.info("preHandle");
//获得请求Controller的方法名
HandlerMethod handlerMethod=(HandlerMethod) handler;
//解析HandleMethod
String methodName=handlerMethod.getMethod().getName();
String className=handlerMethod.getBean().getClass().getSimpleName();
//解析参数,具体的参数key及value是什么,打印日志
StringBuffer requestParamBuffer = new StringBuffer();
//
Map paramMap=httpServletRequest.getParameterMap();
//map.entrySet()是把HashMap类型的数据转换成集合类型
//map.entrySet().iterator()是去获得这个集合的迭代器,保存在iterator里面
Iterator it=paramMap.entrySet().iterator();
while(it.hasNext()){
Map.Entry entry=(Map.Entry)it.next();
String mapKey=(String)entry.getKey();
String mapValue= StringUtils.EMPTY;
//request这个参数mao,里面的value返回的是一个String[]
Object obj=entry.getValue();
if(obj instanceof String[]){
String[] strs=(String[])obj;
mapValue= Arrays.toString(strs);
}
requestParamBuffer.append(mapKey).append("=").append(mapValue);
}
if(StringUtils.equals(className, "UserManageController")&&StringUtils.equals(methodName,"login")){
log.info("权限拦截器截到请求,className:{},methodName:{}",className,methodName);
//如果是拦截到登陆请求,不打印参数,因为参数里面有密码,全部会打印到日志中,防止日志泄露
return true;
}
User user=null;
//从cookie里面获得loginToken
String loginToken= CookieUtil.readLoginToken(httpServletRequest);
if(StringUtils.isNotEmpty(loginToken)){
//通过loginToken从redis里面获得用户信息
String userJsonStr= RedisShardedPoolUtil.get(loginToken);
//将获得的用户信息转换成对象
user= JsonUtil.string2Obj(userJsonStr,User.class);
}
if(user==null||(user.getRole().intValue()!= Const.Role.ROLE_ADMIN)){
//返回false,即不会调用controller里的方法
httpServletResponse.reset();//这里要reset,不做这步,会报异常
httpServletResponse.setCharacterEncoding("UTF-8");//这里需要设置编码,否则会乱码
httpServletResponse.setContentType("application/json;charset=UTF-8");//这里需要设置返回值的类型,因为全部是json接口
PrintWriter out=httpServletResponse.getWriter();//输出流,2种流之一
if(user==null){
//富文本上传判断
if(StringUtils.equals(className,"ProdctManageCotroller")&&StringUtils.equals(methodName,"richtextImgUpload")){
Map resultMap= Maps.newHashMap();
resultMap.put("success",false);
resultMap.put("msg","请登陆管理员");
out.print(JsonUtil.obj2String(resultMap));
}else {
out.print(JsonUtil.obj2String(ServerResponse.createByErrorMessage("拦截器拦截,用户未登陆")));
}
}else {//代表用户不是管理员
if(StringUtils.equals(className,"ProdctManageCotroller")&&StringUtils.equals(methodName,"richtextImgUpload")) {
Map resultMap = Maps.newHashMap();
resultMap.put("success", false);
resultMap.put("msg", "无权限操作");
out.print(JsonUtil.obj2String(resultMap));
}else{
out.print(JsonUtil.obj2String(ServerResponse.createByErrorMessage("拦截器拦截,用户无权限操作")));
}
}
out.flush();
out.close();//这里要关闭
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
第三步:用户管理登陆
package com.mmall.controller.backend;
import com.mmall.common.Const;
import com.mmall.common.ServerResponse;
import com.mmall.pojo.User;
import com.mmall.service.IUserService;
import com.mmall.util.CookieUtil;
import com.mmall.util.JsonUtil;
import com.mmall.util.RedisShardedPoolUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Controller
@RequestMapping("/manage/user")
public class UserManageController {
@Autowired
private IUserService iUserService;
@RequestMapping(value="login.do",method = RequestMethod.POST)
@ResponseBody
public ServerResponse<User> login(String username, String password, HttpSession session, HttpServletResponse httpServletResponse){
ServerResponse<User> response = iUserService.login(username,password);
if(response.isSuccess()){
User user = response.getData();
if(user.getRole() == Const.Role.ROLE_ADMIN){
//说明登录的是管理员
// session.setAttribute(Const.CURRENT_USER,user);
//新增redis共享session的方式,将sessionId以loginToken为键放到cookie里面
CookieUtil.writeLoginToken(httpServletResponse,session.getId());
//将sessionId为键,用户信息为值存储在redis里面
RedisShardedPoolUtil.setEx(session.getId(), JsonUtil.obj2String(response.getData()),Const.RedisCacheExtime.REDIS_SESSION_EXTIME);
return response;
}else{
return ServerResponse.createByErrorMessage("不是管理员,无法登录");
}
}
return response;
}
}