servletRequest、servletRespones作用于链接
servletContext作用于全局
Cookie客户端技术,大家都知道的。
Session服务器端技术--为每一个客户端创造一个独享的Session对象
Session
关键点是,在getSession时,如果不存在当前会话,会自动创建,以后再getSession的时候,用的就是这个了。
Cookie
response.addCookie(),为会话加入一个cookie;
request.getCookies(),获取当前会话的cookies;
Cookie.setMaxAge(),设置生存周期,默认值为浏览器页面时间
Cookie.setPath(),设置有效目录,默认值为当前程序所在目录
Cookie.setDomian,设置域,例如(.sina.com.cn),记得前面加点(.)。浏览器一般会禁止写入第三方域。
example:
显示用户上次访问时间示例
public void doGet(.....){ //解决乱码 response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); //获得一个writer PrintWriter out=response.getWriter(); out.write("上次访问时间"); //获得cookies Cookie cookies[]=request.getCookies(); //遍历所有cookie并进行非空判断 for(int i=0;cookies!=null && i<cookies.length;i++){ Cookie cookie=cookies[i]; //取得存取最后访问时间的cookie if(cookie.getName().equals("lastAccessTime")){ //取得cookie值 String value=cookie.getValue(); //将毫秒时间转换格式化 Date d=new Date(Long.parseLong(value)); out.writer(d.toLocaleString()); } //更新cookie的最后访问时间 Cookie cookie=new Cookie("lastAccessTime",System.currentTimeMills()+""); //设置cookie存活时间,这里是一周。 cookie.setMaxAge(60*60*24*7); //设置cookie目录,只要访问当前目录下,无论存不存在页面,都会携带此cookie访问 cookie.setPath("/***"); //写入这个cookie response.addCookie(cookie); }
注意,浏览器一般只允许存放300个Cookie,每个站点最多20个,每个Cookie最大4kb。
example:
删除cookie
public void doGet(.....){ //首先新建一个cookie,名称为要删除cookie的名字 Cookie cookie=new Cookie("lastAccessTime",""); //将存活时间设置为0 cookie.setMaxAge(0); //访问目录要与目标cookie一样 cookie.setPath("/***"); //写入cookie,就会替换原始cookie,并删除 response.addCookie(cookie); }
判断表单重复提交的事例:
判断重复提交的流程,一般是这样的,在提交的表单中,加入一个随机数,提交表单的时候,一起提交,然后与服务器端session中的随机数(令牌)对比,如果存在,则提交,并且从session中删除这个令牌(随机数)。如果重复提交,提交的随机数与session中无法匹配,则对提交内容不作处理。
一个通用的令牌生成关键代码:
class TokenProcessor{ //令牌 /* * 1.把构造方法私有 * 2.自己创建一个 * 3.对外暴露一个方法,允许获取上面创建的对象 */ private TokenProcessor(){} private static final TokenProcessor instance = new TokenProcessor(); public static TokenProcessor getInstance(){ return instance; } public String generateToken(){ //这样获得的随机数长短不一 String token = System.currentTimeMillis() + new Random().nextInt() + ""; try { //所以,对他们进行一次md5,取得固定长度的摘要 MessageDigest md = MessageDigest.getInstance("md5"); byte[] md5 = md.digest(token.getBytes()); //base64编码,这样做的目的是,避免字节码偶然出现通讯中的结束位,误判断并提前结束传输 //base64是每6位前补00,形成一个字节,然后根据码表转换为键盘上的可见字符。 BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(md5); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } }