6、过滤器、监听器、文件上传和下载

过滤器、监听器、文件上传和下载

过滤器(Filter)

过滤器又可以称之为拦截器。

Filter

java中的Filter并不是一个标准的servlet,它不能处理用户请求,对客户端 生成响应。主要用于对HttpServletRequest进行预处理,以对HttpServletResponse进行后处理。是一个典型的处理链。

通常用于实现诸如日志记录、字符集设置、访问拦截等功能。

过滤器是Javaweb的三大组件之一。其他两个为Servlet和Listener!

过滤器主要是请求目标资源(servlet,jsp,html,图片等一些web组件)之前进行拦截。

实现方式

写一个过滤器就是写一个Java类,然后实现Filter接口。然后在web.xml中配置,过滤的映射路径。与Servlet类似....

<!-- 配置过滤器 -->
<filter>
<filter-name>myFilter</filter-name>
<filter-class>com.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/index.jsp</url-pattern>//需要拦截的路径
</filter-mapping>
<!-- 配置第二个过滤器 -->
<filter>
<filter-name>myFilter2</filter-name>
<filter-class>com.filter.MyFilter2</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter2</filter-name>
<url-pattern>/index.jsp</url-pattern>
</filter-mapping>

多个过滤器执行顺序

web.xml中从 上往下执行,先执行到哪个那个优先过滤。

过滤器的生命周期

生命周期与servlet的类似。

\1. init(FilterConfig):

在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实例,从此不再创建!在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法只会被执行一次;

\2. doFilter(ServletRequest req,ServletResponse res,FilterChain chain):

这个方法会在用户每次访问“目标资源(pattern>/index.jsp)”时执行,如果需要“放行”,那么需要调用FilterChain的doFilter(ServletRequest,ServletResponse)方法,如果不调用FilterChain的doFilter()方法,那么目标资源将无法执行;

\3. destroy():

服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁它。一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter对象的destory()方法。

FilterChain chain.doFilter(req,resp);

对请求进行放行。

四种拦截方式

  1. request 默认的。对过滤的路径直接访问的时候会进入到过滤器。比如:地址栏中直接访问、表单提交、超链接、重定向。

  2. forword 转发访问执行的过滤器。如果访问的路径被过滤,我们还是可以通过间接的访问。比如:转发requestDispatcher#forword()方法、jsp:forword标签都是转发访问。

  3. include 包含访问执行的过滤。

  4. error 当目标资源在web.xml中配置中时,并且出现了异常,转发到目标资源时会执行过滤器。

  5. 里面配置

    <dispatcher>FORWARD</dispatcher>

    过滤器应用场景

    执行目标资源之前做预处理工资,比如设置编码,这种通常会放行。再比如对页面的权限访问。

    在请求前对编码的设置

    <!-- 设置编码的过滤器 -->
    <filter>
    <filter-name>encodeFilter</filter-name>
    <filter-class>com.filter.EncodeFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>encodeFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
    /**
    * 对所有请求的编码进行设置
    */
    request.setCharacterEncoding("utf-8");
    HttpServletRequest rq = (HttpServletRequest) request;
    if(rq.getMethod().equalsIgnoreCase("post")) {
    response.setContentType("text/html;charset=utf-8");
    }
    //放行
    chain.doFilter(request,response);
    }

监听器

监听器的概念:Listener是Servlet的监听器,是由容器管理的。servlet规范中定义的一套对范围对象(page,request,session,servletContext)的生命周期过程进行监听一种机制。使得发开人员更大程度地对PageContext,ServletContext,HttpSession和ServletRequest对象得生命周期进行控制。

监听器得作用:

利用listener接口见通风在容器中某个执行流程,比如监听Java对象得方法电泳或属性改变,当被监听得对象发生上述事件后,监听器某个方法将立即被执行。并且根据其与应用程序得需求做出适当得响应。

被监听的对象:

三个域对象:request session servletContext

​ 需要在web.xml中注册监听器,比如:

