cookie、Session
会话
用户打开了一个浏览器,点击了很多超链接。访问了web多个资源,关闭浏览器,这个过程就叫会话
有状态会话:一个同学来过教室,下次来,我们就会知道这个同学,曾经来过,称之为有状态会话
你能怎么证明你是西开的学生?
1.发票
2.学校登记 学校标记你来过了
一个网站,怎么证明你来过?
客户端 服务端
1.服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了
2.服务器登记你来过了,下次你来的时候我来匹配。
保存会话的两种技术
cookie
-
客户端技术(响应,请求)
session -
服务器技术,利用这个技术,可以保存用户的会话信息?我们可以把信息或者数据放在session中
常见:网站登录之后,下次不用再登录了,第二次直接就可以访问了
Cookie
1.从请求中拿到cookie信息
2.服务器响应给客户端cookie
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器,告诉你,你来的时间。把这个时间封装成信件,你下次带着来,
resp.setCharacterEncoding("utf-16");
req.setCharacterEncoding("utf-16");
PrintWriter out = resp.getWriter();
//cookie服务器端 从客户端获取
Cookie[] cookies = req.getCookies();
//判断cookie是否存在
if(cookies!=null){
//如果存在怎么办
out.write("你上次访问的时间是");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie=cookies[i];
//获取cookie的名字
if(cookie.getName().equals("lastLoginTime")){
//获取cookie的值
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write(date.toString());
}
}
}else{
System.out.println("这是你第一次访问本网站");
}
//服务器给客户端响应一个cookie
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
//设置有效期7天
cookie.setMaxAge(7*24*60*60);
resp.addCookie(cookie);
}
cookie:一般回保存在本地的用户目录下appdata;
一个网站cookie是否存在上限!聊聊细节问题
- 一个cookie只能保存一个信息
- 一个web站点可以给浏览器发送多个cookie,最多20个
- 300个cookie浏览器上限
- cookie大小有限制4kb;
删除cookie: - 不设置有效期,关闭浏览器,自动失效,
- 设置有效期为0;
编码解码:
URLEncoder.encode("","utf-8")
URLDecoder.decode("","utf-8")
Session(重点)
什么是session:
- 服务器会给每一个用户一个 创建session对象
- 一个session独占一个浏览器,只要浏览器没关,这个session就存在
- 用户登录之后,整个网站它都可以访问–》保存用户的信息,保存购物车的信息
Session和cookie区别
- cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
- session是把用户的数据写到用户独占session中,服务器保存(保存重要信息,减少服务器资源的浪费)
- session对象由服务器创建;
使用场景
- 保存一个登录用户信息;
- 购物车信息;
- 在整个网站中经常会使用的数据,我们将它保存在session中
使用session
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到session
HttpSession session = req.getSession();
//给session存东西
//session.setAttribute("name", URLEncoder.encode("华","utf-8"));
session.setAttribute("name", new Person(URLDecoder.decode("华","utf-8"),22));
String id = session.getId();
//判断是不是新的session 新创建的?
PrintWriter writer = resp.getWriter();
if(session.isNew()){
writer.write("session创建成功,ID"+id);
}else {
writer.write("session已经存在,ID"+id);
}
//session 在创建的时候做了什么
//Cookie cookie = new Cookie("JSESSIONID", id);
//resp.addCookie(cookie);
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
//手动注销session
session.invalidate();
}
会话的过期
<session-config>
<!--分钟后session自动失效(单位分钟)-->
<session-timeout>15</session-timeout>
</session-config>
jsp原理剖析
什么是jsp
Java Server Pages:java服务器端页面,也和servlet一样,用于动态web技术!
最大的特点:
- 写jsp就像是html
- 区别:
HTML只给用户提供静态的数据
jsp页面可以嵌入java代码,为用户提供动态数据
jsp原理
思路:jsp到底怎样执行!
- 代码层面没有任何问题
- 服务器内部
Tomcat中有work目录;
idea中使用Tomcat的话会在idea的tomcat中产生一个work目录
我的目录
C:\Users\lenovo\AppData\Local\JetBrains\IntelliJIdea2021.1\tomcat\0e143c1d-74dd-40fc-99d9-25c2878f5ae7\work\Catalina\localhost\request_war\org\apache\jsp
页面变成了java程序
浏览器向服务器发送请求,不管什么访问资源,都是在访问servlet!
jsp最终也会被转换成为一个Java类!
jsp本质上就是一个servlet
//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
//jspService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
1.判断请求
2.内置了一些对象
final javax.servlet.jsp.PageContext pageContext; //页面上下文
javax.servlet.http.HttpSession session = null; //session
final javax.servlet.ServletContext application; //application
final javax.servlet.ServletConfig config; //cofig
javax.servlet.jsp.JspWriter out = null; //out
final java.lang.Object page = this; //page当前页
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
3.输出页面前增加的代码
response.setContentType("text/html;charset=UTF-8"); //设置页面的响应类型
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
4.以上的这些对象我们可以在jsp页面中直接使用!
在jsp页面中:
只要是java代码就会被原封不动的输出
如果是Html代码,就会被转换:
这样的格式输出到前端
jsp基础语法
任何语言都有自己的语法,java中有,jsp也有,jsp作为java技术的一种应用,他拥有一些自己扩充的语法,(了解,知道即可)。Java语法都支持
jsp表达式
<%= new java.util.Date()%>
jsp脚本片段
<%
int sum=0;
for (int i = 0; i <=100; i++) {
sum+=i;
}
out.print("<h1>sum="+sum+"</h1>");
%>
9大内置对象
- PageContext
- Requets
- Response
- Session
- Application [ServletContext ]
- config [ServletConfig]
- out
- page , 不用了
- exception
作用域
pageContext.setAttribute("name1","hua1");//本页面有效
request.setAttribute("name2","hua2");//只在一次请求中有效,转发会携带
session.setAttribute("name3","hua3");//一次会话内有效
application.setAttribute("name4","hua4");//服务器中有效,打开到结束服务器
jsp标签、jstl标签、el表达式
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
el表达式:${}
- 获取数据
- 执行运算
- 获取web开发的常用对象
- 调用java方法
jstl标签
导入标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
JavaBean
实体类
Javabean有特定的写法:
- 必须要有一个无参构造
- 属性必须私有化
- 必须有对应的get/set方法;
一般用来和数据库的字段做映射 ORM;
ORM:对象关系映射 - 表–》类
- 字段-》属性
- 行记录-》对象
MVC三层架构
什么是MVC:MOdel View Controller 模型 视图 控制器
用户直接访问控制层,控制层呢个就可以直接操作数据库;
早些年
servlet--CRUD--》数据库
弊端:程序十分臃肿,不利于维护
servlet的代码中:处理请求、响应、视图跳转、处理jdbc、处理业务代码、处理逻辑代码
架构:没有什么是加一层解决不了的!
Filter
过滤器:用来过滤网站的数据;
- 处理中文乱码
- 登录验证
实现filter接口 不要导错包
public class CharacterEncodingFilter implements Filter{
//初始化 服务器开始时就会初始化
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filter初始化");
}
@Override
//filterChain 链
//
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=utf-8");
System.out.println("setCharacterEncoding执行前。。。");
filterChain.doFilter(servletRequest,servletResponse);//让我们的请求继续走,不写的话,程序到这里就停止了
System.out.println("setCharacterEncoding执行后。。。");
}
//销毁 服务器关闭时才会初始化
@Override
public void destroy() {
System.out.println("filter销毁");
}
}
在web.xml中配置Filter
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>com.hua.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
JDBC
什么是JDBC:java连接数据库
public class JDBC {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/jdbc?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT";
String username = "root";
String password = "admin";
Connection c = DriverManager.getConnection(url,username,password);
Statement s = c.createStatement();
String sql = "select * from person";
ResultSet rs = s.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getObject("id"));
System.out.println(rs.getObject("name"));
System.out.println(rs.getObject("age"));
System.out.println(rs.getObject("adress"));
}
rs.close();
s.close();
c.close();
}
}
事务
要么都成功,要么都失败!
ACID原则:保证数据的安全
开启事务
事务提交 comit()
事务回滚 rollback()
关闭事务
Junit 单元测试
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
简单使用
@Test注解只在方法上有效,加上这个注解,就可以直接运行!
public class Text01 {
@Test
public void test(){
System.out.println("测试方法");
}
}
搭建一个环境(回滚测试)
public void test() {
String url = "jdbc:mysql://localhost:3306/jdbc?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT";
String username = "root";
String password = "admin";
Connection c = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
c = DriverManager.getConnection(url , username ,password);
//创建事务 false(开启)
c.setAutoCommit(false);
String sql ="update acount set money = money-100 where name = 'A'";
c.prepareStatement(sql).executeUpdate();
//创建错误
// int i = 1/0;
String sql1 = "update acount set money = money+100 where name = 'B'";
c.prepareStatement(sql1).executeUpdate();
//关闭事务
c.commit();
} catch (Exception e) {
try {
c.rollback();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
e.printStackTrace();
}finally {
try {
c.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}