summarize
session就是专门存服务器的 一个客户端一个区域,Http一共三个域,session能存中文,cookie不能存中文
学习session 主要考虑三个问题 :1 怎样获得 2.怎样存取 session对象(内存区域) 3.session对象生命周期
客户端端不同 JSESSIONID就不同,一个客户端只能存在一个session,清理了缓存后,JSESSIONID会从新导入
创建和访问session的顺序是 先设置 在获取,当关闭客户端后,在访问,就获取不到了,显示空指针
session持久化:跟Cookie一样:从新建一个设置时间的session头 覆盖原来的session
JSP:它本身就是一个Servlet。第一行
jsp有三大指令:① page(最常用) ② include(一个页面包含另一个页面) ③ taglib 搭配jstl标签使用
language:声明jsp只能嵌套 java语言。contenType:解决response中文乱码,pageEncoding:当前jsp页面的中文乱码。属性session:默认true
原理图
1.获得Session对象
HttpSession session = request.getSession();
此方法会获得专属于当前会话的Session对象,如果服务器端没有该会话的Session 对象会创建一个新的Session返回,如果已经有了属于该会话的Session直接将已有的Session返回(实质就是根据JSESSIONID判断该客户端是否在服务器上已经存在 session了)
2.向session存取数据(session也是一个域对象)
三个方法:
session.setAttribute(String name,Object obj);
session.getAttribute(String name);
session.removeAttribute(String name);
package com.oracle.demo01; //创建Session向里面存数据 import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class SessionServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取Session对象 HttpSession session=request.getSession(); // 向session域中存储数据 session.setAttribute("goods","奶瓶"); // 获取JSESSIONID String id=session.getId(); // 创建Cookie Cookie cookie=new Cookie("JSESSIONID",id); cookie.setPath("/WEB08"); cookie.setMaxAge(60);//设置持久化时间 // 发送Cookie response.addCookie(cookie); response.getWriter().write("JSESSIONID:"+id); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } --------------------------------------------- package com.oracle.demo01; //获取Session对象的内容 import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class Servlet02 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取Session对象 HttpSession session=request.getSession();//这里获取的是内存里的session // 获取session中的内容 这里getattribute得到obj 需要向下转型(强转) String goods=(String)session.getAttribute("goods"); // 解决乱码 response.setContentType("text/html;charset=utf-8"); response.getWriter().write(goods); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
获取session内容的原理是,先打开已经设置好的session,然后在获取,当客户端关闭后,session的值就消失,因为 获取的内容已关闭,空指针无法强转 只会显示空指针
3.Session对象的生命周期(面试题/笔试题)
创建:第一次执行request.getSession()时创建
销毁:
1)服务器(非正常)关闭时
2)session过期/失效(默认30分钟)
问题:时间的起算点 从何时开始计算30分钟?
从不操作服务器端的资源开始计时
可以在工程的web.xml中进行配置
<session-config>
<session-timeout>30</session-timeout>
</session-config>
3)手动销毁session
session.invalidate();
设置登录验证码
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE html> 4 <html> 5 <head> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <title>会员登录</title> 8 <link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" /> 9 <script src="js/jquery-1.11.3.min.js" type="text/javascript"></script> 10 <script src="js/bootstrap.min.js" type="text/javascript"></script> 11 <!-- 引入自定义css文件 style.css --> 12 <link rel="stylesheet" href="css/style.css" type="text/css" /> 13 14 <style> 15 body { 16 margin-top: 20px; 17 margin: 0 auto; 18 } 19 20 .carousel-inner .item img { 21 100%; 22 height: 300px; 23 } 24 25 .container .row div { 26 /* position:relative; 27 float:left; */ 28 29 } 30 31 font { 32 color: #666; 33 font-size: 22px; 34 font-weight: normal; 35 padding-right: 17px; 36 } 37 </style> 38 <script type="text/javascript"> 39 function change(node){ /* node是 自定义 */ 40 node.src="/Shop/CheckImgServlet?time="+new Date().getTime(); 41 } 42 </script> 43 </head> 44 <body> 45 46 <!-- 引入header.jsp --> 47 <jsp:include page="/header.jsp"></jsp:include> 48 49 50 <div class="container" 51 style=" 100%; height: 460px; background: #FF2C4C url('images/loginbg.jpg') no-repeat;"> 52 <div class="row"> 53 <div class="col-md-7"> 54 <!--<img src="./image/login.jpg" width="500" height="330" alt="会员登录" title="会员登录">--> 55 </div> 56 57 <div class="col-md-5"> 58 <div 59 style=" 440px; border: 1px solid #E7E7E7; padding: 20px 0 20px 30px; border-radius: 5px; margin-top: 60px; background: #fff;"> 60 <font>会员登录</font>USER LOGIN 61 <!-- <%-- <%=%> --%> 相当于往页面输出代码 --> 62 <div><%=request.getAttribute("info")==null?"":request.getAttribute("info") %></div> 63 <form class="form-horizontal" action="/Shop/LoginServlet" method="post"> 64 <div class="form-group"> 65 <label for="username" class="col-sm-2 control-label">用户名</label> 66 <div class="col-sm-6"> 67 <input type="text" class="form-control" id="username" 68 placeholder="请输入用户名" name="username"> 69 </div> 70 </div> 71 <div class="form-group"> 72 <label for="inputPassword3" class="col-sm-2 control-label">密码</label> 73 <div class="col-sm-6"> 74 <input type="password" class="form-control" id="inputPassword3" 75 placeholder="请输入密码" name="password"> 76 </div> 77 </div> 78 <div class="form-group"> 79 <label for="inputPassword3" class="col-sm-2 control-label">验证码</label> 80 <div class="col-sm-3"> 81 <input type="text" class="form-control" id="inputPassword3" 82 placeholder="请输入验证码" name="checkcode"> 83 </div> 84 <div class="col-sm-3"> 85 <img src="/Shop/CheckImgServlet" onClick="change(this)"/> 86 </div> 87 </div> 88 <div class="form-group"> 89 <div class="col-sm-offset-2 col-sm-10"> 90 <div class="checkbox"> 91 <label> <input type="checkbox"> 自动登录 92 </label> <label> <input 93 type="checkbox"> 记住用户名 94 </label> 95 </div> 96 </div> 97 </div> 98 <div class="form-group"> 99 <div class="col-sm-offset-2 col-sm-10"> 100 <input type="submit" width="100" value="登录" name="submit" 101 style="background: url('./images/login.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0); height: 35px; 100px; color: white;"> 102 </div> 103 </div> 104 </form> 105 </div> 106 </div> 107 </div> 108 </div> 109 110 <!-- 引入footer.jsp --> 111 <jsp:include page="/footer.jsp"></jsp:include> 112 113 </body> 114 </html>
当输入验证码时, 验证码在 82行 ,起名为 checkcode,产生的验证码放在session域里面,
修改LoginServlet 从13行到38行
1 package com.oracle.web; 2 3 import java.io.IOException; 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 import com.oracle.service.UserService; 9 10 public class LoginServlet extends HttpServlet { 11 private UserService userService=new UserService(); 12 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 13 // 解决中文乱码 14 request.setCharacterEncoding("utf-8"); 15 // 获取用户输入的验证码 16 String checkcode=request.getParameter("checkcode"); 17 // 获取session域中验证码 18 String code=(String)request.getSession().getAttribute("checkcode_session"); 19 // 当两个验证码不匹配的话 20 if(!checkcode.equals(code)){ 21 request.setAttribute("info","验证码错误"); 22 request.getRequestDispatcher("/login.jsp").forward(request, response); 23 } 24 // 获取用户名 25 String username=request.getParameter("username"); 26 // 获取密码 27 String password=request.getParameter("password"); 28 // 调用service层的方法 29 int count=userService.login(username,password); 30 // 如果登录成功 31 if(count>0){ 32 // 重定向 获取 web应用名称request 设置用get 33 response.sendRedirect(request.getContextPath()+"/index.jsp");//这里跳转首页 34 }else{ 35 // 如果登录不成功 因这句话只需要在这次请求中用 so 用request域对象的setAttribute 36 request.setAttribute("info","用户名或密码错误"); 37 // 请求转发 这里服务器内部行为不需要写项目名 38 request.getRequestDispatcher("/login.jsp").forward(request, response);//获取转发器 39 } 40 } 41 42 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 43 doGet(request, response); 44 } 45 }
pm
JSP技术
1.jsp脚本和注释
jsp脚本:
1)<%java代码%> ----- 内部的java代码翻译到service方法的内部 注意: 不+! 不可以定义方法
2)<%=java变量或表达式%> ----- 会被翻译成service方法内部out.print()
3)<%!java代码%> ---- 会被翻译成servlet的成员的内容 注意:+!的可定义方法
jsp注释:不同的注释可见范围是不同
1)Html注释:<!--注释内容--> ---可见范围 jsp源码、翻译后的servlet、页面 显示html源码
2)java注释://单行注释 /*多行注释*/ --可见范围 jsp源码 翻译后的servlet
3)jsp注释:<%--注释内容--%> ----- 可见范围 jsp源码可见
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <!-- 这是HTML注释 --> <% //这是java单行注释 /*这是java多行注释*/ int i=100; System.out.println(i); %> <%--这是jsp注释 --%> <%=i %> <%! String str="袁一鸣" ;%> <%=str %> </body> </html>
2.jsp运行原理-----jsp本质就是servlet(面试)
jsp在第一次被访问时会被Web容器翻译成servlet,在执行过程:
第一次访问---->helloServlet.jsp---->helloServlet_jsp.java---->编译运行
PS:被翻译后的servlet在Tomcat的work目录中可以找到
3.jsp指令(3个)
jsp的指令是指导jsp翻译和运行的命令,包括三大指令:
1)page指令 --- 属性最多的指令(实际开发中page指令默认)
属性最多的一个指令,根据不同的属性,指导整个页面特性
格式:<%@ page 属性名1= "属性值1" 属性名2= "属性值2" ...%>
常用属性如下:
language:jsp脚本中可以嵌入的语言种类
pageEncoding:当前jsp文件的本身编码---内部可以包含contentType
contentType:response.setContentType(text/html;charset=UTF-8)
session:是否jsp在翻译时自动创建session 默认是true 看代码
<%@page import="java.util.ArrayList"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" session="false" errorPage="error.jsp"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% int y=1/0; HttpSession session=request.getSession(); session.setAttribute("goods","naiping"); %> <% ArrayList<String> arr=new ArrayList<String>(); %> </body> </html>
import:导入java的包 手动(在第一行后面+import属性)或者 alt+/
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> 这是一个处理错误页面 </body> </html>
errorPage:当当前页面出错后跳转到哪个页面
isErrorPage:当前页面是一个处理错误的页面
2)include指令
页面包含(静态包含)指令,可以将一个jsp页面包含到另一个jsp页面中
格式:<%@ include file="被包含的文件地址"%>
在WebContext目录上建三个jsp head.jsp 、body.jsp 、footer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> 这是头部 </body> </html> -------------------------------------------------------- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <%@ include file="header.jsp" %> 这是内容 <%@ include file="footer.jsp" %> </body> </html> ---------------------------------------------------------- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> 这是尾部 </body> </html>
3)taglib指令
在jsp页面中引入标签库(jstl标签库、struts2标签库)
格式:<%@ taglib uri="标签库地址" prefix="前缀"%>