<!-- 配置监听在线人数监听器 -->
<listener>
<!-- 监听器类的路径-->
<listener-class>com.listener.CountListener</listener-class>
</listener>

监听ServletContext:

ServletContextListener接口:生命周期的方法

ServletContextAttributeListener接口:对属性的生命周期进行监听。

其他三大域以此类推。

package com.listener;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
/**
* 通过监听器,监听登录在线的人数。
*/
public class CountListener implements HttpSessionAttributeListener{
Set<Object> set = new HashSet<Object>();
private int count = 0;
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
if("aname".equalsIgnoreCase(event.getName())||"username".equalsIgnoreCase(event.getName())) {
set.add(event.getName()+":"+event.getValue());
System.out.println("wojin入了=="+event.getValue());
event.getSession().getServletContext().setAttribute("count", set.size());
event.getSession().getServletContext().setAttribute("set",set);
}
}
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
if("aname".equalsIgnoreCase(event.getName())||"username".equalsIgnoreCase(event.getName())) {
set.remove(event.getName()+":"+event.getValue());
System.out.println("我出去了=="+event.getValue());
event.getSession().getServletContext().setAttribute("count", set.size());
event.getSession().getServletContext().setAttribute("set",set);
}
}
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
if("aname".equalsIgnoreCase(event.getName())||"username".equalsIgnoreCase(event.getName())) {
Object obj = event.getSession().getAttribute(event.getName());
System.out.println(obj);
set.add(obj);
System.out.println("我替换了=="+event.getValue());
event.getSession().getServletContext().setAttribute("count", set.size());
event.getSession().getServletContext().setAttribute("set",set);
}
}
}

文件的上传和下载(fastupload)

在项目中使用SmartUpload组件可以进行文件的上传和下载操作。

详细见文档。

文件上传:

@Override
protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
//编码:SmartUpload获取的文件用的是GBK;
//创建一个上传对象
SmartUpload upload=new SmartUpload();
//初始化对象
upload.initialize(getServletConfig(),arg0,arg1);
//设置上传的基本设置
//设置允许的上传文件列表
upload.setAllowedFilesList("jpg,png,gif,txt");
//设置允许上传的单一文件的最大值,单位是字节;
upload.setMaxFileSize(2*1024*1024);
//设置一次性允许上传的多个文件的总共大小
upload.setTotalMaxFileSize(10*1024*1024);
try {
//设置禁止上传的文件的列表
upload.setDeniedFilesList("exe,com,bat");
//执行上传文件
upload.upload();
//获取上传的所有文件
Files files=upload.getFiles();
//通过getCount()获取总数;进行遍历;
for(int i=0;i<files.getCount();i++){
//遍历判断获取客户端上传的文件
File file =files.getFile(i);
if (file.isMissing()) {//如果文件不存在
continue;//不存在就不用处理
}
//获取上传的文件夹的位置;(项目的发布路径)
String path=arg0.getRealPath("upload");
//输出控制台查看项目的发布路径
System.out.println(path);
//获取上传的文件的文件名.同时修改编码方式;
String filename=new String(file.getFilePathName().getBytes(),"utf-8");
System.out.println("文件名:"+filename);
//使用原文件名保存文件;
file.saveAs(path+"/"+filename);
}
//使用smartupload的request对象去获取字符内容;
//因为form表单传过来的是字节流,不是字符流了;
Request request=upload.getRequest();
String username=new String(request.getParameter("username").
getBytes(),"utf-8");
System.out.println(username+"****");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

文件下载:

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String img=req.getParameter("img");
//String img=req.getParameter("file");
//创建一个上传下载对象;
SmartUpload upload=new SmartUpload();
//初始对象;
upload.initialize(getServletConfig(),req,resp);
//取消浏览器默认程序打开相对应文件的操作;
upload.setContentDisposition(null);
//下载相应的文件名
try {
//实现下载文件
upload.downloadFile("/image/"+img);
} catch (SmartUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

posted @   站着说话不腰疼  阅读(282)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示