代码地址: https://github.com/Zhuyaqiang/javaweb-study
目录
8 JSP
8.1 简介
Java Server Pages: Java服务器端页面, 用于动态Web技术
最大的特点:
- 写JSP就像在写HTML
- JSP页面中可以嵌入JAVA代码, 为用户提供动态数据
8.2 JSP原理
JSP最终也会被转换成一个JAVA类, 本质上就是一个Servlet
// 初始化
public void _jspInit() {}
// 销毁
public void _jspDestroy() {}
// JSPService
public void _jspService(HttpServletRequest, request, HttpServletResponse response) {}
- 判断请求
- 内置一些对象: pageContext, session application(servlet), config, out, page(当前页面)
- 以上对象可以在JSP中直接使用
在JSP页面中, 只要是JAVA代码就会原封不动的输出, 如果是HTML代码, 就会被转换为
out.write("<html>/n")
8.3 JSP基础语法
JSP作为Java技术的一种应用, 拥有一些自己的扩充语法(了解), Java所有语法都支持
8.3.1 JSP表达式
<%--JSP表达式
作用: 用来将程序的输出, 输出到客户端
<%= 变量或者表达式%>
--%>
<%= new java.util.Date()%>
8.3.2 JSP脚本片段
<%
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
out.println("<h1>Sum=" + sum + "</h1>");
%>
8.3.3 JSP声明
会被编译到JSP生成Java的类中, 其他的会被生成到_jspService方法中
<%!
static {
System.out.println("loading servlet!");
}
private int globalVar = 0;
public void kuang() {
System.out.println("进入了方法");
}
%>
<%%> // 片段
<%=%> // 表达式输出值
<%!%> // 定义全局方法
<%--注释--%>
JSP的注释, 不会在客户端显示, HTML会在客户端显示
8.4 JSP指令
<%@ page import="java.util.*" %>
<%@ page errorPage="xxx.jsp"%>
<%@ include file=""%>
<%--会将两个页面合二为一--%>
<%@ include file="common/header.jsp" %>
<h1>网页主体</h1>
<%@ include file="common/footer.jsp" %>
<hr>
<%--JSP标签--%>
<%--拼接页面, 本质还是三个--%>
<jsp:include page="common/header.jsp"></jsp:include>
<h1>网页主体</h1>
<jsp:include page="common/footer.jsp"></jsp:include>
8.5 9大内置对象
- PageContext
- Request
- Response
- Session
- Application [ServletContext]
- config [ServletConfig]
- out
- page
- exception
<%--内置对象--%>
<%
pageContext.setAttribute("name1", "啦啦1号"); // 保存的数据只在一个页面中有效
request.setAttribute("name2", "啦啦2号"); // 保存的数据只在一次请求中有效, 请求转发会携带这个数据
session.setAttribute("name3", "啦啦3号"); // 保存的数据只在一次会话中有效, 从打开浏览器到关闭浏览器
application.setAttribute("name4", "啦啦4号"); // 保存的数据只在一次会话中有效, 从打开服务器到关闭服务器
%>
request: 客户端向服务器发送请求, 产生的数据, 用户看完就没用了, 如: 新闻
session: 客户端向服务器发送请求, 产生的数据, 用户用完一会还有用, 如: 购物车
application: 客户端向服务器发送请求, 产生的数据, 用户用完了, 其他用户还可能用, 如: 聊天数据
9 JavaBean
9.1 实体类
JavaBean有特定的写法:
- 必须要有无参构造
- 属性必须私有化
- 必须有对应的get/set方法
一般用来和数据库的字段做映射
ORM: 对象关系映射
- 表—>类
- 字段—>属性
- 行记录—>对象
id | name | age | address |
---|---|---|---|
1 | 啦啦1号 | 3 | 北京 |
2 | 啦啦2号 | 4 | 厦门 |
3 | 啦啦3号 | 5 | 厦门 |
class People {
private int id;
private String name;
private int age;
private String address;
}
10 MVC三层架构
10.1 简介
MVC: Model View Controller
早年架构:
用户直接访问控制层, 控制层就可以直接操作数据库
servlet--CRUD--数据库
弊端: 程序十分臃肿, 不利于维护
servlet代码中: 处理请求, 响应, 视图跳转, 处理JDBC, 处理业务代码, 处理逻辑代码
10.2 三层架构
Model
- 业务处理: 业务逻辑(Service)
- 数据持久层: CRUE(DAO)
View
- 展示数据
- 提供链接发起Servlet请求
Controller
- 接收用户请求: req: 请求参数, Session信息
- 交给业务层对应的代码
- 控制视图的跳转
11 Filter(重点)
Filter: 过滤器, 用来过滤网站的数据
步骤:
-
导包(servlet)
import javax.servlet.Filter;
-
编写过滤器, 实现Filter接口, 重写方法
public class CharacterEncodingFilter implements Filter { // Web服务器启动时就初始化了 @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("characterEncoding初始化"); } /* 1. 过滤器中的所有代码, 在过滤特定请求的时候都会执行 2. 必须要让过滤器继续通行 filterChain.doFilter(servletRequest, servletResponse); */ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("utf-8"); servletResponse.setCharacterEncoding("utf-8"); servletResponse.setContentType("text/html;charset=UTF-8"); System.out.println("CharacterEncoding执行前"); filterChain.doFilter(servletRequest, servletResponse); // 让程序继续走 System.out.println("CharacterEncoding执行后"); } // Web服务器关闭的时候会销毁 @Override public void destroy() { System.out.println("characterEncoding销毁"); } }
-
web.xml中配置
12 监听器
实现一个监听器接口
-
编写一个监听器类, 实现监听器的接口
// 统计网站在线人数: 统计session public class OnlineCountListener implements HttpSessionListener { // 创建session监听 // 一旦创建Session 就会触发一次这个事件 @Override public void sessionCreated(HttpSessionEvent httpSessionEvent) { ServletContext servletContext = httpSessionEvent.getSession().getServletContext(); Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount"); System.out.println(httpSessionEvent.getSession().getId()); if (onlineCount == null) onlineCount = new Integer(1); else { int count = onlineCount.intValue(); onlineCount = new Integer(count+1); } servletContext.setAttribute("OnlineCount", onlineCount); } // 销毁session监听 // 一旦销毁Session就会触发一次这个事件 @Override public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { ServletContext servletContext = httpSessionEvent.getSession().getServletContext(); Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount"); if (onlineCount == null) onlineCount = new Integer(0); else { int count = onlineCount.intValue(); onlineCount = new Integer(count-1); } servletContext.setAttribute("OnlineCount", onlineCount); /* Session销毁: 1. 自动销毁: xml中配置session-timeout 2. 手动销毁httpSessionEvent.getSession().invalidate() */ } }
-
web.xml中注册监听器
<listener> <listener-class>com.zyq.listener.OnlineCountListener</listener-class> </listener>
-
看情况是否使用
13 过滤器监听器常见应用
监听器: GUI编程中常见
用户登录之后才能进入主页, 用户注销后就不能进入主页了
- 用户登录之后, 向Session中放入用户的数据
- 进入主页的时候要判断用户是否已经登录: 过滤器实现
14 JDBC
14.1 使用
需要jar包的支持
- java.sql
- javax.sql
- mysql-connter-java… 链接驱动
JDBC固定步骤:
- 加载驱动
- 连接数据库, 代表数据库
- 向数据库发送SQL的对象Statement/PreparedStatement: CRUD
- 编写SQL
- 执行SQL
- 关闭连接
14.2 事务
要么都成功, 要么都失败, ACID原则
- 开启事务
- 事务提交 commit()
- 事务回滚 rollback()
- 关闭事务