Filter:过滤器,用来过滤网站的数据;
- 处理中文乱码
- 登陆验证......

Fitler开发步骤
添加依赖
pom.xml
xml
<dependencies>
<!--Jsp依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<!--Servlet依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!--jstl标签依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--standard 依赖-->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!--连接数据库-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
</dependencies>
编写过滤器
导包

代码
实现Filter接口,重写对应的方法即可
CharacterEncondingFilter.java
java
public class CharacterEncondingFilter implements Filter {
// Chain:链
/*
1.过滤器中的所有代码,在过滤请求的时候都会执行
2.必须要过滤器继续通行,才能进行转交 chain.doFilter(request, response);死代码
* */
@Override
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("过滤执行前");
chain.doFilter(request, response); //让我们的请求继续走,如果不写,程序在这里就会被拦截。因为如果有其他过滤也会放在链中进行交接
System.out.println("过滤执行后");
}
// 初始化
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//filterConfig. 可以才初始化的时候获得一些东西,但是一般没有必要这样子操作
System.out.println("CharacterEncondingFilter已经初始化了");
}
//销毁:web服务器停止的时候,过滤器会被销毁
@Override
public void destroy() {
//注销的时候也可以进行垃圾回收的额外操作:
//System.gc();
System.out.println("CharacterEncondingFilter已经销毁了");
}
}
ShowServlet.java
java
public class ShowServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.write("世界");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
在web.xml配置
xml
<servlet>
<servlet-name>ShowServlet</servlet-name>
<servlet-class>com.cike.servlet.ShowServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ShowServlet</servlet-name>
<url-pattern>/show</url-pattern>
<url-pattern>/cn/show</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.cike.filter.CharacterEncondingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
监听器
实现要给监听器的接口;(有N种)
编写一个HttpSession监听器
实现监听器的接口
java
//统计网站在线人数:统计session
//一通百通,有很多个Listener、一年也不一定学的完
public class OnlineCountListener implements HttpSessionListener {
private static int onlineCount = 0;
//创建session监听:看你的一举一动(间谍)
//一旦创建一个Session就会触发一次这个事件!
public void sessionCreated(HttpSessionEvent se){
//HttpSessionEvent代表session事件的一个对象
ServletContext ctx = se.getSession().getServletContext();
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
System.out.println(se.getSession().getId());
if (onlineCount == null){
onlineCount = new Integer(1);
}
else{
int count = onlineCount.intValue();
onlineCount = new Integer(count+1);
}
ctx.setAttribute("OnlineCount", onlineCount);
}
//销毁session监听
//一旦销毁Sesson就会触发一次这个事件!
public void sessionDestroyed(HttpSessionEvent se){
//HttpSessionEvent代表session事件的一个对象
ServletContext ctx = se.getSession().getServletContext();
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount == null){
onlineCount = new Integer(0);
}
else{
int count = onlineCount.intValue();
onlineCount = new Integer(count-1);
}
ctx.setAttribute("OnlineCount", onlineCount);
}
/*
* Session销毁:
* 手动销毁:getSession()invalidate();
* 自动销毁:web.xml中进行配置
* */
}
web.xml注册监听器
xml
<listener>
<listener-class>com.cike.listen.OnlineCountListener</listener-class>
</listener>
自动注销session.
xml
<session-timeout>
<!--以分钟为单位-->
1
</session-timeout>
看情况是否使用
......
过滤器和监听器的常见应用(Gui编写)
- 工具、写外挂、辅助、木马经常用到这些
java
public class TestPanel {
public static void main(String[] args) {
Frame title = new Frame("反序列化通杀工具"); //创建窗体
Panel panel = new Panel(null); // 创建面板
title.setLayout(null); //设置窗体布局
title.setBounds(300,300,2000,2000);
title.setBackground(Color.darkGray);//设置背景颜色
panel.setBounds(50,50,800,800);
panel.setBackground(Color.white);//设置背景颜色
title.add(panel);
title.setVisible(true);
//监听事件,监听关闭事件
title.addWindowListener(new WindowListener() {
@Override //Windows打开事件
public void windowOpened(WindowEvent e) {
System.out.println("Windows打开事件");
}
@Override//Windows关闭中事件
public void windowClosing(WindowEvent e) {
System.out.println("Windows关闭中事件");
System.exit(0); //这里的0指的是正常退出、如果是1指的是存在错误(非正常)
}
@Override//Windows关闭事件
public void windowClosed(WindowEvent e) {
System.out.println("Windows关闭事件");
}
@Override//窗体图标被激活事件
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override//激活
public void windowActivated(WindowEvent e) {
System.out.println("窗体激活事件");
}
@Override//窗体未激活
public void windowDeactivated(WindowEvent e) {
System.out.println("窗体未激活事件");
}
});
}
}
Filter实现权限拦截(登录实验)
用户登录之后才能进入主页!用户注销后就不能进入!
用户登录之后,向Session中放入用户的数据
进入主页的时候要判断用户是否已经登录;可以过滤器实现
sysFilter.java
java
public class sysFilter implements javax.servlet.Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse rep, FilterChain filterChain) throws IOException, ServletException {
// ServletRequest HttpServletRequest 类型不一样,先需要强转换
// ServletResponse HttpServletResponse 类型不一样,先需要强转换
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) rep;
if (request.getSession().getAttribute(Constant.USER_SESSION)==null){
response.sendRedirect("/login.jsp");
}
filterChain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
注销的时候不建议销毁session
开发中一般不建议销毁session,因为频繁的创建session是非常消耗资源的。移除session,只是客户端的session值没了,但是服务端还在,可以做到session复用,就不需要频繁的创建session了
LogoutServlet
java
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//开发中一般不建议销毁session,因为频繁的创建session是非常消耗资源的
Object userSession = req.getSession().getAttribute("USER_SESSION");
if (userSession != null){
//移除session,只是客户端的session值没了,但是服务端还在,可以做到session复用,就不需要频繁的创建session了
req.getSession().removeAttribute("USER_SESSION");
resp.sendRedirect("/login.jsp");
}
}
}
配置常量SESSION
java
public class Constant {
//常量,不加final也可以
//final 在Java 中是一个保留的关键字,可以声明成员变量、方法、类以及本地变量。 一旦你将引用声明作final,你将不能改变这个引用了
public final static String USER_SESSION = "userSession";
}
前端视图跳转
index.jsp
java
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>当前有<span style="color: aquamarine"><%= this.getServletConfig().getServletContext().getAttribute("OnlineCount")%></span>人在线</h1>
<h1><a href="${pageContext.request.contextPath}/login.jsp">管理员登录</a></h1>
</body>
</html>
login.jsp
java
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/login">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="登录">
</form>
</body>
</html>
/sys/success.jsp
java
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>管理员后台</title>
</head>
<body>
<%--没有过滤器的时候,也可以这样子进行未授权访问的验证
<%
Object userSession = request.getSession().getAttribute("USER_SESSION");
if (userSession == null){
response.sendRedirect("/login.jsp");
}
%>
--%>
<h1>恭喜你登陆成功</h1>
<p>flag{this_is_flag}</p>
<p><a href="${pageContext.request.contextPath}/logout">注销</a></p>
</body>
</html>
web.xml的配置
xml
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.cike.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>logout</servlet-name>
<servlet-class>com.cike.servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>logout</servlet-name>
<url-pattern>/logout</url-pattern>
</servlet-mapping>
<filter>
<filter-name>sysFilter</filter-name>
<filter-class>com.cike.filter.sysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sysFilter</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>