Servlet学习(三)

Servlet其他服务

本篇文章最后介绍一些Servlet上文件上传,处理日期,网页重定向,自动刷新等一些操作

文件上传

Servlet 可以与 HTML form 标签一起使用,来允许用户上传文件到服务器。上传的文件可以是文本文件或图像文件或任何文档。

工程中需要引入jar文件:commons-fileupload-1.3.2、commons-io-2.5.jar。

  1. 创建一个文件上传表单
  • 表单 method 属性应该设置为 POST 方法,不能使用 GET 方法。
  • 表单 enctype 属性应该设置为 multipart/form-data.
  • 表单 action 属性应该设置为在后端服务器上处理文件上传的 Servlet 文件。下面的实例使用了 UploadServlet Servlet 来上传文件。
  • 上传单个文件,您应该使用单个带有属性 type=”file” 的 <input …/> 标签。为了允许多个文件上传,请包含多个 name 属性值不同的 input 标签。输入标签具有不同的名称属性的值。浏览器会为每个 input
    标签关联一个浏览按钮。
1
2
3
4
5
6
<form method="post" action="/TomcatTest/UploadServlet" enctype="multipart/form-data">
选择一个文件:
<input type="file" name="uploadFile" />
<br/><br/>
<input type="submit" value="上传" />
</form>
  1. 编写后台 Servlet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

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 org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;


/**
* Servlet implementation class UploadServlet
*/
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

// 上传文件存储目录
private static final String UPLOAD_DIRECTORY = "upload";

// 上传配置
private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3; // 3MB
private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB
private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB

