发表于: 2017-09-13 18:50:38

1 760


今天完成的事情:

还是拦截器

SpirngMVC中拦截器作用:进行权限验证,判断登陆,或者像12306那样判断当前时间是否可以购票

先定义一个拦截器的实现类,SpringMVC中的拦截器拦截请求是通过HandlerInterceptor实现的。我们可以建一个拦截器类来实现HandlerInterceptor接口,或者这个类继承这个接口。

public class LoginInterceptor implements HandlerInterceptor{}

然后实现接口方法,HandlerInterceptor接口有三个方法

1、

public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {}

这个方法是在请求处理之前进行调用的,也就是controller之前。由于拦截器是链式调用的,所有定义了的拦截器会按顺序执行,但最先执行的都是每一个里面的preHandle方法。这个方法主要定义了一些前置初始化操作,或对当前请求的预处理。返回值是布尔类型,返回为false的话那么这整个拦截器都不会再调用。

2、

public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {}

从参数ModelAndView就能看出来,这个方法在controller执行之后,视图渲染之前调用的。我们可以批对ModelAndView对象进行操作。但是它的调用顺序是和preHandle相反的。先声明的反而会后调用。

3、

public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {}

这个方法就是在请求结束之后调用的,也就是渲染视图返回之后,主要是用来清理资源的

要使用拦截器类还需要进行springmvc的配置

声明xml schema,就是一种描述xml文档结构的语言

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"

这样才可以使用mvc标签

声明拦截器,配置什么的如下

<!--配置拦截器-->
<mvc:interceptors>
   <!--使用mvc:interceptors标签来声明需要加入到SpringMVC拦截器链中的拦截器-->
   <!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
   <mvc:interceptor>
       <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
       <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
       <mvc:mapping path="/u/*" />
       <bean class="com.jnshu.utils.LoginInterceptor"></bean>
   </mvc:interceptor>
   <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->
</mvc:interceptors>

利用这个标签可以整一大堆拦截器,按顺序执行。

我这个拦截器类

public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {

System.out.println("调用拦截器");
   Cookie[] cookie = httpServletRequest.getCookies();
   if(cookie != null) {
for (int i = 0; i < cookie.length; i++) {
System.out.println("遍历");
           if (cookie[i].getName().equals("token"))
System.out.println("cookie: " + cookie[i]);
           {
try {
String token = cookie[i].getValue();
                   byte[] tk = TypeUtil.hexStringToByte(token);
                   byte[] tk1 = DES.decrypt(tk, "12345678");
                   String tk2 = new String(tk1);
                   String id = "";
                   String time = "";
                   System.out.println("cookie中的token进行解密");
                   for (int j = 0; j < tk2.length(); j++) {
char c = tk2.charAt(j);
                       if (c == '=') {
for (int k = j + 1; k < tk2.length(); k++)
time = time + tk2.charAt(k);
                           break;
                       }
id = id + c;
                       System.out.println("id=" + id);
                   }
if (userService.select(Integer.parseInt(id)) != null) {

return true;
                   }
}catch (Exception e){
e.printStackTrace();
               }
}
}
}
httpServletResponse.sendRedirect("login");
    return true;
   }

就是解密token,然后由于token里存的是当前id和当前系统时间,所以只能拿id去和数据库里对比了,先这样吧

如果token不同或者cookie为空重定向到login,但是

它给我定位到了/u/login了,还说什么重定向次数过多。。

百度一下好像是它拦截了/u/login这个uri的原因,但是为什么会前边给加了个/u呢?

我设定一下拦截器再试试

<mvc:exclude-mapping path="/u/login"/>

报错

cvc-complex-type.2.4.a: Invalid content was found starting with element 'mvc:exclude-mapping'. One 
 of '{"http://www.springframework.org/schema/mvc":mapping, "http://www.springframework.org/
 schema/beans":bean}' is expected.

这个是由于这个标签不被支持,需要把schema改一下

http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"

3.0改成3.2

再试一下

进去了,但是输入密码之后它又会跳到

研究了半天,找到一种方法

String contextPath = httpServletRequest.getContextPath();
String uri = contextPath + "/login";
System.out.println("重定向路径:" + uri);
httpServletResponse.sendRedirect(uri);
return true;

利用httpServletRequest.getContextPath()来查找出项目名

这里一个问题:

假定你的web application 名称为news,你在浏览器中输入请求路径:

http://localhost:8080/news/main/list.jsp

则执行下面向行代码后打印出如下结果:

1、 System.out.println(request.getContextPath());

打印结果:/news
   2、System.out.println(request.getServletPath());

打印结果:/main/list.jsp
3、 System.out.println(request.getRequestURI());

打印结果:/news/main/list.jsp
4、 System.out.println(request.getRealPath("/"));

打印结果:F:\Tomcat 6.0\webapps\news\test

然后就好了,但是为什么会出现那个错误呢,很迷

明天计划的事情:

小课堂,任务5剩下的

遇到的问题:

如上

收获:

拦截器


返回列表 返回列表
评论

    分享到