11 JSP详解 Filter过滤器监听器 Junit
JSP
什么是JSP
Java Server Page:Java服务器端页面,也和Servlet一样,用于动态Web技术 。
Servlet就是用wirte()那个函数来写页面。
最大特点:
- 写JSP就像在写HTML
- JSP页面中可以嵌入Java代码,为用户提供动态数据
JSP原理
JSP中怎们执行?
- 代码层面没有任何问题
- 服务器内部工作
- tomcat又要给work目录
- IDEA中使用tomcat的会在IDEA的tomcat中产生一个work目录
浏览器向服务器发送请求,不管访问什么资源,其实都在访问Servlet
JSP最终也会被转换成一个Java类 ,JSP中本质上就是Servlet
JSP基础语法
-
创建一个空项目
-
右键项目–>
-
选择web项目
-
配置xml
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
注意!!
第一次运行,如果JSP修改过了,就可以直接选择第二个
这里是热部署:不重启服务器
JSP是访问时服务器才编译,所以这里你只需要选择第二个就行了。
<% %>
<%=%> 和 ${} EL表达式 等价 都可以直接取java的代码值,但是前面的那个会打印出不存在的值null,后面的则会不打印
<%! %>
<%! 定义全局的方法
private int globalvar=0;
public void ybl(){
System.out.println("进入了方法ybl");
}
%>
<%@ page import="java.util.Date" %>
<%--定制错误页面--%>
<%@ page errorPage="error/500.jsp" %>
<%--注释--%>
定义出错的指向 web.xml
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>
JSP指令
<%@ page args %>
<%@ include file=" "%> 导入一些共有相同文件,不一定要在头部,可以嵌入在你需要的地方 ,会将两个页面和二为一,两个页面变量相同会报错
<jsp:include page=""/> JSP标签 上面的include一样功能 拼接页面,但是不是和二唯一,两个页面的变量相同也没事
9大内置对象
- PageContext 存东西
- Request 存东西
- Response
- Session 存东西
- Application [ServletContext] 存东西
- config [ServletConfig]
- out
- page
- exception
JSP 标签、JSTL标签、EL标签
EL:express language ${}
- 获取数据
- 执行运算
- 获取web开发技术开发的常用对象
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
JSP标签
<%-- 转发参数--%>
<jsp:forward page="error/500.jsp">
<jsp:param name="name" value="ybl"/>
<jsp:param name="age" value="12"/>
</jsp:forward>
<%-- 取出参数--%>
<%=request.getParameter("name")%>
JSTL标签库的使用是为了弥补HTML标签的不足,他自定义了许多了标签,可以供我们使用,标签的功能和Java代码一样
JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。
-
核心标签
-
格式化标签
-
SQL标签
-
XML标签
引入核心标签
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
JSTL标签库使用步骤
- 引入相应的taglib
- 使用其中的方法
JavaBean
实体类
JavaBean有特点的写法:
- 必须要有一个无参构造
- 属性必须私有化
- 必须有对应的get/set方法
一般用来做数据库的字段做 映射
ORM: Object relationship Mapping 对象关系映射
- 表–>类
- 字段–>属性
- 行记录–>对象
MVC三层架构
Model view Controller 模型 视图 控制器
Controller:Servlet 接收用户的请求,相应给客户端内容,重定向或者转发
View:视图层 展示数据
Model:
- 业务处理:业务逻辑
- 数据持久层:CRUD(Dao层)
View
- 展示数据
- 提供链接发起Servlet请求(form img)
Controller(Servlet)
- 接受用的请求:request,Session
- 交给业务层处理对应的代码
- 控制试图的跳转
登录--接收用户的登录请求--处理用户的请求(获取用户的登陆参数username password)---交给业务层处理登录业务(判断用户名密码是否正确:事务)--->Dao层查询用户名和密码是否正确----数据库
Filter过滤器
Filter :过滤器,用来过滤网站的数据;
- 处理中文乱码
- 登陆验证
Filter 操作步骤:
-
导包
-
编写过滤器
-
实现Filter接口,重写方法
package com.ybl.filter; import javax.servlet.*; import java.io.IOException; public class CharacterEncoding implements Filter { //初始化 web服务器启动就初始化了,随时等待过两次对象 public void init(FilterConfig filterConfig) throws ServletException { System.out.println("CE初始化了"); } //chain 链条 /* 1.过滤中的所有代码,再过滤特定请求的时候都会执行 2.必须要让过滤器继续通行 */ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("utf-8"); servletResponse.setCharacterEncoding("utf-8"); servletResponse.setContentType("text/html"); System.out.println("CE 执行前....."); filterChain.doFilter(servletRequest,servletResponse);//让我们的请求继续走,如果不写,程序到这里拦截停止 System.out.println("CE 执行后....."); } //服务器关闭 的时候过滤销毁 public void destroy() { System.out.println("C销毁了"); } }
- 在web.xml配置Filter
<filter> <filter-name>characterEncoding</filter-name> <filter-class>com.ybl.filter.CharacterEncoding</filter-class> </filter> <filter-mapping> <filter-name>characterEncoding</filter-name> <!-- 只要是/servlet的任何请求都会经过这个过滤器--> <url-pattern>/servlet/*</url-pattern> </filter-mapping>
监听器
实现一个监听器接口
package com.ybl.listener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
//统计网站在线人数:统计session
public class onlineListener implements HttpSessionListener {
//创建session监听:看你的一举一动
//一旦创建session就会触发一次这个事件!
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
System.out.println(httpSessionEvent.getSession().getId());
Integer onlinecount =(Integer) servletContext.getAttribute("onlinecount");
if(onlinecount==null){
onlinecount=new Integer(1);
}else {
int count=onlinecount.intValue();
onlinecount=new Integer(count +1);
}
servletContext.setAttribute("onlinecount",onlinecount);
}
//销毁session
//一旦销毁就会触发这个时间
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);
}
/*
1.手动销毁
2.xml配饰session
*/
}
注册web.xml的监听器
<!-- 注册监听器-->
<listener>
<listener-class>com.ybl.listener.onlineListener</listener-class>
</listener>
3.看情况是否使用其他监听器
过滤器、监听器常见应用
用户登录之后才能进入主页,用户注销之后不能进入主页。
- 主页登录后,向Session中放入用户的数据
- 进入主页的时候要判断用户是否已经登录;要求:在过滤器中实现
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request =(HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if (request.getSession().getAttribute("username")==null){
response.sendRedirect("/error.jsp");
}
filterChain.doFilter(request,response);
}
<filter>
<filter-name>filter</filter-name>
<filter-class>com.ybl.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
JDBC
JDBC:java连接数据库!
需要Jar包的支持:
- Java.sql
- javax.sql
- mysql-connector-java…连接驱动(必须导入)
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置 这里jdbc是schema的名字
String url="jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC&useUnicode=true&characterEncoding=gbk&autoReconnect=true&failOverReadOnly=false";
String username="root";
String password="109456";
//1.加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.连接数据库
Connection connection= DriverManager.getConnection(url,username,password);
//3.向数据库发送SQL对象 Statement
Statement statement = connection.createStatement();
//4.编写SQL
String sql="select * from users";
//5.查询sql 返回结果集
ResultSet resultSet = statement.executeQuery(sql);
//5.1 int i=statement.executeUpdate(sql); 修改都用这个函数 i表达返回的行数
while (resultSet.next()){
System.out.println("id="+resultSet.getObject("id"));
System.out.println("name="+resultSet.getObject("name"));
System.out.println("password="+resultSet.getObject("password"));
}
//6.关闭连接释放资源 一定要做 先开的 后关
resultSet.close();
statement.close();
connection.close();
}
JDBC事务:
要么都成功,要么都失败
ACID原则 :原子性 一致性 隔离性 持久性 保证数据的安全。
开启事务;
事务提交;commit()
事务回滚:rollback()
关闭事务;
Junit test
就是导入Jar包之后可以直接运行函数,不需要 main函数
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
使用注解 @Test 来调用。