/**
* 上传数据及保存文件
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 检测是否为多媒体上传
if (!ServletFileUpload.isMultipartContent(request)) {
// 如果不是则停止
PrintWriter writer = response.getWriter();
writer.println("Error: 表单必须包含 enctype=multipart/form-data");
writer.flush();
return;
}

// 配置上传参数
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
factory.setSizeThreshold(MEMORY_THRESHOLD);
// 设置临时存储目录
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));

ServletFileUpload upload = new ServletFileUpload(factory);

// 设置最大文件上传值
upload.setFileSizeMax(MAX_FILE_SIZE);

// 设置最大请求值 (包含文件和表单数据)
upload.setSizeMax(MAX_REQUEST_SIZE);

// 中文处理
upload.setHeaderEncoding("UTF-8");

// 构造临时路径来存储上传的文件
// 这个路径相对当前应用的目录
String uploadPath = request.getServletContext().getRealPath("./") + File.separator + UPLOAD_DIRECTORY;


// 如果目录不存在则创建
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}

try {
// 解析请求的内容提取文件数据
@SuppressWarnings("unchecked")
List<FileItem> formItems = upload.parseRequest(request);

if (formItems != null && formItems.size() > 0) {
// 迭代表单数据
for (FileItem item : formItems) {
// 处理不在表单中的字段
if (!item.isFormField()) {
String fileName = new File(item.getName()).getName();
String filePath = uploadPath + File.separator + fileName;
File storeFile = new File(filePath);
// 在控制台输出文件的上传路径
System.out.println(filePath);
// 保存文件到硬盘
item.write(storeFile);
request.setAttribute("message",
"文件上传成功!");
}
}
}
} catch (Exception ex) {
request.setAttribute("message",
"错误信息: " + ex.getMessage());
}
// 跳转到 message.jsp
request.getServletContext().getRequestDispatcher("/message.jsp").forward(
request, response);
}
}
  1. 编译和运行 Servlet
  • 编译上面的 Servlet UploadServlet,并在 web.xml 文件中创建所需的条目,

Servlet 处理日期

Servlet可以直接使用Java 提供的 java.util 包中的 Date 类。

column0 column1
序号 方法 & 描述
1 boolean after(Date date)。如果调用的 Date 对象中包含的日期在 date 指定的日期之后,则返回 true,否则返回 false。
2 boolean before(Date date)。如果调用的 Date 对象中包含的日期在 date 指定的日期之前,则返回 true,否则返回 false。
3 Object clone( )。重复调用 Date 对象。
4 int compareTo(Date date)。把调用对象的值与 date 的值进行比较。如果两个值是相等的,则返回 0。如果调用对象在 date 之前,则返回一个负值。如果调用对象在 date 之后,则返回一个正值。
5 int compareTo(Object obj)。如果 obj 是 Date 类,则操作等同于 compareTo(Date)。否则,它会抛出一个 ClassCastException。
6 boolean equals(Object date)。如果调用的 Date 对象中包含的时间和日期与 date 指定的相同,则返回 true,否则返回 false。
7 long getTime( )。返回 1970 年 1 月 1 日以来经过的毫秒数。
8 int hashCode( )。为调用对象返回哈希代码。
9 void setTime(long time)。设置 time 指定的时间和日期,这表示从 1970 年 1 月 1 日午夜以来经过的时间(以毫秒为单位)。
10 String toString( )。转换调用的 Date 对象为一个字符串,并返回结果。

Servlet 网页重定向

当文档移动到新的位置,我们需要向客户端发送这个新位置时,我们需要用到网页重定向。网页重定向主要是为了实现负载均衡。

实现方法如下:

  1. sendRedirect() 方法
1
2
public void HttpServletResponse.sendRedirect(String location)
throws IOException

该方法把响应连同状态码和新的网页位置发送回浏览器。

  1. setStatus() 和 setHeader() 方法
1
2
3
String site = "http://www.nanaiii.com" ;
response.setStatus(response.SC_MOVED_TEMPORARILY);
response.setHeader("Location", site);

Servlet 点击计数器

网页点击计数器

很多时候,您可能有兴趣知道网站的某个特定页面上的总点击量。使用 Servlet 来计算这些点击量是非常简单的,因为一个 Servlet 的生命周期是由它运行所在的容器控制的。

以下是实现一个简单的基于 Servlet 生命周期的网页点击计数器需要采取的步骤:

  1. 在 init() 方法中初始化一个全局变量。
  2. 每次调用 doGet() 或 doPost() 方法时,都增加全局变量。
  3. 如果需要,您可以使用一个数据库表来存储全局变量的值在 destroy() 中。在下次初始化 Servlet 时,该值可在 init() 方法内被读取。这一步是可选的。
  4. 如果您只想对一个 session 会话计数一次页面点击,那么请使用 isNew() 方法来检查该 session 会话是否已点击过相同页面。这一步是可选的。
  5. 您可以通过显示全局计数器的值,来在网站上展示页面的总点击量。这一步是可选的。

网站点击计数器

很多时候,您可能有兴趣知道整个网站的总点击量。在 Servlet 中,这也是非常简单的,我们可以使用过滤器做到这一点。

以下是实现一个简单的基于过滤器生命周期的网站点击计数器需要采取的步骤:

  1. 在过滤器的 init() 方法中初始化一个全局变量。
  2. 每次调用 doFilter 方法时,都增加全局变量。
  3. 如果需要,您可以在过滤器的 destroy() 中使用一个数据库表来存储全局变量的值。在下次初始化过滤器时,该值可在 init() 方法内被读取, 这一步是可选的。

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void  doFilter(ServletRequest request, 
ServletResponse response,
FilterChain chain)
throws java.io.IOException, ServletException {

// 把计数器的值增加 1
hitCount++;

// 输出计数器
System.out.println("网站访问统计:"+ hitCount );

// 把请求传回到过滤器链
chain.doFilter(request,response);
}

web.xml中的配置:

1
2
3
4
5
6
7
8
9
<filter>
<filter-name>SiteHitCounter</filter-name>
<filter-class>SiteHitCounter</filter-class>
</filter>

<filter-mapping>
<filter-name>SiteHitCounter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

自动刷新页面

setIntHeader()方法

1
2
3
4
public void setIntHeader(String header, int headerValue)
//实例
// 设置刷新自动加载的事件间隔为 5 秒
response.setIntHeader("Refresh", 5);

此方法把头信息 “Refresh” 连同一个表示时间间隔的整数值(以秒为单位)发送回浏览器,从而实现自动刷新页面。

谢谢你请我吃糖果
0%