javaweb2
7、Cookie、Session
7.1、会话
会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话
有状态会话:(一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过,称之为有状态会话);
客户端 ---------- 服务端
- 服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了;cookie
- 服务器登记你来过了,下次来的时候来匹配你;session
7.2、保存会话的两种技术
cookie
- 客户端技术(响应,请求)
session
- 服务器技术,利用这个技术,可以保存用户的会话信息?我们可以把信息或者数据放在session中!
- 常见应用:网站登录之后,下次登录是就不必重新登录了
7.3、Cookie
-
从请求中拿到cookie信息
-
服务器响应给客户端cookie
Cookie[] cookies = req.getCookies(); //获得cookie cookie.getName(); //获得cookie中的key cookie.getValue(); //获得cookie中的value new Cookie("lastLoginTime", System.currentTimeMillis() + ""); //新建一个cookie cookie.setMaxAge(24*60*60); //设置cookie的有效期 resp.addCookie(cookie); //响应给客户端一个cookie
cookie:一般会保存在本地的用户目录下appdata
一个网站cookie是否存在上限!细节问题
- 一个Cookie只能保存一个信息;
- 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
- Cookie有上限4kb
- 300个cookie浏览器上限
删除cookie
- 不设置有效期,关闭浏览器,自动失效
- 设置有效期时间为0
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
//将cookie的有效期设置为0
cookie.setMaxAge(0);
resp.addCookie(cookie);
编码解码:
URLEncoder.encode("秦疆","utf-8");
URLEncoder.decode(cookies.getValue(),"utf-8");
7.4、Session(重点)
什么是Session:
-
服务器会给每一个用户(浏览器)创建一个Session对象;
-
一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
-
用户登录之后,整个网站它都可以访问了! —>保护用户的信息
-
Session和cookie的区别:
- Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
- Session把用户的数据写到独占Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
- Session对象由服务器创建
使用场景:
- 保存一个登录用户的信息;
- 购物车信息;
- 在整个网站中经常会使用到的数据,我们将它保存在Session中;
使用Session;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-16");
resp.setCharacterEncoding("utf-16");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
session.setAttribute("name", new Persion("添强", 25));
//获取Session的ID
String sessionid = session.getId();
//判断Session是不是新创建
if(session.isNew()){
resp.getWriter().write("session创建成功,ID:"+sessionid);
}else {
resp.getWriter().write("session已经在服务器中存在了,ID:"+sessionid);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
Persion name = (Persion) session.getAttribute("name");
System.out.println(name.toString());
//注销session
session.removeAttribute("name");
session.invalidate();
在web。xml中注销session
<!--设置Session默认的失效时间-->
<session-config>
<!--15分钟后session自动失效-->
<session-timeout>15</session-timeout>
</session-config>
8、JSP
8.1、什么是JSP
Java Server Pages : Java服务器端页面,也和Servlet一样,用于动态Web技术
最大的特点:
- 写JSP就像在写HTML
- 区别:
- HTML只给用户提供静态的数据
- JSP页面中可以嵌入JAVA代码,为用户提供动态数据;
8.2、JSP原理
思路:JSP是怎么执行的!
- 代码层面没有任何问题
- 服务器内部工作
tomcat中有一个work目录;
IDEA中使用Tomcat的会在IDEA的tomcat中生产一个work目录 - 在IDEA tomcat的工作空间最终发现页面转变成了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; //页面上下文
final javax.servlet.ServletContext application; //applicationContext
final javax.servlet.ServletConfig config; //config
javax.servlet.jsp.JspWriter out = null; //out
final java.lang.Object page = this; //page:当前
HttpServletRequest request //请求
HttpServletRequest response //响应
3、输出页面前增加的代码
response.setContentType("text/html; charset=UTF-8"); //设置响应的页面类型
pageContext = _jspxFactory.getPageContext(this, request, response,
null, false, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
out = pageContext.getOut();
_jspx_out = out;
4、以上的这些个对象我们可以在JSP页面中直接使用!
在JSP页面中:
只要是JAVA代码就会原封不动的输出;
如果是HTML代码,就会被转换为:
out.write("<html>\r\n");
这样的格式,输出到前端!
8.3、JSP基础语法
任何语言都有自己的语法,JAVA中有,。 JSP作为java技术的一种应用,他拥有一些自己扩充的语法(了解,知道即可),java所有语法都支持!
JSP表达式
<%--JSP表达式
作用:用来将程序的输出,输出到客户端
<%= new java.util.Date()%>
--%>
<%= new java.util.Date()%>
JSP脚本片段
<%--jsp脚本片段--%>
<%
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
out.write(i);
}
out.println("<h1>Sum="+sum+"</h1>");
%>
JSP脚本片段再实现
<%
for (int i = 0; i < 5; i++) {
%>
<h1>hello,world <%=i%> </h1>
<%
}
%>
JSP声明
<%!
static {
System.out.println("Loading Servlet!");
}
private int globalVar = 0;
public void kuang(){
System.out.println("进入了方法kuang");
}
%>
JSP声明:会被编译到JSP生成的java类中!其他的,就会被生成到_jspService方法中!
在JSP中,嵌入JAVA代码即可
<%%>
<%=%>
<%!%>
<%-- 注释--%>
8.4、JSP指令
<%--@include 会将两个页面合二为一--%>
<%@include file="common/header.jsp"%>
<h1>网页主体</h1>
<%@include file="common/footer.jsp"%>
<hr>
<%--JSP标签
jsp:include:拼接页面,本质上还是三个
--%>
<jsp:include page="common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="common/footer.jsp"/>
8.5、9大内置对象
- PageContext 存东西
- Request 存东西
- Response
- Session 存东西
- Application【SerlvetContext】 存东西
- config【ServletConfig】
- out
- page
- exception
pageContext.setAttribute("name1","秦疆1号"); //保存的数据只在一个页面中有效
request.setAttribute("name2","秦疆2号"); //保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","秦疆3号"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","秦疆4号"); //保存的数据只在服务器中有效,从打开服务器到关闭服务器
- request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的!
- session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车
- application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据;
8.6、JSP标签、JSTL标签、EL表达式
<!-- JSTL表达式的依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- standard标准库 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
EL表达式:${}
- 获取数据
- 执行运算
- 获取web开发的常用对象
JSP标签
<h1>我是1</h1>
<%--jsp:include--%>
< page="/jsptag2.jsp">
<jsp:param name="name" value="kuangshen"/>
<jsp:param name="age" value="12"/>
</jsp:forward>
JSTL表达式
JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义许多标签,可以供我们使用,标签的功能和lava代码一样!
核心标签(掌握部分)
JSTL标签库使用步骤
- 引入对应的taglib
- 使用其中的方法
- 在Tomcat也需要引入jstl的包,否则会报错:JSTL解析错误
-----------------------------------------if
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入JSTL核心标签库,我们才能使用JSTL标签--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h4>if测试</h4>
<hr>
<form action="coreif.jsp" method="get">
<%--
EL表达式获取表单中的数据
${param.参数名}
--%>
<input type="text" name="username" value="${param.username}">
<input type="submit" value="登录">
</form>
<%--判断如果提交的用户名是管理员,则登录成功--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
<c:out value="管理员欢迎您!"/>
</c:if>
<%--自闭合标签--%>
<c:out value="${isAdmin}"/>
</body>
</html>
--------------------------------------------------switch---------------------------------------------
<%--定义一个变量score,值为85--%>
<c:set var="score" value="85"/>
<c:choose>
<c:when test="${score>=90}">
你的成绩为优秀
</c:when>
<c:when test="${score>=80}">
你的成绩为良
</c:when>
<c:when test="${score>=70}">
你的成绩为中
</c:when>
<c:when test="${score>=60}">
你的成绩为及格
</c:when>
</c:choose>
-------------------------------------------------for each---------------------------------------------------------
<%
ArrayList<String> people = new ArrayList<>();
people.add(0,"张三");
people.add(1,"李四");
people.add(2,"王五");
people.add(3,"赵六");
people.add(4,"田七");
request.setAttribute("list",people);
%>
<%--
var,每一次遍历出来的变量
items,要遍历的对象
begin,
end,
step, 步长
--%>
<c:forEach var="people" items="${list}">
<c:out value="${people}"/> <br>
</c:forEach>
9、JavaBean
实体类
JavaBean有特定的写法:
- 必须要有一个无参构造
- 属性必须私有化
- 必须有对应的get/set方法
一般用来和数据库的字段做映射 ORM;
ORM:对象关系映射
- 表---->类
- 字段---->属性
- 行记录---->对象
10、MVC三层架构
什么是MVC: Model view controller 模型、视图、控制器
10.1、早期架构
用户直接访问控制层,控制层就可以直接操作数据库;
servlet--CRUD-->数据库
弊端:程序十分臃肿,不利于维护
servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码
架构:没有什么是加一层解决不了的!
程序猿调用--JDBC--mysql ORACLE sqlServer.....
10.2、MVC三层架构
-
Model
- 业务处理:业务逻辑(Service)
- 数据持久层:CRUD(Dao)
-
view
- 展示数据
- 提供链接发起的Serclet请求(a,from,img…)
-
controller
-
接收用户的请求:(req:请求参数、Session信息…)
-
交给业务层处理对应的代码
-
控制视图的跳转
登录--->接收用户的登录请求--->处理用户的请求(获取用户登录的参数,username,password)---->交给业务层处理登录业务(判断用户舒密码是否正确:事务)--->Dao层查询用户名和密码是否正确-->数据库
-
11、Filter(重点)
Filter:过滤器,用来过滤网站的数据
- 处理中文乱码
- 登录验证…
Filter开发步骤:
-
导包
-
编写过滤器
-
导包不要错(Fiter记得导入的是java.servlet目录下的)
-
编写过滤器
// 初始化:web服务器启动,就已经初始化了,随时等待过滤对象出现! public void init(FilterConfig filterConfig) throws ServletException { System.out.println("CharacterEncodingFilter初始化"); } /* 1.过滤器中的所有代码,在过滤特定请求的时候都会执行 2.必须要让过滤器继续同行 */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=UTF-8"); System.out.println("CharacterEncodingFilter执行前..."); chain.doFilter(request, response); // 让我们的请求继续走,如果不写,程序到这里就被拦截停止! System.out.println("CharacterEncodingFilter执行后..."); } // 销毁:web服务器关闭的时候,过滤器会销毁 public void destroy(){ System.out.println("CharacterEncodingFilter销毁"); }
3.在web.xml中配置Filter
-
12、监听器
实现一个监听器的接口;(有N种)
-
编写一个监听器—>实现监听器的接口
public void sessionCreated(HttpSessionEvent se) {} public void sessionDestroyed(HttpSessionEvent se) {}
2.web.xml中注册监听器
<listener>
<listener-class>com.servlet.listener</listener-class>
</listener>
13、过滤器、监听器常见应用
监听器:常用来监听GUI界面
实现功能:用户登录之后才能进入主页!用户注销后就不能进入主页了!
-
用户登录后,向Session中放入用户的数据
-
进入主页的时候要判断用户是否已经登录;在过滤器中进行实现
14、JDBC
什么是JDBC: java database conectioner
需要jar包的支持:
- java.sql
- javax.sql
- mysql-conneter-java…连接驱动(必须要导入)
jdbc使用的几个步骤;
1.建立数据库,使用SQL语句建立数据库的表;
2.导入数据库依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency>
</dependencies>
3.idea中连接数据库
4.jdbc固定六个步骤
// 配置信息
// useUnicode=true&characterEncoding=gbk解决中文乱码格式
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=gbk";
String username = "root";
String password = "123456";
// 1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.连接数据库,代表数据库
Connection connection = DriverManager.getConnection(url, username, password);
//3.向数据库发送SQL的对象Statement:CRUD
Statement statement = connection.createStatement();
//4.编写SQL
String sql = "select * from users";
//5.执行sql, 查询sql对象,返回一个结果集resultSet
ResultSet rs = statement.executeQuery(sql);
while (rs.next()){
System.out.println("id="+rs.getObject("id"));
System.out.println("name="+rs.getObject("name"));
System.out.println("password="+rs.getObject("password"));
System.out.println("email="+rs.getObject("email"));
System.out.println("brithday="+rs.getObject("brithday"));
}
//6.关闭连接,释放资源(一定要做)先开后关
rs.close();
statement.close();
connection.close();
- 加载驱动
- 连接数据库,代表数据库
- 向数据库发送SQL的对象Statement:CRUD
- 编写SQL(根据业务,不同的sql)
- 执行SQL
- 查---------- ResultSet rs = statement.executeQuery(sql); 返回的是查询到的结果
- 增删改--------- int i = statement.executeUpdate(sql); 返回的是受影响的行数
- 关闭连接
预编译插入数据
// 配置信息
// useUnicode=true&characterEncoding=gbk解决中文乱码格式
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=gbk";
String username = "root";
String password = "123456";
// 1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.连接数据库,代表数据库
Connection connection = DriverManager.getConnection(url, username, password);
//3.编写sql
String sql = "insert into users(id, name, password, email, brithday) VALUES (?,?,?,?,?);";
//4.预编译
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,4);//第一位都是占位符
preparedStatement.setString(2,"狂神说java");
preparedStatement.setString(3,"123456");
preparedStatement.setString(4,"274949663@qq.com");
preparedStatement.setDate(5,new Date(new java.util.Date().getTime()));
//5.执行sql, 查询sql对象,返回一个结果集resultSet
int i = preparedStatement.executeUpdate();
if(i>0){
System.out.println("插入成功");
}
//6.关闭连接,释放资源(一定要做)先开后关
preparedStatement.close();
connection.close();
}
事务
要么都成功,要么都失败
ACID原则:保证数据的安全
开启事务
事务提交 commit()
事务回滚 rollback()
关闭事务
Junit单元测试
依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
简单使用
@Test注解只有在方法上有效,只要加这个注解的方法,就可以直接运行!
@Test
public void test(){
System.out.println("hello");
}
成功和失败能表示出来
start transaction; #开启事务
update account set money = money - 100 where name = 'A';
update account set money = money + 100 where name = 'B';
commit ;
reparedStatement.close();
connection.close();
}
#### 事务
要么都成功,要么都失败
ACID原则:保证数据的安全
```JAVA
开启事务
事务提交 commit()
事务回滚 rollback()
关闭事务