一.文件上传下载
1.文件上传
文件上传涉及到前台页面的编写和后台服务器端代码的编写,前台发送文件,后台接收 并保存文件,这才是一个完整的
文件上传。
1) 前台页面
在做文件上传的时候,会有一个上传文件的界面,首先我们需要一个表单,并且表单的 请求方式为 POST;其次我
们的 form 表单的 enctype 必须设为”multipart/form-data” 即 enctype="multipart/form-data" 意思是设置表单的MIME 编码。默认情况下这个编码格式 是 ”application/x-www-form-urlencoded”,不能用于文件上传;只有使用了multipart/form-data 才能完整地传递文件数据。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户登录</title>
</head>
<body>
<form action="userServlet" method="post">
姓名:<input type="text" name="uname" id="uname" /> <br/>
密码:<input type="password" name="upwd" id="upwd" /> <br/>
<input type="button" value="登录" onclick="checkForm()" />
<span id="msg" style="font-size:12px;color:red"></span>
<input type="hidden" name="actionName" value="form" />
</form>
</body>
<script type="text/javascript" src="js/jquery-3.4.1.js"></script>
<script type="text/javascript">
/*
* 验证表单
*/
function checkForm(){
// 获取用户名
var uname = $("#uname").val();
// 判断是否为空
if (uname.length < 1) {
$("#msg").html("姓名不能为空!");
return;
}
// 获取密码
var upwd = $("#upwd").val();
// 判断是否为空
if (upwd.length < 1) {
$("#msg").html("密码不能为空!");
return;
}
// 提交表单
$("form").submit();
}
</script>
</html>
2) 后台 commons-fileupload 的使用
首先需要导入第三方jar 包,http://commons.apache.org/ 下 载commons-io 和 commons-fileupload 两个jar 的资源。解压并导入到项目中。commons-fileupload.jar 是文件上传的核心包 commons-io.jar 是 filefupload 的依赖包,同时又是一个工具包。
介绍一下使用到的几个核心类
DiskFileItemFactory – 设置磁盘空间,保存临时文件。只是一个工具类
ServletFileUpload – 文件上传的核心类,此类接收 request,并解析
ServletFileUpload.parseRequest(request); – List 解析 request
1、 创建一个 DiskFileItemFactory 工厂类,并制定临时文件和大小
2、 创建 ServletFileUpload 核心类,接收临时文件,做请求的转换
3、 通过 ServletFileUpload 类转换原始请求,得到 FileItem 集合
4、 遍历集合中的各个元素并处理
5、 判断每个元素是否是普通表单项,如果是则按照普通表单项处理
6、 如果不是普通表单项,则是文件,通过处理的方式进行处理(上传)
public class UploadSource extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 设定编码,可以获取中文文件名
req.setCharacterEncoding("UTF-8");
// 获取tomcat下的upload目录的路径
String path = getServletContext().getRealPath("/upload");
// 临时文件目录
String tempPath = getServletContext().getRealPath("/temp");
// 检查我们是否有文件上传请求
// boolean isMultipart = ServletFileUpload.isMultipartContent(req);
// 1、声明DiskFileItemFactory工厂类,用于在指定磁盘上设置一个临时目录
DiskFileItemFactory disk = new DiskFileItemFactory(1024 * 10, new
File(tempPath));
// 2、声明ServletFileUpload,接收上面的临时文件。也可以默认值
ServletFileUpload up = new ServletFileUpload(disk);
// 3、解析request
try {
List<FileItem> list = up.parseRequest(req);
if (list.size() > 0) {
for (FileItem file : list)
// 判断是否是普通的表单项
if (file.isFormField()) {
String fieldName = file.getFieldName();
// 中文乱码,此时还需要指定获取数据的编码方式
// String value = file.getString();
String value = file.getString("UTF-8");
System.out.println(fieldName + "=" + value);
} else { // 说明是一个文件
// 获取文件本身的名称
String fileName = file.getName();
System.out.println(file.getFieldName());
// 处理文件名称
fileName =
fileName.substring(fileName.lastIndexOf("\\") + 1);
System.out.println("old Name : " + fileName);
// 修改名称
String extName =
fileName.substring(fileName.lastIndexOf("."));
String newName =
UUID.randomUUID().toString().replace("-", "") + extName;
// 保存新的名称,并写出到新文件中
file.write(new File(path + "/" + newName));
System.out.println("文件名是:" + fileName);
System.out.println("文件大小是:" + file.getSize());
file.delete();
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2. 文件下载
文件下载即将服务器上的资源下载(拷贝)到本地,我们可以通过两种方式下载。第一种是通过超链接本身的特性来下载;第二种是通过手动写出来下载。
1) 超链接下载
当我们在 HTML 或 JSP 页面中使用标签时,原意是希望能够进行跳转,但当超链接遇到浏览器不识别的动态网页时则会自动下载。例如超链接下载但当遇见浏览器能够直接显示的资源,浏览器就会默认显示出来,比如 txt,png,jpg 等。当然我们也可以通过 download 属性规定浏览器进行下载。但有些浏览器并不支持。
默认下载
指定 download 属性下载
这里,download 也可以不写任何信息,会自动使用默认文件名。这样当用户打开浏览 器点击链接的时候就会直接下载文件。
2) 后台实现下载
Step1:需要通过 HttpServletResponse.setContentType 方法设置 Content-type头字段的值, 为浏览器无法使用某种方式或激活某个程序来处理的 MIME 类型,例 如 ”application/octet-stream” 或 ”application/x-msdownload” 等
Step2:需要通过 HttpServletResponse.setHeader 方法设置Content-Disposition 头的值 为”attachment;filename=文件名”
Step3: 读取下载文件,调用HttpServletResponse.getOutputStream 方法返回的OutputStream 对象来向客户端写入附件内容。
public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
// 获取文件下载路径
String path = getServletContext().getRealPath("/") + "download/";
String fileName = req.getParameter("filename");
File file = new File(path + fileName);
if (file.exists()) {
// 设置相应类型 application/octet-stream
resp.setContentType("application/x-msdownload");
// 设置头信息
resp.setHeader("Content-Disposition", "attachment;filename=" +
fileName);
InputStream is = new FileInputStream(file);
ServletOutputStream os = resp.getOutputStream();
byte[] car = new byte[1024];
int len = 0;
while ((len = is.read(car)) != -1) {
os.write(car, 0, len);
}
// 关闭流、释放资源
os.close();
is.close();
} else {
System.out.println("文件不存在,下载失败!");
}
}
}
二、过滤器
1.介绍
Filter 即为过滤,用于在 Servlet 之外对 Request 或者 Response 进行修改。它主要用于对用户请求进行预处理,也可以对 HttpServletResponse 进行后处理。使用 Filter 的完整流程: Filter 对用户请求进行预处理,接着将请求交给 Servlet 进行处理并生成响应,最后 Filter 再 对服务器响应进行后处理。在一个 web 应用中,可以开发编写多个 Filter,这些 Filter 组合 起来称之为一个 Filter 链。
若是一个过滤器链:先配置先执行(请求时的执行顺序);响应时: 以相反的顺序执行。在 HttpServletRequest 到达 Servlet 之前,拦截客户的 HttpServletRequest 。根据需要检查HttpServletRequest,也可以修改 HttpServletRequest 头和数据。在HttpServletResponse 到达客户端之前,拦截 HttpServletResponse。根据需要检查 HttpServletResponse,也可以修改 HttpServletResponse 头和数据。
2. 实现
我们可以通过实现一个叫做javax.servlet.Fileter 的接口来实现一个过滤器,其中定义了 三个方法,init(), doFilter(), destroy()分别在相应的时机执行。后期观察生命周期。 Filter 的实现只需要两步:
Step1: 编写 java 类实现 Filter 接口,并实现其 doFilter 方法。
Step2: 在 web.xml 文件中对编写的 filter 类进行注册,并设置它所能拦截的资源。
Filter 接口中有一个 doFilter 方法,当开发人员编写好 Filter,并配置对哪个 web 资源进行拦截后,Web 服务器每次在调用 web 资源的 service 方法之前,都会先调用一下 filter 的 doFilter 方法。因此可以达到如下效果:
调用目标资源之前,让一段代码执行。
是否调用目标资源(即是否让用户访问 web 资源)。
web 服务器在调用 doFilter 方法时,会传递一个 filterChain 对象进来,filterChain 对象是 filter 接口中最重要的一个对象,它提供了一个 doFilter 方法,开发人员可以根据需求决定 是否调用此方法,调用该方法,则 web 服务器就会调用 web 资源的 service 方法,即 web 资源就会被访问,否则 web 资源不会被访问。(本质是放行,调用doFilter 方法后,即请求可以到达资源)
url-pattern 的配置:
①配置具体路径/index.html/TestServlet.do
②带有通配符的配置*.do /* /user/* *.html *.jsp
3. 过滤器执行的顺序
通过观察 web.xml 中的配置和各个filter 的执行顺序,找出filter 执行先后的依据。根据之前观察 Servlet 生命周期的的方式,观察一下过滤器的生命周期。
三、监听器
1. 介绍
web 监听器是一种 Servlet 中的特殊的类,它们能帮助开发者监听 web 中的特定事件, 比如 ServletContext,HttpSession,ServletRequest 的创建和销毁;变量的创建、销毁和修改等。 可以在某些动作前后增加处理,实现监控。例如可以用来统计在线人数等。
2. 实现
监听器有三类8 种:⑴监听生命周期:实现接口ServletRequestListener、HttpSessionListener 、 ServletContextListener⑵监听值的变化:实现接口ServletRequestAttributeListener、HttpSessionAttributeListener、ServletContextAttributeListener ⑶针对 session 中的对象:监听 session 中的java 对象(javaBean) 是 javaBean 直接实现监听器 的接口。这里我们只做一个简单的演示。假设我们想做一个对在线人数的监控。
Step1:创建一个监听器,需要实现某种接口,根据需求选取HttpSessionListener
Step2:在 web.xml 中配置该监听器
创建一个类,并实现 HttpSessionListener 接口,用来检测 Session 的创建和销毁。 在类中定义一个成员变量用来存储当前的 session 个数。
在 web.xml 中配置该监听器,让监听器生效
做一个测试的 Servlet 用来登陆,和显示当前在线人数
访问并测试结果