Cookie
HTTP在获取完整数据后会断开连接。
当客户端第1次请求服务器时,服务器向客户端发送数据的同时,发送一个身份验证标识,这个验证标识就是cookie文件。
接下来,客户端跟服务器的每一次数据交互,客户端都必须携带该cookie
如果cookie丢失或者超时失效,则服务器无法识别,就会要求用户重新登录
cookie是无法被浏览器端完全禁止的
同时cookie还能承担一些客户端用户信息的保存,例如:用户名密码、浏览记录等等
第一次访问服务器,服务器响应时发送给浏览器Cookie,浏览器再次访问对应路径时携带Cookie访问(request中有cookie)
创建Cookie
坑:Cookie中不允许有空格,而时间的格式都存在空格,所以想要将时间加入Cookie中,请注意格式化问题
// 1.创建Cookie
Cookie cookie = new Cookie("username", "zhangsan");
Cookie cookie1 = new Cookie("address","上海");
// 2.设置三个参数
// 2.1有效路径
// / 整个网站,只要访问同一个网站,都会回传给服务器
// /0831 只要访问0831这个应用,都会回传给服务器 默认(创建Cookie的Servlet或页面所在的目录)
cookie.setPath("/");
// 2.2 有效期 默认值-1 表示保存在内存中,游览器关闭失效,0表示删除Cookie 大于0表示有效期,单位秒
cookie.setMaxAge(60*60*24);
// 2.3 设置仅有http能访问
cookie.setHttpOnly(true);
// 3.响应给客户端
response.addCookie(cookie);
response.addCookie(cookie1);
读取Cookie
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
System.out.println(cookie.getName()+"-----"+cookie.getValue());
}
更新与删除cookie
// 1.更新修改cookie (保证name 与 有效路径相同,就会被认为是一个cookie)
// 创建时会覆盖原有同一个Cookie ,调整value与有效时间
Cookie cookie = new Cookie("username", "chichi");
cookie.setMaxAge(60*60*24);
// response.addCookie(cookie);
// 2.删除Cookie
// 即使cookie有效为0,让cookie失效,删除内存中的cookie
cookie.setMaxAge(0);
response.addCookie(cookie);
老版本Tomcat中Cookie存在不能使用中文的问题,目前版本中已不存在此问题
//在以前会出现中文乱码问题,所以需要编码,现在不需要了
//编码
Cookie cookie = new Cookie("username", URLEncoder.encode("李四", "utf-8"));
response.addCookie(cookie);
//解码
Cooke[] cookies = request.getCookies;
f (cookies != null) {
for (Cookie cookie : cookies) {
System.out.println(cookie.getName()+"--"+URLDecoder.decode(cookie.getValue(),"utf-8"));
}
}
优缺点
正因有Cookie,才可以使用Session,游览器第一次请求时,会由服务器创建Session,响应时会把SessionID作为Cookie发送给游览器。
每个Session都有自己的SessionId,,这个Cookie的有效期持续到浏览器关闭(即有效期为默认值-1),这样当游览器每次进行新的请求时,都会把这个Cookie发送给服务器,服务器会认为这是同一个游览器,不会再为它创建新Session,而是让他使用它自己的Session
Session
Session是服务器的,在服务器中
一个服务器对于一个游览器仅保持一个会话
获取Session并设置
// 1.使用request获取Session
HttpSession session = request.getSession();
// 获取ID
System.out.println("SessionId 是:"+session.getId());
// 获取有效期 ,默认值 30分钟
System.out.println("有效期:" +session.getMaxInactiveInterval());
// 1.1修改有效期 单位秒
session.setMaxInactiveInterval(10*60);
// 1.2使用配置文件
<!-- 修改Session有效期-->
<session-config>
<!-- 单位:分钟-->
<session-timeout>60</session-timeout>
</session-config>
使用Session保存数据
// 使用session保存数据
// 1.设置数据
session.setAttribute("age", "18");
// 2.获取数据
session.getAttribute("age");
// 3.删除数据
session.removeAttribute("age");
获取访问时间和最后一次访问时间
session的有效期是从最后一次访问时间开始计算
// 获取session的创建时间
Instant instant = new Date(session.getCreationTime()).toInstant();
// 获取session的最后一次访问时间
Instant date1 = new Date(session.getLastAccessedTime()).toInstant();
Session失效
浏览器关闭,session只是失效,并没有清除,有效期过了,服务器会把它清除,但是会为什么失效,是因为存在客户端中的存有sessionid的cookie没有了。
Cookie禁用解决方案
一旦Cookie禁用,Cookie与Session将都难以使用
另一种实现
response.encodeURL(String url)
第一次访问时生成带jsssessionid的地址,第二次访问发现有请求中有cookie传来,此方法判断游览器未禁用Cookie,就不会在生成带jsssessionid的地址;但如果第二次访问时发现没有Cookie传来,判断游览器禁用Cookie,以后每次生成的地址都会带jss sessionid。
ServletContext
全局对象,所有用户均可使用
// 1.获取ServletContext
// 1.1 通过ServletContext方法
ServletContext app1 = getServletContext();
// 1.2 通过request
ServletContext aoo2 = request.getServletContext();
// 1.2 通过Session
ServletContext app3 = request.getSession().getServletContext();
获取应用上下文路径另一种方法
request.getContextPath();
可用于设置cookie的有效路径,无论本应用名如何变化,访问本应用都会使游览器发送cookie
cookie.setPath(request.getContextPath());
类加载器读取java项目下out目录或web项目中out目录下classes目录下的文件,读取这两个目录中的文件时使用类加载器。其他选用真实目录
在out目录中寻找,而项目真实路径以web应用目录为根,可以用于读取Web应用目录下的任意文件,即web应用中的任意文件
真实路径与上下文路径区别
String realPath1 = app1.getRealPath("/img/001.jpg");
输出F:\month8\0831web2\out\artifacts\0831web2_war_exploded\img\001.jpg
会找到本地的真实路径
String realPath = app1.getRealPath("/");
F:\month8\0831web2\out\artifacts\0831web2_war_exploded\
应用上下文路径: /0831web 是自己配置的,访问时的路径
使用真实目录,读取文件并输出到网页中
ServletContext servletContext = getServletContext();
String realPath = servletContext.getRealPath("/img/kekeluo.jpg");
ServletOutputStream outputStream = response.getOutputStream();
FileInputStream fis =new FileInputStream(realPath);
byte[] bytes = new byte[1024];
int len = 0;
// 设置响应头,使得游览器保存文件,而不是打开文件;;使用URLEncode使得能保存中文名字
response.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode("哈哈.jpg", "utf-8"));
while ((len = fis.read(bytes))!=-1){
outputStream.write(bytes,0,len);
}
fis.close();
状态管理
域对象
扩展 验证码
生成图片验证码,使用ValidateCode包
@WebServlet(name = "CodeServlet",value = "/codeservlet")
public class CodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 生成图片验证码
// 四个参数:生成图片width宽度,height高度,单位像素,codeCount验证码字符数,lineCount乱线条数
ValidateCode code = new ValidateCode(100,30,4,20 );
// 将code加入session中,以便验证,getCode方法可将验证码所含字符
request.getSession().setAttribute("code",code.getCode());
// 把图片验证码写到响应
code.write(response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
使用位置
<img src="codeservlet">