发表于: 2017-11-20 20:49:33
1 693
今天完成的事
【一点java小知识】
在java.lang包中有String.split()方法,是个拆分字符串的,返回是一个数组。作用我测试了一哈。
public class test2 {
public static void main(String[] args) {
String l = "123,123,123,456.123424,345";
String[] ll = l.split(",|\\.");
for (int i = 0; i < ll.length; i++) {
System.out.println(ll[i]);
}
}
}
这个对我今天的拆解Token揭秘后的字符串有用。
就是昨天困惑的地方。
【配置拦截器】
先说一下拦截器是干嘛的。
拦截器呢,就是实现一个接口。接口中定义了三个方法:preHandle(requsest,response.handle);postHandle(request,response,handle,modleandview);aftercompletion(request,response,handle,ex);下面说说每个方法的作用和作用空间。
1.preHandle(requsest,response.handle) :在请求处理之前调用这个方法,即请求从前台传递到controller之前调用的方法,返回值是boolean,如果返回的是true,那么继续进行下面两个方法;如果返回的是false,请求结束;我的拦截器里面获取了request中的session数据;来验证用户是否登录;如果flag为true返回true;反之返回false;这个是我们完成任务主要要用的方法,我们在跳转链接处理请求前进行判定。
2.postHandle(request,response,handle,modleandview):由preHandle 方法的解释我们知道这个方法包括后面要说到的afterCompletion 方法都只能是在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用。postHandle 方法,顾名思义就是在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行,这和Struts2 里面的Interceptor 的执行过程有点类型。Struts2 里面的Interceptor 的执行过程也是链式的,只是在Struts2 里面需要手动调用ActionInvocation 的invoke 方法来触发对下一个Interceptor 或者是Action 的调用,然后每一个Interceptor 中在invoke 方法调用之前的内容都是按照声明顺序执行的,而invoke 方法之后的内容就是反向的。(没时间了,了解一下就好,感觉和事务管理有关系)
3.aftercompletion(request,response,handle,ex):该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。(这里有一个疑问,一会会讲)
开始配置拦截器
在我的springMVC里面添加了配置文件。
<!--据说这是一个开启注解的标签,我先放在这里,一会试试关了能不能完成需求-->
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/profession"/>
<bean class="com.xiuzhen.Interceptor.IndexInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
配置了一个类。
继承了HandlerInterceptor 方法。
package com.xiuzhen.Interceptor;
import com.xiuzhen.domain.User;
import com.xiuzhen.service.UserService;
import com.xiuzhen.utils.DesUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by ${MIND-ZR} on 2017/11/20.
*/
public class IndexInterceptor implements HandlerInterceptor {
@Autowired
private UserService userService;
//Handler执行之前调用这个方法
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
//那倒请求里面的cookie
Cookie[] cookies =httpServletRequest.getCookies();
//判断cookies中的token有效性来判断用户是否登录
if(cookies != null){
//取出Toke名字的cookies
for (int i=0;i<cookies.length;i++){
if (cookies[i].equals("Token")){
System.out.println("开始拦截");
//取出这个cookie
String t=cookies[i].getValue();
//破解Token
String tDecrypt=new DesUtil("gaomingda").decrypt(t);
//拆解这个破解之后的Token
String[] arrToken=tDecrypt.split(",");
String username=arrToken[0];
String logTime=arrToken[1];
//通过账号登录时间对比用户是否正确
User user=userService.selectUserByName(username);
if (logTime.equals(user.getLogtime())){
return true;
}
}
}
}
return false;
}
//Handler执行之后,ModelAndView返回之前调用这个方法
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
//Handler执行完成之后调用这个方法public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
Cookie cookie = new Cookie("Token",null);
cookie.setMaxAge(0);
cookie.setPath("/");
httpServletResponse.addCookie(cookie);
}
}
注意上面有一个地方。
我在拦截器的aftercompletion里面做了一个更新cookie的操作,就是说按这个方法的意思我应该可以达到刷新就重置cookie的作用,没有cookie就不能再访问当前页面,但是实际操作是刷新之后还能访问,但是方法执行了。因为控制台输出了。
但是我的cookies更新方法没问题啊。
那为什么cookie没有被更新呢。。。如果被更新应该不能被访问了啊。
用请求头看一下
第一次访问。
我F5刷新。再看cookie里面的Token
我的Token值没有变。。。
还是说这个afterCompletion方法里面的httpServletResponse.addCookie(cookie);并不能添加coolies?
想不明白,明天再搞搞,搞不明白问一下师兄吧。
这个也影响不了任务。
往下做。
完成了对职业页面的拦截。
不登陆访问的时候。
没有Token你进不来你气不气。
登陆之后。
带着Token进来的。
因为我的cookies有效时间是60秒。
所以我等到60秒之后刷新页面。
又不能访问了。
总结一下总共发生了什么。
首先我这个用户进来
我从前端拿到用户的账户名和密码二话不说先通过我的
来进行账户名和密码进行判定。对比,对的上,往下运行,对不上,扔出去。
账户名和密码判定里面用到了MD5加密
如果说账户名和密码对应。
那么开始通过这个用户名和登陆时间(此刻的一个时间戳)
用DES生成一个Token。(其实就是一个cookies的ID。。)也就是令牌。
然后我们的服务端开始带着cookie闯进各种页面。
如果我的页面进行了拦截器拦截。
那么我的拦截器会对这个cookies里面的Token。进行揭秘分析分解字符串。
分出来的时间和用户名扔到数据库去比对。
比对一样,可以进行访问。
不一样,不能访问。返回原来的页面。
【收获】
【关于深度思考的一个问题】
拦截器、过滤器、监听器各有什么作用?
参考文档。
https://www.zhihu.com/question/35225845(这个参考文档讲的巨他妈逗。。。言简意赅。)
这个文档可以支撑我讲一个小课堂。。。。马一下。
过滤器(Filter):
过滤器换一种表达就是预处理(pre processing)或者后处理(post processing),你说到的依赖于servlet容器,我觉得这是狭隘层次上的定义,你用米进行煮饭前要做什么,要用水先对米进行清洗,浸泡一下,这就是预处理;你榨完果汁后是直接喝吗,不,还要用筛子将果渣过滤掉,这就是后处理,对数据进行预处理或者后处理就是过滤器要做的工作,常见的应用有将请求中的数据进行转码,日志系统,系统缓存这些都是要依赖过滤器来实现,servlet中通过实现servlet中给的接口从而实现自定义过滤器,当有多个过滤器时就形成了过滤器链,也就是要依次经过过滤器链中的过滤器才能最终到达实际目标.
拦截器(Interceptor):
顾名思义,就是对数据进行拦截,从这个定义上看,似乎和过滤器很像,但是拦截器要做的工作更多是安全方面,比如用户验证,判断是否登陆。和过滤器的一个区别就是拦截器不一定会到达目标,也就是他可以拒绝你的请求,但是过滤器是一定会到达目标,但是在到达目标前或者后要进行一些操作.
监听器:
显然就是生活中的监视,和监听相关的概念就是事件,这些名词在生活中其实都经常接触。事件往大了说就是动作的序列,往小了说就是一个动作。想想电影中某个大boss叫你去监视某个人,那么你就充当了监听器的作用,监视的作用意义何在,就是当被监视对象出现了某个状态时要做出处理(触发某个方法),一般大boss会对你说如果那个人作出了什么举动(出现了某个状态),那么你就怎么怎么样,你监视的对象的动作或者说状态就是所谓的事件,而你(监听器)对这个状态的处理就是处理方法。举javascript中的例子来说,鼠标点击事件(onClick一个动作),键盘按下事件(onKeyDown,onKeyPress一个动作)等,显然javascript给相应对象设置了监听器。
【另外一点奇怪的想法】
今天做更新时间语句的时候有一个大胆的想法。
我更新用户登录时间的时候能不能不传入用户对象。
而通过用户名字和时间两个参数去进行操作。。就是说我的映射语句是这样的话,
<update id="updateLogTime" parameterType="java.lang.Long" parameterMap="java.lang.String">
update task4 set logtime = #{logTime} WHERE username= #{username}
</update>
我的DAO层也是传入两个参数的话。
void updateLogTime(Long logTime ,String username);
发现是不可以的。。。
参数绑定错误。。
说明mybatis应该是不 允许传入两个参数的,乖乖的去更新对象了。
遇到的问题
上面提到了一个。
还有另一个已经解决了。
我在做Token破解以后的时间比对的时候。
有一个小坑。
看上去没什么问题对不对。
但是不对。
第一个箭头其实是一个分离出来的字符串类型。
第二个箭头其实是一个我获取的long类型。
这两个怎么比都是false。。。。。。。。
解决方法也简单
做个强转
这样就可以了。。。。
明天要完成的事。
用拦截器的第二种方式再进行一遍拦截。
做一个注册账户的需求。
再做一个根据cookie记录用户浏览记录的需求。(看到一个文档,好像也不是很难。。。)
解决上面拦截器的问题。
完善一下任务5。
总结知识点提交任务5。(但愿
评论