JavaWeb三大组件 1、都需要在web.xml中进行配置 Servlet Filter Listener
2、过滤器 会在一组资源(jsp, servlet, css, html等等)的前面执行 可以让请求得到目标资源,也可以不让请求达到 过滤器有拦截请求的能力
3、编写过滤器 (1)实现Filter接口 (2)在web.xml中进行配置 (3)Filter是单例的
4、配置web.xml
FilerName
FilerClass
FilerName
/*
继承示例
package com.pengshiyu.filtrer;
import javax.servlet.*;
import java.io.IOException;
public class Afilter implements Filter {
/**
* 创建之后马上执行,用来做初始化
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 每次过滤都会执行
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
System.out.println("进入过滤器");
// 调用后序方法
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("离开过滤器");
}
/**
* 销毁之前的调用,用来释放资源
*/
@Override
public void destroy() {
}
}
FilterConfig -> 与ServletConfig相似 获取初始化参数 getInitParameter() 获取过滤器名称 getFilterName() 获取application getServletContext()
FilterChain 放行,执行后序方法 doFilter()
课时2 多个过滤器的执行顺序执行下一个过滤器或目标资源 FilterChain.doFilter()
Afilter进入过滤器
Bfilter进入过滤器
getAge
Bfilter离开过滤器
Afilter离开过滤器
课时3 四种拦截方式
请求 REQUEST 默认 转发 FORWARD 包含 INCLUDE 错误 ERROR
FilerName
/*
REQUEST
页面出错
500
500.html
课时4 使用filter-mapping控制多个Filter的执行顺序
filter-mapping的配置顺序决定过滤器执行顺序
课时5 Filter的应用场景、Filter的目标资源、小结预处理:执行目标资源之前做预处理工作,例如设置编码 拦截:通过条件判断是否放行,例如用户登录校验 回程拦截:目标资源执行之后,做一些后序的特殊处理工作,例如目标资源输出的数据进行处理
直接指定servlet-name
FilerName
ServletName
小结 Filter3个方法 FilterChain类 4中拦截方式
课时6 案例1:分IP统计访问次数数据结构:
ipcount192.168.0.132192.168.0.222统计工作在所有资源之前都执行,使用Filter 这个过滤器只做统计,不做拦截 数据Map Map保存到ServletContext中 从request中获取客户端ip
使用监听器创建 map AListener.java
package com.pengshiyu.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.LinkedHashMap;
import java.util.Map;
public class AListener implements ServletContextListener {
// 服务器启动时创建map
public void contextInitialized(ServletContextEvent sce) {
Map map = new LinkedHashMap();
sce.getServletContext().setAttribute("map", map);
}
public void contextDestroyed(ServletContextEvent sce) {
}
}
使用过滤器统计数据 AFilter.java
package com.pengshiyu.filter;
import javax.servlet.*;
import java.io.IOException;
import java.util.Map;
public class AFilter implements Filter {
private FilterConfig config;
/**
* 创建之后马上执行,用来做初始化
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.config = filterConfig;
}
/**
* 每次过滤都会执行
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
ServletContext app = this.config.getServletContext();
Map map = (Map)app.getAttribute("map");
String ip = request.getRemoteAddr();
System.out.println("ip: " + ip);
if(map.containsKey(ip)){
Integer count = map.get(ip);
map.put(ip, count+1);
} else{
map.put(ip, 1);
}
// 放行
filterChain.doFilter(request, response);
}
/**
* 销毁之前的调用,用来释放资源
*/
@Override
public void destroy() {
}
}
显示数据 BServlet.java
package com.pengshiyu.servlet;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
ServletContext app = getServletContext();
Map map = (Map) app.getAttribute("map");
response.setContentType("text/html; charset=UTF-8");
response.getWriter().println(map.toString());
}
}
配置监听器和过滤器生效 web.xml
BServlet
com.pengshiyu.servlet.BServlet
BServlet
/b
AFilter
com.pengshiyu.filter.AFilter
AFilter
/*
com.pengshiyu.listener.AListener
课时7 案例2:粗粒度权限管理
基于角色的权限控制RBAC tb_user tb_role tb_userrole tb_menu tb_rolemenu
web.xml
AServlet
com.pengshiyu.servlet.AServlet
AServlet
/hello
AFilter
com.pengshiyu.filter.AFilter
AFilter
/hello.html
AServlet.java
package com.pengshiyu.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println("post: " + username);
// 设置session
request.getSession().setAttribute("username", username);
// 跳转页面
request.getRequestDispatcher("hello.html").forward(request, response);
}
}
过滤器进行简单的权限校验 AFilter.java
package com.pengshiyu.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class AFilter implements Filter {
private FilterConfig config;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.config = filterConfig;
}
@Override
public void doFilter(ServletRequest req, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
String username = (String) request.getSession().getAttribute("username");
System.out.println("filter: " + username);
if(username != null){
// 放行
filterChain.doFilter(request, response);
} else{
// 跳转到登录页
request.getRequestDispatcher("login.html").forward(request, response);
}
}
@Override
public void destroy() {
}
}
课时8 案例3:全站编码问题
// post编码
request.setCharacterEncoding("utf-8");
// get编码
String username = request.getParameter("username");
username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
// 响应编码
response.setContentType("text/html; charset=UTF-8");
HttpServletRequest装饰类 EncodingRequest.java
package com.pengshiyu.filter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.nio.charset.StandardCharsets;
// 装饰器
public class EncodingRequest extends HttpServletRequestWrapper {
public EncodingRequest(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
// 处理编码问题
String value = super.getParameter(name);
value = new String(value.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
return value;
}
}
过滤器AFilter.java
package com.pengshiyu.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class AFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String method = httpServletRequest.getMethod();
// 设置响应编码
response.setContentType("text/html; charset=UTF-8");
if ("GET".equals(method)) {
// 放行
EncodingRequest encodingRequest = new EncodingRequest(httpServletRequest);
filterChain.doFilter(encodingRequest, response);
} else if ("POST".equals(method)) {
request.setCharacterEncoding("utf-8");
filterChain.doFilter(request, response);
}
}
@Override
public void destroy() {
}
}
响应处理AServlet.java
package com.pengshiyu.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println(request.getParameter("name"));
response.getWriter().print("你好");
}
}
web.xml
AServlet
com.pengshiyu.servlet.AServlet
AServlet
/hello
AFilter
com.pengshiyu.filter.AFilter
AFilter
/*
课时9 案例4:页面静态化之准备工作(图书管理小项目)
功能:
查询所有
按分类查看
BookServlet
findAll() 查询全部
findByCategory() 按分类查询
BookService: 省略
BookDao:
List findAll()
List findByCategory()
Book:
bid
bname
price
category
静态化: 第一次访问从数据库取数据,保存到html中 第二次之后访问就直接从html中读取,不再从数据库中取数据
数据准备:
create table tb_book(
bid int primary key auto_increment,
bname varchar(50),
price decimal(10, 2),
category int
);
insert into tb_book(bname, price, category) values("Java", 12, 1);
insert into tb_book(bname, price, category) values("Python", 12, 1);
insert into tb_book(bname, price, category) values("JavaScript", 12, 1);
insert into tb_book(bname, price, category) values("Go", 12, 1);
insert into tb_book(bname, price, category) values("三国演义", 12, 2);
insert into tb_book(bname, price, category) values("西游记", 12, 2);
insert into tb_book(bname, price, category) values("水浒传", 12, 2);
insert into tb_book(bname, price, category) values("红楼梦", 12, 2);
创建对应的Book类
package com.pengshiyu.bean;
public class Book {
private int bid;
private String bname;
private double price;
private int category;
public Book() {
}
public int getBid() {
return bid;
}
public void setBid(int bid) {
this.bid = bid;
}
public String getBname() {
return bname;
}
public void setBname(String bname) {
this.bname = bname;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getCategory() {
return category;
}
public void setCategory(int category) {
this.category = category;
}
@Override
public String toString() {
return "Book{" +
"bid=" + bid +
", bname='" + bname + '\'' +
", price=" + price +
", category=" + category +
'}';
}
}
BookDao.java
package com.pengshiyu.dao;
import com.pengshiyu.bean.Book;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import util.TxQueryRunner;
import java.sql.SQLException;
import java.util.List;
public class BookDao {
private QueryRunner qr = new TxQueryRunner();
public List findAll() {
String sql = "select * from tb_book";
try {
List list = qr.query(sql, new BeanListHandler(Book.class));
System.out.println(list);
return list;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public List findByCategory(int category) {
String sql = "select * from tb_book where category = ?";
try {
return qr.query(sql, new BeanListHandler(Book.class), category);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
BookServlet
package com.pengshiyu.servlet;
import com.pengshiyu.dao.BookDao;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class BookServlet extends BaseServlet {
private BookDao bookDao = new BookDao();
public void findAll(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.setAttribute("bookList", bookDao.findAll());
request.getRequestDispatcher("book.jsp").forward(request, response);
}
public void findByCategory(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int category = Integer.parseInt(request.getParameter("category"));
request.setAttribute("bookList", bookDao.findByCategory(category));
request.getRequestDispatcher("book.jsp").forward(request, response);
}
}
用到的工具类 TxQueryRunner.java
package util;
import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
public class TxQueryRunner extends QueryRunner {
@Override
public int[] batch(String sql, Object[][] params) throws SQLException {
Connection con = JdbcUtil.getConnection();
int[] result = super.batch(con, sql, params);
JdbcUtil.releaseConnection(con);
return result;
}
@Override
public T query(String sql, ResultSetHandler rsh, Object... params)
throws SQLException {
Connection con = JdbcUtil.getConnection();
T result = super.query(con, sql, rsh, params);
JdbcUtil.releaseConnection(con);
return result;
}
@Override
public T query(String sql, ResultSetHandler rsh) throws SQLException {
Connection con = JdbcUtil.getConnection();
T result = super.query(con, sql, rsh);
JdbcUtil.releaseConnection(con);
return result;
}
@Override
public int update(String sql) throws SQLException {
Connection con = JdbcUtil.getConnection();
int result = super.update(con, sql);
JdbcUtil.releaseConnection(con);
return result;
}
@Override
public int update(String sql, Object param) throws SQLException {
Connection con = JdbcUtil.getConnection();
int result = super.update(con, sql, param);
JdbcUtil.releaseConnection(con);
return result;
}
@Override
public int update(String sql, Object... params) throws SQLException {
Connection con = JdbcUtil.getConnection();
int result = super.update(con, sql, params);
JdbcUtil.releaseConnection(con);
return result;
}
}
JdbcUtil.java
package util;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class JdbcUtil {
// 需要配置c3p0-config.xml
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 返回连接对象
public static Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
// 返回连接池对象
public static DataSource getDataSource() {
return dataSource;
}
// 释放连接
public static void releaseConnection(Connection connection) {
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
book.jsp
图书列表
分类:
全部
第一类
第二类
ID
书名
价格
分类
${book.bid}
${book.bname}
${book.price}
${book.category}
配置文件
pom.xml
jstl
jstl
1.2
taglibs
standard
1.1.2
web.xml
BookServlet
/book
BookServlet
com.pengshiyu.servlet.BookServlet
c3p0-config.xml
com.mysql.cj.jdbc.Driver
jdbc:mysql://localhost:3306/data
root
123456
2
2
2
10
访问路径 http://localhost:8080/demo/book?method=findAll http://localhost:8080/demo/book?method=findByCategory&category=1
课时10 案例4:页面静态化之如果文件存在直接重定向到html使用一个过滤器,把servlet请求的资源输出保存到html中 第二次访问资源的时候,如果已存在就直接重定向到html文件
课时11 案例5:页面静态之生成html页面CacheFilter.java
package com.pengshiyu.filter;
import com.pengshiyu.response.StaticResponse;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
public class CacheFilter implements Filter {
private FilterConfig config;
private final String cacheFileName = "cache";
private String cacheFilePath = null;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.config = filterConfig;
this.cacheFilePath = this.config.getServletContext().getRealPath(this.cacheFileName);
File file = new File(this.cacheFilePath);
if(file.exists()){
file.mkdir();
}
}
/**
* 访问路径
* http://localhost:8080/demo/book?method=findByCategory&category=4
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse)servletResponse;
String category = request.getParameter("category");
String filepath = this.cacheFilePath + "/" + category + ".html";
File file = new File(filepath);
// 如果页面不存在就缓存页面
if(!file.exists()){
StaticResponse staticResponse = new StaticResponse(response, filepath);
filterChain.doFilter(request, staticResponse);
}
System.out.println("文件存在了");
request.getRequestDispatcher(this.cacheFileName + "/" + category + ".html").forward(request, response);
}
@Override
public void destroy() {
}
}
StaticResponse.java
package com.pengshiyu.response;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
public class StaticResponse extends HttpServletResponseWrapper {
private PrintWriter pw;
public StaticResponse(HttpServletResponse response, String filename) throws FileNotFoundException {
super(response);
this.pw = new PrintWriter(filename);
}
@Override
public PrintWriter getWriter() throws IOException {
// 掉包输出流
return this.pw;
}
}