更改idea代码模板
会话技术
1. 会话:一次会话中包含多次请求和响应。
* 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
2. 功能:在一次会话的范围内的多次请求间,共享数据
3. 方式:
1. 客户端会话技术:Cookie
2. 服务器端会话技术:Session
Cookie:
1. 概念:客户端会话技术,将数据保存到客户端
2. 快速入门:
3. 实现过程:客户端申请,服务器响应,数据存储在本地,下次访问将存储在本地的数据一并发送过去,实现多次请求响应的数据共享,服务器发送和接收cookie
* 使用步骤:
1. 创建Cookie对象,绑定数据
* new Cookie(String name, String value)
2. 发送Cookie对象
* response.addCookie(Cookie cookie)
3. 获取Cookie,拿到数据
* Cookie[] request.getCookies()
使用super的时候出错了,?
封装cookie
//使用注解可以更加简便。其中有默认参数,例如loadstarup
@WebServlet("/head_easy")
//可以更加简化,将url省略掉,使用value就可以,进一步value也不用写
public class servlet_test extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("head_easy类");
System.out.println("dopost类");
// 获得cookie
Cookie[] cookies = req.getCookies();
if(cookies!=null){
for(Cookie c:cookies){
String cName = c.getName();
String cValue = c.getValue();
System.out.println(cName+cValue);
}
}
else{
System.out.println("cookie是空的");
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("head_easy类");
System.out.println("doget类");
this.doPost(req,resp);
}
}
解读cookie
//使用注解可以更加简便。其中有默认参数,例如loadstarup
@WebServlet("/head_easy")
//可以更加简化,将url省略掉,使用value就可以,进一步value也不用写
public class servlet_test extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("head_easy类");
System.out.println("dopost类");
// 获得cookie
Cookie[] cookies = req.getCookies();
if(cookies!=null){
for(Cookie c:cookies){
String cName = c.getName();
String cValue = c.getValue();
System.out.println(cName+cValue);
}
}
else{
System.out.println("cookie是空的");
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doget类");
this.doPost(req,resp);
}
}
如果是同一个浏览器存在缓存,不是同一个则报空
3. 实现原理
* 基于响应头set-cookie和请求头cookie实现
* 受协议约束,识别到响应头则将数据本地存储,下一次发送携带数据,
在一个web服务器下部署多个web项目
4. cookie的细节
-
一次可不可以发送多个cookie?
* 可以
* 可以创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可。
2. cookie在浏览器中保存多长时间?
1. 默认情况下,当浏览器关闭后,Cookie数据被销毁,即cookie此时存在于浏览器内存中,关闭即释放
2. 持久化存储:
* setMaxAge(int seconds)
1. 正数:将Cookie数据写到硬盘的文件中。持久化存储。并指定cookie存活时间,时间到后,cookie文件自动失效。关闭浏览器后30s内仍然有效,预示着网站登录的有效期,方便关闭后再登录
cookie.setxxx(0)
3. 负数:默认值,在内存
4. 零:删除cookie信息,cookie不在内存与硬盘,服务器不能直接操作客户端电脑信息,通过这种方式操作客户端电脑cookie,在cookie的存活时间内清除
3. cookie能不能存中文?
* 在tomcat 8 之前 cookie中不能直接存储中文数据。
* 需要将中文数据转码—一般采用URL编码(%E3)
* 在tomcat 8 之后,cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,URL解码解析
4. cookie多项目共享问题?
1. 假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
* 默认情况下cookie不能共享* setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录。统一服务器的不同项目有共享数据的需求 * 如果要共享,则可以将path设置为"/" 2. 不同的tomcat服务器间cookie共享问题? 3. 由于项目过大,分支过多,如果将资源部署在同一服务器上,那么服务器无法支持,因此多台服务器之间也有共享数据需求 * setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享 * setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享
-
Cookie的特点和作用
1. cookie存储数据在客户端浏览器,数据容易篡改和丢失
2. 浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20个)
* 作用:
1. cookie一般用于存出少量的不太敏感的数据
2. 在不登录的情况下,完成服务器对客户端的身份识别 -
案例:记住上一次访问时间
1. 需求:
1. 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎您首次访问。
2. 如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:显示时间字符串
使用cookie实现,判断特定名字的cookie是否存在,若存在则取出时间并更新时间显示回来标语,不存在则创建放入时间显示欢迎标语
但是cookie中的特殊字符,如空格不支持显示,应该对于特殊字符使用urlencoder编码
条件判断是否创建或者更新cookie
@WebServlet("/Test01_01")
public class Test01_01 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("01-01-dopostt");
// Cookie msg = new Cookie("MSG", "hello");
// msg.setPath("/");
// response.addCookie(msg);
// 回复消息有中文,因此加上响应头
response.setContentType("text/html;charset=utf-8");
// 获得所有的cookie
Cookie[] cookies = request.getCookies();
Boolean exit=false;
// 遍历所有的cookie,为什么要判断cookie长度
if(cookies!=null && cookies.length>0){
for(Cookie c:cookies){
// 如果有特定的cookie名字出现
if(c.getName().equals("last_time")){
exit=true;
// 返回上次的登录时间,为什么要使用url与解码,特殊字符?是空格一类
String decoded_time = URLDecoder.decode(c.getValue(), "utf-8");
response.getWriter().write("<h1>"+"欢迎回来"+decoded_time+"<h1>");
// 将当前时间值更新进入cookie中
Date date = new Date();
// 重新设定date显示格式,其默认为美国格式
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String formated_date = dateFormat.format(date);
// 将当前时间编码后存储
String encode_date = URLEncoder.encode(formated_date, "utf-8");
c.setValue(encode_date);
// 设置cookie存活时间
c.setMaxAge(24*60*60);
response.addCookie(c);
}
else{
// response.getWriter().write("有cookieda都不符合条件");
}
// 找到就推出循环
break;
}
}
// 判断需要的文件是否存在,如果不存在就创建
if(cookies==null || cookies.length==0 || exit==false){
// 将当前时间值更新进入cookie中
Date date = new Date();
// 重新设定date显示格式,其默认为美国格式
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年mm月dd日 HH:mm:ss");
String formated_date = dateFormat.format(date);
// 将当前时间编码后存储
String encode_date = URLEncoder.encode(formated_date, "utf-8");
Cookie c = new Cookie("last_time", encode_date);
// 设置cookie存活时间
c.setMaxAge(24*60*60);
response.addCookie(c);
response.getWriter().write("您首次登录");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("01-01-doget");
this.doPost(request, response);
}
}
JSP:入门学习
1. 概念:
* Java Server Pages: java服务器端页面
* 可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码
* 用于简化书写,将java与html结合在一起
2. 原理
* JSP本质上就是一个Servlet
配置在这个文件夹中,work下index变成了class,work存放运行时生成的资源文件
jsp-java-httpJspBase内部类,-httpserverlet
service方法将html基本元素输出,将页面元素进行了封装便于调用,相当于附加了一个解释器,所以简化了书写
3. JSP的脚本:JSP定义Java代码的方式
1. <% 代码 %>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么,定义局部变量,作用范围小。
2. <%! 代码 %>:定义的java代码,在jsp转换后的java类的成员位置,就是成员变量一类,为什么不写在上面一起?不常用,作用范围比较大。。
3. <%= 代码 %>:定义的java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么,页面输出语句。
4. JSP的内置对象:
* 在jsp页面中不需要获取和创建,可以直接使用的对象,因为这些方法后来解释的时候都会放到service中执行,service中resp,req可以识别这些方法
* jsp一共有9个内置对象。
* 今天学习3个:
* request
* response
* out:字符输出流对象。可以将数据输出到页面上。和response.getWriter()类似
* response.getWriter()和out.write()的区别:
* 在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
* response.getWriter()数据输出永远在out.write()之前,就是response无论定义在哪里,都输出在out之前
* 因此建议使用out,不至于突然打乱布局,out顺序输出
代码截断,可以分段写控制与展示
优点:不用重启服务器,jsp就可以及时更新
Session:
1. 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
也是域对象,类似context,一次会话
3. 快速入门:
1. 获取HttpSession对象:
HttpSession session = request.getSession();
2. 使用HttpSession对象:
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
4. 原理
* Session的实现是依赖于Cookie的。
* 就是服务器创建一个session,指定唯一id,浏览器申请资源的时候将cookieID响应,反馈数据,后来浏览器访问其他资源携带这个cookieID,服务器会根据这个ID找到内部的数据,反馈,安全性高,内存消耗
-
细节:
1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
* 默认情况下。不是。会话结束了,可以打印session,会打印id,不同
*
* 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
Cookie c = new Cookie(“JSESSIONID”,session.getId());
c.setMaxAge(60*60);
response.addCookie©;2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗? * 不是同一个,但是要确保数据不丢失。tomcat自动完成以下工作,比如用户购物期间服务器重启,应当保证之前用户的数据不丢失,便于接下来的操作 * session的钝化: * 在服务器正常关闭之前,将session对象系列化到硬盘上 * session的活化: * 在服务器启动后,将session文件转化为内存中的session对象即可。 idea不活化,原因?钝化成功,将session.ser存储但是活化失败,因为当项目重启后,会将work目录删掉,导致之前的钝化无用,无法恢复数据 先找到本地项目-out目录(部署的项目,打包war)-找到tomcat目录下webapps,放入识别,开启(被解压)- 服务器开启,访问-需要是打包的名字+资源名代表实际路径,不再是虚拟路径 同tocmat目录下work目录运行时动态资源,比如jsp-java,session被序列化的文件也存储,这里服务器正常关闭后会将文件放入目录内,session.ser,当下次开启服务器,会自动读取session.ser,方便。 未来开发不在idea中部署,而是扔到webapps中居多,保证了钝化的work不会被轻易删除 3. session什么时候被销毁? 1. 服务器关闭 2. session对象调用invalidate() 。 3. session默认失效时间 30分钟,这就是一些网站30分钟重新登录的原因 可在tomcat的conf中web.xml中修改默认配置 选择性配置修改 <session-config> <session-timeout>30</session-timeout> </session-config>
-
session的特点
- session用于存储一次会话的多次请求的数据,存在服务器端
- session可以存储任意类型,任意大小的数据
- session与Cookie的区别:
- session存储数据在服务器端,Cookie在客户端
- session没有数据大小限制,Cookie有
- session数据安全,Cookie相对于不安全
jsp不能直接浏览器了,要使用服务器
演示代码,这里首次登录时间使用sessiion固化,即使浏览器关闭服务器未关闭依旧能在浏览器重启后访问之前的数据
-
HttpSession session = request.getSession();
Cookie jsessionid = new Cookie("JSESSIONID", session.getId());
jsessionid.setMaxAge(60*60);
response.addCookie(jsessionid);
Enumeration<String> attributeNames = session.getAttributeNames();
boolean flag_exist=false;
while (attributeNames.hasMoreElements()) {
flag_exist=true;
String s = attributeNames.nextElement();
Object attribute = session.getAttribute(s);
System.out.println("session键值对:"+s+":"+attribute);
response.getWriter().write("session数据存储为:"+attribute);
}
if (flag_exist==false) {
session.setAttribute("奇变偶不变",new Date());
}
在比较字符串相等应考虑到变量为空情况,最好的方法是,str.equals,可以保证不是空来调用equals
如果都是变量,可以使用&&先判断是否等于null
验证码逻辑问题,应该是一次性的,用完就失效,否则会导致登录检查无效