Cookie(续)
Cookie注意事项
一般站点中的保存用户名的操作都只是保存在本地,如果用户更换电脑,那么这些信息就无效了,而且Cookie还不能跨浏览器。
Cookie中也不能出现中文,如果出现了中文就需要使用URLEncoder.encode()来进行编码,获取的时候就需要使用URLDecoder.decode()来进行解码操作。
String name = "姓名";
String value = "李四";
name = URLEncoder.encode(name, "utf-8");
value = URLEncoder.encode(value, "utf-8");
Cookie cookie = new Cookie(gender, value);
response.addCookie(cookie);
Cookie[] cookies = req.getCookies();
if(cookies != null){
for(Cookie coo:cookies){
String name = URLDecoder.decode(coo.getName(), "utf-8");
String value = URLDecoder.decode(coo.getValue(), "utf-8");
System.out.println(name + ":" + value);
}
}
不同的浏览器对Cookie的个数都有着对应的限制,Cookie是存储在浏览器上的,而且一般由服务器进行创建和设定。
Cookiie的覆盖
如果服务器端发送重复名称且路径一致的Cookie那么就会覆盖原有的Cookie。
Cookie的路径
//创建Cookie对象
Cookiecookie=newCookie("A","a");
//响应给客户端
resp.addCookie(cookie);
//创建Cookie对象
Cookiecookie1=newCookie("B","b");
cookie1.setPath("/");//代表当前服务器所有资源都能访问
//响应给客户端
resp.addCookie(cookie1);
//创建Cookie对象
Cookiecookie2=newCookie("C","c");
cookie2.setPath("/cookie");//在访问服务器中cookie中的资源才能访问
//响应给客户端
resp.addCookie(cookie2);
//创建Cookie对象
Cookiecookie3=newCookie("D","d");
cookie3.setPath("/cookie/test");//在访问服务器中cookie下test中的资源才能访问
//响应给客户端
resp.addCookie(cookie3);
cookie1.setPath("/"); 将cookie1设置在根目录上
cookie2.setPath("/cookie");//在访问服务器中cookie中的资源才能访问,并且能访问在根目录中的cookie以及默认路径的cookie 默认路径就是在/cookie 中
cookie3.setPath("/cookie/test"); 能访问test中、cookie中以及根目录中的cookie
只要是路径中显示出的文件夹中的子级的cookie都能访问
session
Httpsession 对象是Javax.servlet.http.HttpSession的实例,属于http协议的范畴,对于服务器来说每个链接的客户都是一个session,servlet容器使用此接口创建客户端和服务器之间的会话。会话会保留一定的时间段(默认无操作30分钟)、session的作用就是保存一次会话,在一次会话期间共享数据。session在浏览器和服务器端都可以感知到,如果重新打开一个浏览去无法去得之前设置的session,每一个session只会保存在当前的浏览器中
获取session:
HttpSession session = request.getSession()
会话标志JSESSIONID
sessionid是存放在浏览器端的cookie中的唯一标志,用于标识一次会话。每当一次请求到达服务器就会开启会话,服务器会第一步查看cookie中的sessionid,如果不存在则认为这是一次新的会话,会创建一个新的session对象,并会为本次会话创建一个新的id,且会回传给cookie。如果存在sessionid,便会根据这个id去查看是否存在含有该id的session对象,如果没有怎hi认为是一个新的会话,重新创建一个新的session对象,标志此次会话,如果找到响应的session对象,则认为之前标志过该对象返回该session对象数据达到共享。
作为域对象
session用于表示一次会话,在一次会话中数据是可以方向的,此时可以通过setAttribute(name,value)向该域中天津爱数据,通过getAttribute(name)获取数据,通过removeAttribute(name)从狱中移除数据。一旦session不存在或者两个session不同时便不能共享数据了,这和session的生命周期有关系了。
session的销毁
1.默认时间:在Tomcat中的session默认时间是30分钟,这是不操作界面的时间,如果有操作session就会重新计算。默认时间设置在Tomcat的web.xml文件中。ctrl+f,查找sessio-timeout
2.自己设定时间:通过session.setMaxInactiveInterval(s);也可以通过session.getMaxInactiveInterval(s)获取当前设置的时间。
3.立刻失效:通过session.invalidate()让session立刻失效
4.关闭浏览器:session的地产是依赖cookie实现的(通过cookie中的sessionid识别),且cookie的有效时间为浏览器运行,因此关闭浏览器session也会失效
5.关闭服务器:
当非正常关闭服务器时,session 销毁;当正常关闭服务器时,Session 将被序列化到磁盘上,在 工作空间 work 目录下的 SESSION.ser 文件中,如果对象被保存在了 Session 中,服务器在关闭时要把 对象序列化到硬盘,这个对象就必须实现 Serializable 接口,下次启动服务时,自动加载到内存。
ServletContext
每个web应用都有且仅有一个servletContext对象,又称之为application对象,该对象是和应用程序相关在web启动时就会创建对应的servletcontext对象。
该对象的作用首先是作为域对象用于共享数据,此时共享的数据在整个应用程序重共享,第二该对象中保存有当前应用的相关信息:
方法 | 作用 |
---|---|
getserverInfo | 获取当前服务器信息 |
getResourceAsStream(String path) | 以流的心声获取某个资源 |
getRealPath(String path) | 获取资源的真实路径 |
获取servletcontext对象的方法
1.ServletContext servletcontext = request.getServletContext();
2.HttpSession session = request.getSession();
ServletContext servletcontext = session.getServletContext();
3.通过servletConfig
Serveltconfig servletconfig = getServletConfig();
ServletContext servletcontext =servletconfig.getServletContext()
4.直接获取
ServletContext servletcontext =getServeltContext();
作为域对象
servletContext servletcontext = getServeltContext();
servletcontext.setAttribute(“name”,“value”);
serveletcontext.getAttribute(“name”);
servletcontext.removeAttribute(“name”);
文件上传下载
文件上传
文件上传涉及到前台额main的编写和后台服务器代码的编写,前台发送文件,后台接收并保存文件。
前台页面
前台页面上传文件的请求方式必须为post;另外需要设置表单的MIME编码enctype为multipart/form-data;该编码的默认编码格式是"qpplication/x-www-form-urlencoded",不能用于文件上传;只有是用了multiple/form-data才能完整的传递文件数据
后台commons-fileupload的使用
首先需要导入第三方jar包,在http://commons.apache.org/ 下载 commons-io 和 commonsfileupload 两个jar的资源。解压并导入到项目中。commons-fileupload.jar 是文件上传的核心包 commons-io.jar 是 fileupload 的依赖包,同时又是一个工具包。
介绍导入包中的几个核心类:
DiskFileItemFactory 设置磁盘空间,保存临时文件
servletFileUpload 文件上传的核心类,此类接收request并解析
servletFileUpload.parseRequest(request): List解析request
步骤如下:
1.创建一个DiskFileItemFactory 工厂,并制定临时文件和大小
2.创建ServletFileUpload核心类,接收临时文件,做请求的转换
3.通过创建ServletUpload类转换原始请求,得到FileItem集合
4.遍历集合中的各个元素并处理
5.判断每个元素是否是普通表单向,如果是则按照普通表单项处理
6.如果不是普通表单项,则是文件,通过处理的方式进行处理(上传)
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
// 设定编码可以获取中文文件名
request.setCharacterEncoding("UTF-8");
// 获取tomcat下的upload目录的路径
String path = getServletContext().getRealPath("/upload");
// 临时文件目录
String tempPath = getServletContext().getRealPath("/temp");
// 检查我们是否有文件上传请求
// boolean isMultipart = ServletFileUpload.isMultipartContent(req);
// 1、声明DiskFileItemFactory工厂类,用于在指定磁盘上设置一个临时目录
DiskFileItemFactory disk = new DiskFileItemFactory(1024 * 10, new File(tempPath)); // 2、声明ServletFileUpload,接收上面的临时文件。也可以默认值
ServletFileUpload up = new ServletFileUpload(disk);
// 3、解析request
try {
List<FileItem> list = up.parseRequest(request);
if (list.size() > 0) {
for (FileItem file : list) {
// 判断是否是普通的表单项
if (file.isFormField()) {
String fieldName = file.getFieldName();
// 中文乱码,此时还需要指定获取数据的编码方式
// String value = file.getString();
String value = file.getString("UTF-8"); System.out.println(fieldName + "=" + value);
} else {
// 说明是一个文件
// 获取文件本身的名称
String fileName = file.getName();
System.out.println(file.getFieldName());
// 处理文件名称
fileName = fileName.substring(fileName.lastIndexOf("\\") + 1); System.out.println("old Name : " + fileName);
// 修改名称
String extName = fileName.substring(fileName.lastIndexOf(".")); String newName = UUID.randomUUID().toString().replace("", "") + extName;
// 保存新的名称,并写出到新文件中
file.write(new File(path + "/" + newName));
System.out.println("文件名是:" + fileName);
System.out.println("文件大小是:" + file.getSize());
file.delete();
}
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
文件下载
文件下载就是将服务器上的资源下载到本地,可以通过两种方式下载,第一种是通过超链接本身的特性来下载,第二种是通过手动写出来下载
1)、超链接下载
在html或jsp页面中使用超链接原意是进行跳转,但是当超链接遇到浏览器不识别的动态网页是则会自动下载,如果浏览器能够直接显示的资源,浏览器就会默认显示出来,比如TXT、png、jpg等。也可以通过download属性规定浏览器进行下载,但是有些浏览器并不支持
默认下载:
<a href ="upload/abc.zip">超链接</a>
指定download属性下载
<a href="upload/abc.txt" download="abcd.txt">超链接下载</a>
download也可以不写任何信息,会自动使用默认文件名。这样用户打开浏览器点解链接的时候回直接下载文件
2)、后台实现下载
第一步:需要通过HTTPServletResponse.setContentType方法设置Content-type头字段的值,这样浏览器才能够通过使用某种方法或激活某个程序来处理相应的MIME类型的数据如”application/octet-stream” 或”application/x-msdownload” 。
第二步:需要通过 HttpServletResponse.setHeader 方法设置 Content-Disposition 头的值为“attachment:filename=文件名”,filename提供了文件下载时的一个默认文件名 ,
Step3:读取下载文件,调用 HttpServletResponse.getOutputStream 方法返回的 OutputStream对象来向客户端写入附件内容。
public class DownLoadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置请求编码
request.setCharacterEncoding("UTF-8");
// 接受参数,得到需要被下载的文件的名称
String fileName = request.getParameter("fileName");
// 判断名字名是否为空
if(fileName == null || "".equals(fileName)){
// 提示
System.out.println("文件名不能为空");
return;
}
// 获取文件存放的真实路径
String path = request.getServletContext().getRealPath("/" + fileName);
// 通过文件路径和文件名得到file对象
File file = new File(path);
// 判断是否存在,并且是一个标准文件
if (file.exists() && file.isFile()){
// 设置相应类型 application/octet-stream
response.setContentType("application/x-msdownload");
// 设置头信息
response.setHeader("Content-Disposition", "attachment;filename=" + fileName); // 通过file对象得到输入流
FileInputStream in = new FileInputStream(file);
// 得到输出流
ServletOutputStream out = response.getOutputStream();
byte[] car = new byte[1024];
int len = 0;
while((len = in.read(car)) != -1){
out.write(car,0,len);
}
// 关闭流
in.close();
out.close();
} else {
System.out.println("文件路径不正确!");
}
}
}