资讯网站项目
存在登录和未登录两种状态的操作,调用后台方法需要进行判定是否登录。 此时拦截器派上用场
//拦截器用处(来源:跟着开涛学SpringMVC)
1、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
2、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;
3、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
4、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
5、OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。
…………本质也是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现。
HandlerInterceptorAdapter
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse
response, Object handler, Exception ex) throws Exception {
}
分别实现预处理、后处理(调用了Service并返回ModelAndView,但未进行页面渲染)、返回处理(已经渲染了页面)
在preHandle中,可以进行编码、安全控制等处理;
在postHandle中,有机会修改ModelAndView;
在afterCompletion中,可以根据ex是否为null判断是否发生了异常,进行日志记录。
//自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface NeedLogin {
String value() default "";
}
//拦截器,继承HandlerInterceptorAdapter接口
public class LoginInterceptor extends HandlerInterceptorAdapter{
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
if(handler.getClass().isAssignableFrom(HandlerMethod.class)){//如果是spring mvc 方法
NeedLogin needLogin = ((HandlerMethod)handler).getMethodAnnotation(NeedLogin.class);
if(needLogin!=null){
NewsUser u = (NewsUser) request.getSession().getAttribute("user");
if(u==null){
String rt = request.getHeader("X-Requested-With");
if(rt!=null && "XMLHttpRequest".equals(rt)){
JSONObject json = new JSONObject();
json.put("isLogin", false);
response.getWriter().print(json.toString());
return false;
}else{
response.sendRedirect(request.getContextPath()+"/news/index");
return false;
}
}else{
return true;
}
}
}
return true;
}
}
根据以上写法:
1.如果写了@NeedLogin注解,则调用方法之前会进行是否登录校验
2.未写,则不校验
@NeedLogin
@ResponseBody
@RequestMapping(value="addOrUpdate")
public String addHistory(Long roomId, Long userId) {
JSONObject obj = new JSONObject();
boolean flag = false;
ZhiboWatchRecord zhiboWatchRecord = zhiboWatchRecordService
.addOrUpdateToHistory(roomId, userId);
if (zhiboWatchRecord != null) {
flag = true;
}
obj.put("status", flag? 1:0);
return obj.toString();
}