admin管理员组文章数量:1574493
三大Web组件:Servlet,Listener,Filter
一、Listener(监听器)
1.Web开发过程中的监听器:
监听对象:ServletContext
监听事件:创建和销毁
监听者:自己编写的一个监听器
触发事件:会触发监听器里面的方法
具体应用:
Context创建的时候读取一些配置文件;
Spring实例化的入口 ServletContextListener;
2.如何去编写一个listener?
(1)编写一个类实现ServletContextListener
(2)注册该listener(注解或者web.xml)
listener怎么做到监听的?
ServletContext的创建代码是在tomcat内部的,而且是很久之前就已经写好的,如何做到调用30年后写的代码呢?
伪代码:ServletContext对象的创建和销毁的代码
Class ServletContextXXX{
多态 将自己编写的listener注入到接口引用中
ServletContextListener listener;
Void create(){
创建的时候,该方法会被调用
Listener.contextInitialized
}
Void destroy(){
在销毁的时候,这个方法会被调用
Listener.contextDestroyed
}
}
3.使用场景
初始化配置、Spring程序执行的入口。
二、Filter(过滤器)
游戏中的文字检测到违禁的文字会自动替换成**********。
1.如何编写filter
(1)编写一个类实现Filter接口
(2)声明当前filter(web.xml或注解)
或者
任选其一即可。
2.如何让filter和servlet产生关联?让我们调用servlet时中间执行filter?
原来他们之间是没有任何关系的。
最简单的关联方式就是通过url-pattern进行关联,将servlet的url-pattern赋值给filter。
注意此时语法是允许的。
默认情况下filter执行的是拦截操作,如果想要filter放行,那么需要
3.filter的url-patterns可以设置/ * 吗?
完全可以设置 / * ,不会对我们的程序产生任何影响。
设置编码格式写到filter里面,那么其他servlet、也可以设置编码格式。
4.多个servlet不可以设置多个url-patterns,filter可以设置多个url-patterns吗?
完全可以设置。规定。
规定servlet不可以设置用一个url-patterns
Filter完全可以设置相同的url-patterns
处于功能上的考虑
Servlet:开发动态web资源,处理请求作出响应的,如果多个servlet相同url-pattern调用谁呢?
Filter:过滤器,执行过滤任务的,如果多个filter设置相同url-pattern,那么先后调用即可。
5.多个filter同时匹配时,先后顺序是什么样的呢?
对于web.xml来说,以mapping声明的先后顺序为准。
如果是注解呢?注意注解不要写成servlet的注解。
以类名首字母的ASII码先后顺序为准。
如果web.xml和注解同时配置,先xml后注解。
6.整个请求的执行流程
到达应用之前的步骤不会发生变化。区别在于达到应用之后。
- 浏览器地址栏输入http://localhost:8080/app/servlet,浏览器构建请求报文
- 达到目标机器,被8080端口接收,处理请求报文,生成request对象以及一个response对象
- 两个对象传递给engine,挑选host继续处理
- 继续传递对象,选择Context来处理
- 继续传递对象给context,根据配置的filter的url-patterns,判断能否处理该请求,如果可以,那么加入请求处理的队列中,如果有多个filter同时匹配到,那么就根据上面的原则,确定多个filter之间的调用顺序.
- 继续查找servlet的url-patterns,如果有,也加入队列中
登录案例:
LoginServlet.java
package com.cskaoyan.login;
import com.cskaoyan.login.bean.User;
import com.cskaoyan.login.utils.DruidUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//JDBC EE串讲 JSON MVC(JDBC) Maven Project1
String username = request.getParameter("username");
String password = request.getParameter("password");
QueryRunner runner = new QueryRunner(DruidUtils.getDataSource());
User user = null;
try {
user = runner.query("select * from user where username = ? and password = ?",
new BeanHandler<User>(User.class), username, password);
} catch (SQLException e) {
e.printStackTrace();
}
if(user != null){
request.getSession().setAttribute("user", user);
response.getWriter().println("登录成功,跳转至个人主页");
response.setHeader("refresh","2;url=info.jsp");
return;
}
response.getWriter().println("用户名或者密码错误");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
GlobalFilter .java
package com.cskaoyan.login.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/*")
public class GlobalFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
DruidUtils.java
package com.cskaoyan.login.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class DruidUtils {
private static DataSource dataSource;
static {
//从ds里面去获取,得到datasource即可
try {
Properties properties = new Properties();
//流 -----> file ----- path
//假如想将配置文件放在WEB-INF目录下 realPath
//那么当前配置文件必须要有一个API来接收request或者context,否则无法获取路径
//但是如果这么做了以后,那么今后该配置文件只能处理EE项目,SE项目需要重新在写一份
//那么,有没有一种方式,既可以处理EE也可以处理SE呢?
//有办法。利用类加载器来帮助我们获取流信息
//输入空字符串的时候,其实是到com同级目录
InputStream inputStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(inputStream);
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return getDataSource().getConnection();
}
public static DataSource getDataSource(){
return dataSource;
}
}
User.java
package com.cskaoyan.login.bean;
public class User {
private Integer id;
private String username;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
login.jsp
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/7/31
Time: 15:54
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="<%=request.getContextPath()%>/login" method="post">
<input type="text" name="username"><br>
<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
info.jsp
<%@ page import="com.cskaoyan.login.bean.User" %><%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/7/31
Time: 16:53
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
User user = (User) request.getSession().getAttribute("user");
%>
欢迎您,<%=user.getUsername()%>
</body>
</html>
druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/transfer?characterEncoding=utf-8
username=root
password=123456
filters=stat
initialSize=2
maxActive=300
maxWait=60000
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200
三、JDBC
标准JDBC
Class.forName(com.mysql.jdbc.Driver);
Connection conn = DriverManager.getConnection(url,user,password)
PrepareStatement psmt = Conn.prepareStatement(sql);
Psmt.setInt(1,xxx);
Psmt.setString(2,xxx);
ResultSet rs = Psmt.executeQuery();
While(rs.next()){
Rs.getString(columnLabel);
Rs.getInt(columnLabel);
}
Conn.close();
Psmt.close();
Rs.close();
为什么要引入数据库连接池?
因为创建连接的过程是十分消耗系统性能的,频繁创建和销毁连接,极易容易引起系统宕机。
连接先预先创建好,取出一个来使用,用完不要关闭,而是直接放回连接池。
获取DataSource数据源通过getConnection()。
为什么没有releaseConnection呢?即便提供了也没用,无法阻止主动去调用conn.close方法
有没有一种方式,close但是不是真的关闭,而是放回连接池。包装设计模式。
BeanListHandler:将结果封装为list对象形式
BeanHandler:将结果的第一行数据封装为一个对象
ScalarHandler:用来查询只有一列数据的值(聚合函数 count、max、min、avg)
2.配置文的存放位置
EE项目,配置文件放在哪呢?
最外层package目录同级
版权声明:本文标题:(七)Web三大组件_JavaEE_学习笔记 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1727773837a1128879.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论