昨天跟前天讲了HttpServletRequest,HttpServletResponse,Cookie, Seesion,怎么说呢, 觉得还是cookie和session比较难些,request与response到不怎么难的,主要是因为使用cookie与session实现的功能有点多了,比如:使用Cookie获得商品浏览记录,买过电脑的童鞋都应该知道,我们买电脑之前是不是都上网看看那款电脑的性价比高,你在浏览电脑的同时,他会将你电脑的电脑存到一个浏览记录里,你从这个浏览记录中可以看到你浏览了那些电脑。而session呢,它实现的功能就有点多了,比如:著名购物车就是用session实现的,自动登录,在服务器端还可以使用session来做放置表单重复提交。做的东西一多感觉就有点小难了。。。
1、cookie:
cookie是客户端技术,当用户访问服务器时,服务器会为每个回话创建一个session,在创建完之后向客户端写入一个cookie,cookie name:JSESSIONID, cookie: session.getId(), cookie默认是会话级别的,他储存在浏览器的内存中,当浏览器关闭时,会话级别的cookie也就被删除,但是也可以通过调用cookie的setMaxAge方法设置它的有效时间,利用这一点可以让cookie帮我们干一些事情,干什么事情呢?比如:获得上次访问某个站点的时间; 获得商品浏览记录。
使用Cookie获得商品浏览列表和上次访问的时间 (要想cookie记住用户浏览记录,则必须将创建的cookie添加到响应头上)
使用cookie获得商品浏览记录:
1、得到所有的cookie,并检查其中有没有目标cookie
2、若在所有得到的cookie中,没有检查到目标cookie, 那么就创建一个目标cookie,并设置他的有效时间。这是唯一能保证保证cookie能记住浏览信息的方法。因为cookie默认是会话级别的,它保存在浏览器的缓存中,当关闭浏览器时,cookie也就随之消失了
使用cookie删除浏览记录:
1、创建一个cookie,区别标示名与目标cookie的区别标示名相同,并设置他的有效时间为0, 例如:Cookie cookie = new Cookie("visite", ""); cookie.setMaxAge(0);
这样创建了一个cookie,用它来直接覆盖掉目标cookie。
cookie声明周期:用户访问服务器, 服务器创建session,向客户端写入一个cookie,会话级别的cookie,在推出浏览器时,被删除;否则,有效期过了也别删除。
2、session
session是服务器端技术,当用户访问服务器时,服务器会把用户的数据保存到一个单独的session中。
session声明周期:用户访问服务器时,服务器首先会检索请求中有没有session的一个标示号成为JESSIONID,若有则服务器就会检索出相应的session,若没有就会重新创建一个session可能是服务器删除了该用户的session对象),session是在调用getSession(true)方式时创建。当服务器被关闭,session超时或者调用了session的invalidate方法销毁session在这三种情况下,session对象会被销毁
我们使用session实现自动登录、购物车、防止表单重复提交功能:
购物车:
response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String id = request.getParameter("id"); Map<String, Integer> map = null; //先创建一个session, HttpSession session = request.getSession(); //在session中检查有没有Map集合 map = (Map<String, Integer>) session.getAttribute("map"); //若Map集合为空,那么重新创建一个,然后将这个Map集合设置到session中 if (map == null) { map = new HashMap<String, Integer>(); session.setAttribute("map", map); } Integer count = map.get(id); if (count == null) { //当商品被第一次浏览,则count = 1 count = 1; System.out.println("null count = 1"); } else { //当商品已经被浏览过了,则count++ System.out.println(" not null count ++"); count ++; } map.put(id, count);
3、在request与response中,我任务最重要的是乱码问题,以前也是经常被这些乱码搞得很是烦恼,想要弄明白乱码问题,为什么产生乱码?就必须对用户向服务器发出请求直至服务器响应结束这整个过程中每一个阶段数据都是用什么字符集编码有所了解?
我是这样理解的,出现乱码就是使用的字符集不对称,可能我的理解还不够细节,但是我任务我这样的理解可以很好的掌握乱码的原理:
1、(假设我们的浏览器的打开数据编码是gbk)当用户发出请求时,同时会提交一些数据,这些数据是使用浏览器的默认的编码转换成字节流。浏览器生成HTTP请求发送给服务器,服务器接受到请求之后,创建request与response对象,在创建request对象,服务器将传递过来的字节流转换字符串,并使用默认的字符集ISO8859-1往request写入数据。这也就是为什么你使用request.getParamter("param")得到的是乱码,然后调用service方法响应客户端的请求,在service方法中也同样使用ISO8859-1向response对象中,当service方法执行完之后,服务器将响应信息会送给客户端浏览器显示,这是客户端的到依然是乱码,因为response中的数据是ISO8859-1的,把是ISO8859-1数据用gbk的编码打开肯定是乱码。解决的方法就是设置会送给浏览器的数据的编码:response.setCharacterEncoding("UTF-8");但是这只对post提交方式有效。解决post提交方式乱码问题还应设置他的contentType:response.setContentType("text/html;charset=utf-8");
4、你给我聊一聊web开发中的四个域对象(自己总结的可能不是很好)
所谓的域对象就是能够存储数据的对象,在web开发中一共有四个域对象:page域、request、session域、context域,他们对象的类分别是:PageContext, HttpServletRequest,HttpSession, ServletContext.. web服务器启动时,会为每个web应用创建一个ServletContext,他代表整个web应用,通常也称之为context域,存储在context域里的数据,共享于整个web应用中,当很多用户并发访问时,会有线程安全问题。
session域里储存的是同一用户在同一绘画期间,在web应用各个资源之间共享的数据,session对象不需要像request那样,在请求转发时,需要传递请求数据。通过他可以实现购物车。
request域保存的是用户向服务器发出请求的信息。在请求转发时需要将数据设置到request域中。
page域保存的是页面信息,他是非常强大的的一个域对象,也是JSP的九大内置对象之一,通过他可以可以得到其他的其他八大内置对象。
5、Expires与If-modified-since,last-modifie在缓存上有什么区别?
1、使用Expires响应头时,浏览器首先会去访问缓存,若发现请求的页面缓存到未来时间,则不向服务器发出请求,直接从缓存里获取数据。
2、使用If—modified-since请求头与last-modified响应头时,当客户访问服务器上的资源时,服务器会指定last-modified,当客户再一次访问时,服务器会比较If-modified-since与last-modified,
若发现你请求的资源的请求头If-modified-since比较新,这时服务器就会发送304状态码给客户浏览器,叫浏览器从缓存里拿数据。若发现If-modified-since比较旧,则服务器就将请求的资源会送给浏览器。
在这个过程之中,服务器起到一个掌控的作用,决定浏览器是否从缓存里获取数据。
1、和 2、的区别:在使用Expires时,与服务器没有交互;而第二种则有与服务器有交互
自己总结出的 结论:若一网页中有3个资源(比如:3张图片),若是使用If—modified-since请求头与last-modified响应头时,在服务器请求时,从缓存里拿数据,这时向服务器发出的请求是 1 次。
6、文件下载 (文件名为中文)
文件下载的原理就是就是读取服务器上的文件,并将它写入客户端浏览器。通过设置HTTP的响应头,可以设置文件是不是下载文件, Content-disposition的用法:response。setHeader("Content-disposition", "attchment;filename=文件名"); 通过设置HTTP响应头来设置文件是不是下载文件的具体步骤:
1、通过设置HTTP的响应头Content-disposition,告诉浏览器这个文件下载文件,
2、获得她的MIME类型
3、通过设置HTTP响应头来告诉浏览器这个文件是以什么格式被下载, response.setHeader("Content-type", mimeType);
注意:在文件下载中,若是文件名为中文,那么要对文件名URL编码,
String filename = "图片.bmp";
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
这样就能成功下载文件了。
7、实现断点下载
//实现断点下载 String filepath = this.getServletContext().getRealPath("/range.txt"); // System.out.println(filepath); URL url = new URL("http://www.google.com.hk"); URLConnection connection = url.openConnection(); connection.addRequestProperty("Range", "bytes=0-"); PrintWriter out = response.getWriter(); InputStream in = connection.getInputStream(); int temp = 0; while ((temp = in.read()) != -1) { out.write(temp); } in.close();
通过上面的实例,使用这一功能可以在网上抓取一些无法保存的页面。