当前位置:网站首页>Cookie & Session & kaptcha验证码
Cookie & Session & kaptcha验证码
2022-06-12 18:52:00 【苏瞳呐】
文章目录
Cookie
1. 概念
是服务器通知客户端保存键值对的一种技术。
cookie 是 servlet(服务器) 发送到 Web 浏览器(客户端)的少量信息,这些信息由浏览器保存,然后发送回服务器。
客户端有了 cookie 后,每次请求都发送给服务器
每个 cookie 的大小不能超过 4 KB。
2. 创建Cookie
protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//1. 创建Cookie对象
Cookie cookie = new Cookie("key1", "value1");
//2. 通知客户端保存
resp.addCookie(cookie);
resp.getWriter().write("Cookie创建成功");
}
3. 服务器获取Cookie
protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
//System.out.println(cookie);
resp.getWriter().write("Cookie["+ cookie.getName() + " = " + cookie.getValue() + "] <br/>");
}
// 查找特定的Cookie (项目中会把这个写成工具类)
Cookie need = null;
for (Cookie cookie : cookies) {
if ("key2".equals(cookie.getName())) {
need = cookie;
break;
}
}
if (need != null) {
// 不等于null,说明赋过值
resp.getWriter().write("找到了需要的Cookie");
}
}
CookieUtils.java
// 查找特定的Cookie
public static Cookie findCookie(Cookie[] cookies, String name) {
if (cookies == null || name == null || cookies.length == 0) {
return null;
}
for (Cookie cookie : cookies) {
if (name.equals(cookie.getName())) {
return cookie;
}
}
return null;
}
4. Cookie的修改
protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) {
// 第一种
// 修改需要先创建同key的Cookie对象,新值直接构造传入就行
Cookie newCookie1 = new Cookie("key1", "newValue1");
resp.addCookie(newCookie1); // 保存修改
// 第二种
Cookie newCookie2 = CookieUtils.findCookie(req.getCookies(), "key2");
if (newCookie2 != null) {
newCookie2.setValue("newValue2"); // !注意不支持中文和一些符号,需要的话可以使用BASE64编码
resp.addCookie(newCookie2);
}
}
5. Cookie的生命控制
Cookie的生命控制,即Cookie什么时候销毁
API:setMaxAge(int expiry)
- 正值表示 cookie 将在经过该值表示的秒数后过期 (关闭浏览器再次访问还在)
- 负值意味着 cookie 不会被持久存储,将在 Web 浏览器退出时删除 (默认是负数,-1)
- 0 值表示马上删除 cookie。
修改后记得 resp.addCookie(cookie);
6. Cookie的有效路径Path
有效路径Path 可以过滤哪些Cookie可以发送给服务器,那些不发。
Path是通过请求的地址来进行有效的过滤
例如:
cookie1 path=/工程路径
cookie2 path=/工程路径/abc
请求地址: (默认是当前的工程路径)
http://ip:port/工程路径/a.html
则cookie1会发送给服务器,cookie2不发送
http://ip:port/工程路径/abc/d.html
cookie2,cookie1都发送!!
Cookie cookie = new Cookie("path1", "path1");
cookie.setPath(req.getContextPath() + "/abc"); // -> /工程路径/abc
7. Cookie应用-免用户名密码登录
前端:login.jsp
<form action="/dynamicobject/loginServlet" method="post">
用户名: <input type="text" name="username" value="${cookie.username.value}"> <br/>
密码: <input type="password" name="password" value="${cookie.password.value}"> <br/>
<input type="submit" value="登录">
</form>
后端:LoginServlet.java
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
String username = req.getParameter("username");
String password = req.getParameter("password");
// 这里可以去数据库查找,我们这里写死了
if ("sutong".equals(username) && "123456".equals(password)) {
Cookie c1 = new Cookie("username", username);
c1.setMaxAge(60 * 60 * 24 * 7); // 一周内有效
resp.addCookie(c1);
Cookie c2 = new Cookie("password", password); // 一般密码都会加密的
c2.setMaxAge(60 * 60 * 24 * 7);
resp.addCookie(c2);
System.out.println("登陆成功!");
} else {
System.out.println("登陆失败!");
}
}
}
Session
1. 概念
Session是一个接口(HttpSession),就是会话。
用来维护一个客户端和服务器之间关联的一种技术。
每个客户端都有它自己的一个Session。
Session会话中,我们经常用来保存用户登录之后的信息。
2. 创建和获取Session
创建和获取都是一个函数 request.getSession()
第一次调用是创建Session,之后调用都是获取前面创建好的Sesson会话对象
isNew()
: 判断是不是刚创建出来的(是不是新的)
getId()
: 每个会话都会有个唯一id值
protected void createOrGetSession(HttpServletRequest req, HttpServletResponse resp) throws IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
HttpSession session = req.getSession(); // 创建或获取Session
boolean flag = session.isNew(); // 判断是否刚创建
String id = session.getId(); // id
resp.getWriter().write("得到的Session的Id是" + id + "<br/>");
resp.getWriter().write("这个Session是否刚创建" + flag);
}
3. Session域数据的存取
存取:
HttpSession session = req.getSession();
session.setAttribute("key1", "value1");
获取:
String att = (String) req.getSession().getAttribute("key1"); // 返回的是Object
4. Session的生命周期的控制
API:public void setMaxInactiveInterval(int interval)
设置Session的超时时间(秒为单位),超过时长就会被销毁(是最大不活跃间隔!)
正数是超时时长,负数是永不超时。注意:0不是立即销毁,立即销毁是session.invalidate()
获取方法:public int getMaxInactiveInterval()
默认是1800秒,即半小时。
因为在Tomcat的服务器的配置文件web.xml中,有写<session-timeout>30</session-timeout>
如果我希望我们工程的Session不想是30分钟,可以在自己项目下的web.xml做以上相同的配置,就可以修改工程下所有Session的默认超时时长了。
<session-config>
<session-timeout>20</session-timeout> <!-- 分钟为单位-->
</session-config>
如果只想修改个别Session的超时时长,则需要使用session.setMaxInactiveInterval(interval)
方法
超时时长:指的是客户端两次请求的最大间隔时长!!
5. 浏览器和Session的关联
当客户端没有Cookie信息的时候,发送请求,服务器会(调用req.getSession())创建Session对象,每次创建Session会话的时候,都会创建一个Cookie对象,这个Cookie对象的key永远是:JSESSIONID,value是新创建出来的Session的Id。然后通过响应头返回给客户端。
当客户端有了这个Cookie之后,每次请求会把Session的Id以Cookie的形式发送给服务器,然后服务器这边会通过Id查找自己之前创建好的Session对象(调用req.getSession()),并返回。
如果上次创建的Session的没过期的时候,我们手动把Cookie信息删掉的话,服务器就没法通过得到id,就没法找到之前的那个Session对象,客户端发送请求的时候,服务器则会重新创建新的Session会话,重复上面的操作。
Session 技术,底层其实是基于 Cookie 技术来实现的
kaptcha验证码
验证码可以解决表单重复提交的情况
1. 使用
我们可以使用第三方的jar包,谷歌验证码,kaptcha-2.3.2.jar
- 导包
- 在 web.xml 中去配置用于生成验证码的Servlet程序 (即com.google.code.kaptcha.servlet.KaptchaServlet这个类,谷歌写的)
<servlet>
<servlet-name>KaptchaServlet</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>KaptchaServlet</servlet-name>
<!-- 注意这里改的访问名(看起来像个图片),这样的话访问这个就是自动生成验证码和图片,并保存到Session域-->
<url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
- 在表单中使用 img标签去显示验证码并使用它
<form action="" method="post">
用户名:<input type="text" name="username"> <br/>
密码:<input type="password" name="password"> <br/>
验证码:<input type="text" name="code"> <br/>
<img id="code_img" src="http://localhost:8080/book/kaptcha.jpg" alt="图片找不到"> <br/>
<input type="button" value="注册">
</form>
在服务器获取谷歌生成的验证码和客户端发来的验证码比较使用 (获取后记得马上删除)
获取谷歌生成的验证码 :
req.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
获取用户提交的验证码:
req.getSession().getAttribute("code")
2. 验证码的切换
// 给验证码图片绑定单机事件
$("#code_img").click(function () {
// 但这样每次发一样的请求,可能会被浏览器的缓存导致验证码无法改变,
// 缓存是根据工程名后面的资源名和参数产生的,所以我们可以在后面加上一个随机的参数跳过缓存
//this.src = "http://localhost:8080/book/kaptcha.jpg";
this.src = "http://localhost:8080/book/kaptcha.jpg?d=" + new Date(); // 可以加个时间戳
});
边栏推荐
- leetcode:98. Count the number of subarrays whose score is less than k [double pointers + number of calculated subsets + de duplication]
- bilibili视频列表名字太长显示不全的解决方法
- io.seata.common.exception.FrameworkException: can not connect to services-server.
- 基于halcon—缺陷检测常用方法与示例总结
- 快速复制浏览器F12中的请求到Postman/或者生成相关语言的对应代码
- Mise en œuvre de l'ACL réflexe dans le simulateur Cisco Cisco Packet Tracer
- Enhanced version of unit test code displayed by SAP e-commerce cloud Spartacus UI checkout spinner
- leetcode:6096. 咒语和药水的成功对数【排序 + 二分】
- leetcode:5270. 网格中的最小路径代价【简单层次dp】
- 观察网站的页面
猜你喜欢
Review of MySQL (VI): usage of Union and limit
Mise en œuvre de l'ACL réflexe dans le simulateur Cisco Cisco Packet Tracer
no available service ‘null‘ found, please make sure registry config correct
Review of MySQL (3): query operation
leetcode:6094. 公司命名【分组枚举 + 不能重复用set交集 + product笛卡儿积(repeat表示长度)】
从应无所住说起
Difference between rxjs of() and of ({})
leetcode:98. 统计得分小于 K 的子数组数目【双指针 + 计算子集个数 + 去重】
基于Halcon的矩形卡片【手动绘制ROI】的自由测量
Mysql ->>符号用法 Json相关
随机推荐
Vue —— 进阶 vue-router 路由(二)(replace属性、编程式路由导航、缓存路由组件、路由的专属钩子)
Mysql database (28): Variables
[blockbuster release] ant dynamic card, enabling the app home page to realize agile update
yoloe 目标检测使用笔记
Have a meal, dry pot, fat intestines + palm treasure!
leetcode:98. Count the number of subarrays whose score is less than k [double pointers + number of calculated subsets + de duplication]
A story on the cloud of the Centennial Olympic Games belonging to Alibaba cloud video cloud
lua记录
Chrome browser solves cross domain problems
leetcode:6095. 强密码检验器 II【简单模拟 + 不符合直接False】
国内如何下载Vega
Leetcode 1049. Weight of the last stone II
no available service ‘null‘ found, please make sure registry config correct
Two months later, my second listing anniversary [June 2, 2022]
Common methods and examples of defect detection based on Halcon
leetcode:5270. Minimum path cost in Grid [simple level DP]
The Bean Validation API is on the classpath but no implementation could be found
Getting started with the go language is simple: read / write lock
leetcode:5289. 公平分发饼干【看数据范围 + dfs剪枝】
【0008】无序列表