浅谈HttpSession&ServletContext&文件下载

417 阅读4分钟

1. HttpSession对象

1.1 作用以及创建对象

Session的作用是标识一次会话,或者说确认一个用户;并在一次会话(一个用户的多次请求)期间共享数据.我们可以通过request.getSession()方法获取当前会话的session对象

HttpSession session=request.getSession();

1.2 标识会话 JSESSIONID

Session的作用既然是标识一次会话,那么此次会话就应该有个唯一标志,这个标志就是sessionId.

每当一次请求到达服务器,如果开启了会话(访问了session),服务器第一步会查看 是否从客户端回传一个名为JSESSIONID 的cookie,如果没有则认为这是一次新的会话, 会创建一个新的session 对象,并用唯一的sessionId 为此次会话做一个标志.如果有 JESSIONID 这个cookie 回传,服务器则会根据JSESSIONID 这个值去查看是否含有id 为JSESSION 值的session 对象,如果没有则认为是一个新的会话,重新创建一个新的 session 对象,并标志此次会话; 如果找到了相应的session 对象,则认为是之前标志过 的一次会话,返回该session 对象,数据达到共享.

这里提到一个叫做JSESSIONID 的cookie,这是一个比较特殊的cookie,当用户请 求服务器时,如果访问了session,则服务器会创建一个名为JSESSIONID,值为获取到 的session(无论是获取到的还是新创建的)的sessionId 的cookie 对象,并添加到 response 对象中,响应给客户端,有效时间为关闭浏览器.

所以Session 的底层依赖Cookie 来实现.

1.3 Session域对象

session用来标识一次会话,在一次会话中的数据是可以共享的,此时的session作为域对象存在

可以通过session.setAttribute(name,value)向域对象中添加数据

通过session.getAttribute(name)从域对象中取数据

通过session.removeAttribute(name)从域对象中移除数据.

例:

HttpSession session=request.getSession();
session.setAttribute("name","Tom");
response.sendRedirect("servletdemo");//因为在一次会话中的数据是共享的,所以其中的数据使用重定向仍然有效

不管请求转发还是重定向,session作用域中的数据在一整个会话中都有效.

1.4 Session的销毁

  1. 默认到期时间 在服务器规定时间内没有任何操作,session对象就会自动销毁

  2. 自己设定时间 通过session.setMaxInactiveInterval(int)设定session的最大不活动时间,单位是秒

通过session.getMaxInactiveInterval(int)获取session的最大不活动时间

  1. 关闭浏览器 session的底层以来cookie;默认关闭浏览器即失效

  2. 关闭服务器 当非正常关闭服务器,session关闭

当正常关闭服务器,session将被序列化至磁盘上 5. 手动销毁 session.invalidate();

2. ServletContext对象

2.1 介绍

每个webb应用都有且仅有一个ServletContext对象,又称Application对象,从名称中可知,这个对象与应用程序有关. 在web容器启动时,会为每个web应用程序创建一个对应的ServletContext对象.

该对象有两个作用,一个是作为域对象用来数据共享,此时数据在整个应用中共享;该对象保存了当前应用程序相关信息.

例如通过getServerInfo()方法获取当前服务器信息;通过getResourceAsStream(String path)方法以流的方式获取某个资源; 通过getRealPath(String path)获取资源的真实路径

2.2 ServletContext对象获取

获取ServletContext对象有多种途径:

  1. 通过request对象:

    ServletContext servletContext=request.getServletContext();

  2. 通过session

    ServletContext servletContext=request.getSession().getServletContext();

  3. 通过ServletConfig

    ServletContext servletContext=getServletConfig().getServletContext();

  4. 直接获取

    ServletContext servletContext=getServletContext();

2.3 作为域对象

ServletContext也可作为域对象使用,通过向其中存储数据,可以使整个应用程序共享其中的数据.但建议不存放过多,因为ServletContext中的数据 不手动移除就会一直存在.

例:

ServletContext servletContext=getServletContext();
servletContext.setAttribute("name1","value1");
servletContext.getAttribute("name1");
servletContext.removeAttribute("name1");

3.文件下载

3.1 超链接下载

当超链接遇到浏览器识别不了的动态网页时就会自动下载.当浏览器遇到能识别的资源时,就会默认显示出来,比如txt,png,jpg.我们也可以通过download属性规定浏览器进行下载.

例:

<a href="upload/abc.zib">超链接下载</a>

指定download属性下载:

<a href="upload/abc.txt" download>超链接下载</a>

这里download可以不写任何信息,会自动使用默认文件名.这样用户打开浏览器点击链接的时候就会直接下载文件

3.2 后台下载

实现步骤:

1. 需要通过HttpServletResponse.setContentType 方法设置Content-type
头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的MIME 类型,例如”
application/octet-stream” 或”application/x-msdownload” 等

2. 需要通过HttpServletResponse.setHeader 方法设置Content-Disposition
头的值为”attachment;filename=文件名”

3. 读取下载文件,调用HttpServletResponse.getOutputStream 方法返回的
OutputStream 对象来向客户端写入附件内容.

代码:

public class DownloadServlet extends HttpServlet{

	protected void service (HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
		
		request.setCharacterEncoding("UTF-8");
		//获取文件下载路径
		String path=getServletContext().getRealPath("/")+"download/";
		String filename=request.getParameter("filename");
		File file=new File(path+filename);
		if(file.exists()){
			//设置响应类型application/x-msdownload
			response.setContentType("application/x-msdownload");
			//设置头信息
			response.setHeader("Content-Disposition","attachment;filename="+filename);
			InputStream is = new FileInputStream(file);
			ServletOutputStream os = resp.getOutputStream();
			byte[] car = new byte[1024];
			int len = 0;
			while ((len = is.read(car)) != -1) {
			os.write(car, 0, len);
			}
			// 关闭流、释放资源
			os.close();
			is.close();
			} else {
			System.out.println("文件不存在,下载失败!");
			}
		}
	}
}