
本文共 22215 字,大约阅读时间需要 74 分钟。
web学习(三)
1.内容简介
1.1 说明
本篇内容接上篇
相关内容:、、、、
1.2 内容概述
本篇文章主要内容有以下几点:
- 会话技术
- Cookie
- Session
- JSP:入门学习
2.会话技术
2.1 概述
会话:客户端和服务器之间的请求响应过程。类似于生活中人与人之间的交谈
2.2 特点
一次会话中包含多次请求和响应
一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到一方断开为止
2.3 功能
功能:在一次会话的范围内的多次请求间,共享数据
2.4 方式
- 客户端会话技术:Cookie
- 服务器端会话技术:Session
3.Cookie
3.1 概念
概念:客户端会话技术,将数据保存到客户端
3.2 快速入门
使用步骤:
- 创建Cookie对象,绑定数据
- new Cookie(String name,String value)
- 发送Cookie对象
- response.addCookie(Cookie cookie)
- 获取Cookie,拿到数据
- Cookie[] request.getCookies()
package cn.web.cookie;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * Cookie快速入门 */@WebServlet("/CookieDemo1")public class CookieDemo1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.创建Cookie对象 Cookie cookie = new Cookie("msg","hello"); //2.发送Cookie response.addCookie(cookie); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }}
package cn.web.cookie;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * Cookie快速入门 */@WebServlet("/CookieDemo2")public class CookieDemo2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //3.获取Cookie Cookie[] cookies = request.getCookies(); //获取数据:遍历cookies if (cookies != null) { for (Cookie cookie : cookies) { String name = cookie.getName(); String value = cookie.getValue(); System.out.println(name+":"+value); } } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }}
3.3 实现原理
基于响应头Set-Cookie:和请求头Cookie实现
Set-Cookie:msg=hello
Cookie: msg=hello; Idea-f553bdfa=62966084-8612-4dfe-afb9-51e7478d4bbe
3.4 Cookie的细节
-
一次可不可以发送多个cookie?
可以
可以创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可
package cn.web.cookie;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/CookieDemo3")public class CookieDemo3 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.创建Cookie对象 Cookie cookie1 = new Cookie("msg","hello"); Cookie cookie2 = new Cookie("name","zhangsan"); //2.发送Cookie response.addCookie(cookie1); response.addCookie(cookie2); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }}
-
cookie在浏览器中保存多长时间?
-
默认情况下,当浏览器关闭后,Cookie数据被销毁
-
持久化存储:
setMaxAge(int seconds)
- 正数:将Cookie数据写到硬盘文件中。持久化存储。Cookie存活时间
- 负数:默认值
- 零:删除Cookie信息
package cn.web.cookie;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/CookieDemo4")public class CookieDemo4 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.创建Cookie对象 Cookie cookie1 = new Cookie("msg","setMaxAge"); //2.设置Cookie的存活时间// cookie1.setMaxAge(30);//将Cookie持久化到硬盘,30秒后自动删除Cookie文件// cookie1.setMaxAge(-5);//默认值// cookie1.setMaxAge(300); cookie1.setMaxAge(0);//删除Cookie信息 //2.发送Cookie response.addCookie(cookie1); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }}
-
-
cookie能不能存中文?
在tomcat 8 之前,cookie中不能直接存储中文数据
- 需要将中文数据转码–一般采用URL编码(%B3)
在tomcat 8 之后,cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,使用URL解码解析
package cn.web.cookie;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet("/CookieDemo5")public class CookieDemo5 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.创建Cookie对象 Cookie cookie1 = new Cookie("msg","你好"); //2.发送Cookie response.addCookie(cookie1); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }}
-
cookie共享问题?
假设在一个tomcat服务器中部署多个web项目,那么这些web项目的cookie能不能共享?
- 默认情况下cookie不能共享
- setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录
- 如果要共享,则可以将path设置为“/”
不同tomcat服务器间cookie共享问题?
- setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
- 例如:setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享
3.5 Cookie特点和作用
- cookie存储数据在客户端浏览器
- 浏览器对于单个cookie的大小有限制(4kb)以及 对同一个域名下的总cookie数量也有限制(20个)
作用:
- cookie一般用于存储少量不太敏感的数据
- 在不登录的情况下,完成服务器对客户端的身份识别
4.案例
4.1 需求
- 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问
- 如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:显示时间字符串
4.2 分析
-
可以采用cookie完成
-
在服务器中的Servlet中判断是否有一个名为lastTime的cookie
有:不是第一次访问
- 响应数据:欢迎回来,您上次访问时间为:2021年4月6日10:05:57
- 写回cookie:lastTime=2021年4月6日10:05:57
没有:是第一次访问
- 响应数据:您好,欢迎您首次访问
- 写回cookie:lastTime=2021年4月6日10:05:57
4.3 实现代码
package cn.web.cookie;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.net.URLDecoder;import java.net.URLEncoder;import java.text.SimpleDateFormat;import java.util.Date;/** 在服务器中的Servlet中判断是否有一个名为lastTime的cookie 有:不是第一次访问 1. 响应数据:欢迎回来,您上次访问时间为:2021年4月6日10:05:57 2. 写回cookie:lastTime=2021年4月6日10:05:57 没有:是第一次访问 1. 响应数据:您好,欢迎您首次访问 2. 写回cookie:lastTime=2021年4月6日10:05:57 */@WebServlet("/CookieTest1")public class CookieTest1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); //1.获取所有cookie Cookie[] cookies = request.getCookies(); //设置标识,判断是否第一次访问 boolean flag = true; //2.遍历cookie数组 if (cookies != null && cookies.length > 0){ for (Cookie cookie: cookies){ //3.获取cookie名称 String name = cookie.getName(); //4.判断cookie名是否为lastTime if (name.equals("lastTime")){ flag = false;//不是第一次访问 //获取时间,设置cookie值为时间字符串格式 Date date = new Date(); SimpleDateFormat sdate = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String str_date = sdate.format(date); //URL编码 System.out.println("编码前:"+str_date); str_date = URLEncoder.encode(str_date, "utf-8"); System.out.println("编码后:"+str_date); cookie.setValue(str_date); //设置cookie存活时间 cookie.setMaxAge(60*60*24*30);//一个月 //发送cookie response.addCookie(cookie); //响应数据 String value = cookie.getValue(); //URL解码 System.out.println("解码前:"+value); value = URLDecoder.decode(value, "utf-8"); System.out.println("解码后:"+value); response.getWriter().write("欢迎回来,您上次访问时间为:"+value+"
"); break; } } } if (cookies == null || cookies.length == 0 || flag){ flag = false;//是第一次访问 //获取时间,设置cookie值为时间字符串格式 Date date = new Date(); SimpleDateFormat sdate = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String str_date = sdate.format(date); //URL编码 System.out.println("编码前:"+str_date); str_date = URLEncoder.encode(str_date, "utf-8"); System.out.println("编码后:"+str_date); Cookie cookie = new Cookie("lastTime",str_date); //设置cookie存活时间 cookie.setMaxAge(60*60*24*30); //发送cookie response.addCookie(cookie); //响应数据 response.getWriter().write("您好,欢迎您首次访问
"); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }}
5.JSP入门
5.1 概述
JSP(Java Server Pages):Java服务器端页面
可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义Java代码
用于简化书写!!!
JSP(全称JavaServer Pages)是由[Sun Microsystems](https://baike.baidu.com/item/Sun Microsystems)公司主导创建的一种标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成、或其他格式文档的网页,然后返回给请求者。JSP技术以语言作为,为用户的请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求
JSP将Java代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,动态生成其中的部分内容。JSP引入了被称为“JSP动作”的XML标签,用来调用内建功能。另外,可以创建JSP标签库,然后像使用标准HTML或XML标签一样使用它们。标签库能增强功能和服务器性能,而且不受问题的限制。JSP文件在运行时会被其编译器转换成更原始的代码。JSP编译器可以把JSP文件编译成用Java代码写的Servlet,然后再由Java编译器来编译成能快速执行的二进制,也可以直接编译成二进制码
5.2 原理
jsp本质上就是一个Servlet
5.3 JSP脚本
jsp定义Java代码的方式
- <% Java代码 %>:定义的Java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么
- <%! Java代码 %>:定义的Java代码,在jsp转换后的Java类的成员变量
- <%= Java代码 %>:定义的Java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么
<%@ page contentType="text/html;charset=UTF-8" language="java" %>Title <% System.out.println("hello jsp"); %> <% int i = 3; %> <%! int i = 5; %> <%= i %> <%= "hello" %> System.out.println("hello jsp");JSP
5.4 JSP内置对象
在jsp页面中不需要获取和创建,可以直接使用的对象
jsp一共有9个内置对象
今天学习3个:
-
request
-
response
-
out:字符输出流对象。可以将数据输出到页面上。和response.getWriter()类似
response.getWriter()和out.write()的区别:
- 在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据
- response.getWriter()数据输出永远在out.write()之前
5.5 JSP编写案例
<%@ page import="java.util.Date" %><%@ page import="java.text.SimpleDateFormat" %><%@ page import="java.net.URLEncoder" %><%@ page import="java.net.URLDecoder" %><%@ page contentType="text/html;charset=UTF-8" language="java" %>Title <% //1.获取所有cookie Cookie[] cookies = request.getCookies(); //设置标识,判断是否第一次访问 boolean flag = true; //2.遍历cookie数组 if (cookies != null && cookies.length > 0){ for (Cookie cookie: cookies){ //3.获取cookie名称 String name = cookie.getName(); //4.判断cookie名是否为lastTime if (name.equals("lastTime")){ flag = false;//不是第一次访问 //获取时间,设置cookie值为时间字符串格式 Date date = new Date(); SimpleDateFormat sdate = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String str_date = sdate.format(date); //URL编码 System.out.println("编码前:"+str_date); str_date = URLEncoder.encode(str_date, "utf-8"); System.out.println("编码后:"+str_date); cookie.setValue(str_date); //设置cookie存活时间 cookie.setMaxAge(60*60*24*30);//一个月 //发送cookie response.addCookie(cookie); //响应数据 String value = cookie.getValue(); //URL解码 System.out.println("解码前:"+value); value = URLDecoder.decode(value, "utf-8"); System.out.println("解码后:"+value); %>欢迎回来,您上次访问时间为:<%= value %>
<% break; } } } if (cookies == null || cookies.length == 0 || flag){ flag = false;//是第一次访问 //获取时间,设置cookie值为时间字符串格式 Date date = new Date(); SimpleDateFormat sdate = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String str_date = sdate.format(date); //URL编码 System.out.println("编码前:"+str_date); str_date = URLEncoder.encode(str_date, "utf-8"); System.out.println("编码后:"+str_date); Cookie cookie = new Cookie("lastTime",str_date); //设置cookie存活时间 cookie.setMaxAge(60*60*24*30); //发送cookie response.addCookie(cookie); //响应数据 %>您好,欢迎您首次访问
<% } %>
6.Session
6.1 概述
概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
6.2 快速入门
-
获取HttpSession对象:
- HttpSession session = request.getSession();
-
使用HttpSession对象:
- Object getAttribute(String name)
- void setAttribute(String name,Object value)
- void removeAttribute(String name)
package cn.web.session;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.io.IOException;@WebServlet("/SessionDemo1")public class SessionDemo1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取session HttpSession session = request.getSession(); //2.获取数据 session.setAttribute("msg","hello session"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }}
@WebServlet("/SessionDemo2")public class SessionDemo2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //使用session获取数据 //1.获取session HttpSession session = request.getSession(); //2.获取数据 Object msg = session.getAttribute("msg"); System.out.println(msg); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }}
6.3 原理
session的实现是依赖于cookie的
6.4 细节
-
当客户端关闭后,服务器不关闭,两次获取的session是否为同一个?
-
默认情况下:不是
-
如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存
Cookie cookie = new Cookie(“JSESSIONID”, session.getId());
cookie.setMaxAge(60); response.addCookie(cookie);
@WebServlet("/SessionDemo3")public class SessionDemo3 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取session HttpSession session = request.getSession(); System.out.println(session); //JSESSIONID=3B347FAECDA509974C04E65AD0DCE7CF // //2.期望客户端关闭后,session也能相同 Cookie cookie = new Cookie("JSESSIONID", session.getId()); cookie.setMaxAge(60); response.addCookie(cookie); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }}
-
-
客户端不关闭,服务器关闭后,两次获取的session是否为同一个?
- 不是同一个,但是要确保数据不丢失
- session的钝化:在服务器正常关闭之前,将session对象系列化到硬盘
- session的活化:在服务器启动后,将session文件转化为内存中的session对象即可
-
session的失效时间?
-
服务器关闭
-
session对象调用invalidate()。
-
session默认失效时间 30分钟
选择性配置修改
<session-config>
<session-timeout>30</session-timeout>
</session-config>
-
6.5 特点
- session用于存储一次会话的多次请求的数据,存在服务器
- session可以存储任意类型,任意大小的数据
session和cookie的区别:
- session存储数据在服务器端,cookie在客户端
- session存储数据没有大小限制,cookie有
- session数据安全,cookie相对于不安全
7.案例
7.1 需求:
- 访问带有验证码的登录页面login.jsp
- 用户输入用户名,密码,以及验证码
- 如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误
- 如果验证码输入有误,跳转登录页面,提示:验证码错误
- 如果全部输入正确,则跳转到主页success.jsp,显示:用户名,欢迎您
7.2 分析
7.3 实现
package cn.web.servlet;import cn.web.domain.User;import cn.web.domain.UserDao;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.io.IOException;import java.util.Map;import java.util.Set;@WebServlet("/loginServlet")public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.设置request编码 request.setCharacterEncoding("utf-8"); //2.获取参数map String username = request.getParameter("username"); String password = request.getParameter("password"); String checkCode = request.getParameter("checkCode"); //3.先获取生成的验证码 HttpSession session = request.getSession(); String checkCode_session = (String) session.getAttribute("checkCode_session"); //删除session中存储的验证码 session.removeAttribute("checkCode_session"); //3.先判断验证码是否正确 if (checkCode_session != null && checkCode_session.equalsIgnoreCase(checkCode)) { //忽略大小写比较// UserDao dao = new UserDao();// User user = dao.login(username, password);// //判断用户名和密码是否一致// if (user.getUsername().equals(username) && user.getPassword().equals(password)) {//需要调用UserDao查询数据库 if ("zhangsan".equals(username) && "123".equals(password)) { //登录成功 //存储信息,用户信息 session.setAttribute("user", username); //重定向到success.jsp response.sendRedirect(request.getContextPath() + "/success.jsp"); } else { //登录失败 //存储提示信息到request request.setAttribute("login_error", "用户名或密码错误"); //转发到登录页面 request.getRequestDispatcher("/login.jsp").forward(request, response); } } else { //验证码不一致 //存储提示信息到request request.setAttribute("cc_error", "验证码错误"); //转发到登录页面 request.getRequestDispatcher("/login.jsp").forward(request, response); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); }}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>login
package cn.web.servlet;import javax.imageio.ImageIO;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import java.awt.*;import java.awt.image.BufferedImage;import java.io.IOException;import java.util.Random;@WebServlet("/checkCodeServlet")public class CheckCodeServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int width = 100; int height = 50; //1.创建一个对象,在内存中图片(验证码图片对象及) BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); //2.美化图片 //2.1 填充背景色 Graphics g = image.getGraphics();//画笔对象 g.setColor(Color.pink);//设置画笔颜色 g.fillRect(0,0,width,height); //2.2 画边框 g.setColor(Color.blue); g.drawRect(0,0,width-1,height-1); String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; //生成随机角标 Random r = new Random(); StringBuilder sb = new StringBuilder(); for (int i = 1; i <= 4; i++) { int index = r.nextInt(str.length()); //获取字符 char ch = str.charAt(index);//随机字符 sb.append(ch); //2.3 写验证码 g.drawString(ch+"",width/5*i,height/2); } String checkCode_session = sb.toString(); //将验证码存入session HttpSession session = request.getSession(); session.setAttribute("checkCode_session",checkCode_session); //2.4 画干扰线 g.setColor(Color.green); int i =0; while ( i <= 10){ int x1 = r.nextInt(width); int x2 = r.nextInt(width); int y1 = r.nextInt(height); int y2 = r.nextInt(height); if ((x2-x1)>80 || (y2-y1)>30) { i++; g.drawLine(x1, x2, y1, y2); } } //3.将图片输出到页面展示 ImageIO.write(image,"jpg",response.getOutputStream()); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); }}
发表评论
最新留言
关于作者
