1.1.1 需求:
1.1.2 分析:
1.1.2.1 技术分析:
1.1.3 代码实现:
1.1.4 总结:
1.1.4.1 文件上传问题:文件名重名.
在网站上有商品维护,上传商品图片,需要使用文件上传:
【文件上传的概述】
Ø 文件上传:
* 指的是将本地的文件 写到 服务器上.
Ø 文件上传技术:
* Servlet3.0 :注解开发,文件上传,异步请求.
* JSPSmartUpload :嵌入到JSP中完成文件上传.主要用于Model1年代的.
* FileUpload :Apache的文件上传组件.
* Struts2 :底层是FileUpload.
Ø 文件上传的要素:
* 表单的提交的方式必须是POST.
* 表单中需要有文件上传的表单元素:这个元素这个元素必须有name属性和值:<input type=”file” name=”upload”>
* 表单的enctype属性的值必须是multipart/form-data.
【Servlet3.0】
Ø Servlet3.0与Servlet2.5提供了三个新特性:
* 注解开发 :方便
* 文件上传 :有些API不是特别全.
* 异步请求 :
【Servlet3.0的注解开发】
Ø @WebServlet
Ø @WebListener
Ø @WebFilter
【文件上传原理分析】
Ø 设计文件上传的页面:
进行文件上传的抓包分析:
没有设置enctype属性的时候:只能获得文件的名称,而没有文件内容.
设置enctype属性为multipart/form-data:获得到文件名及文件内容.
【步骤一】:设置一个文件上传页面.
【步骤二】:点击提交,提交到Servlet中.
【步骤三】:在Servlet中接收参数.
【步骤四】:获得服务器的文件上传的路径.
【步骤五】:通过流写到该路径下就OK了.
代码:
[AppleScript]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
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
|
@WebServlet
(
"/UploadServlet"
)
@MultipartConfig
public
class
UploadServlet extends HttpServlet
{
private static final long serialVersionUID
=
1
L;
protected void doGet
(
HttpServletRequest request
,
HttpServletResponse response
)
throws ServletException
,
IOException
{
/
/
接收普通数据
:
request.setCharacterEncoding
(
"UTF-8"
)
;
String filedesc
=
request.getParameter
(
"filedesc"
)
;
System.out.println
(
"文件描述"
+
filedesc
)
;
/
/
接收文件
:
Part part
=
request.getPart
(
"upload"
)
;
long size
=
part.getSize
(
)
;
/
/
获得文件大小
:
System.out.println
(
"文件大小:"
+
size
)
;
String
name
=
part.getName
(
)
;
System.out.println
(
"文件表单中的name属性的名称"
+
name
)
;
/
/
获得文件名
:
String header
=
part.getHeader
(
"Content-Disposition"
)
;
int idx
=
header.lastIndexOf
(
"filename=\"
");
String fileName = header.substring(idx+10, header.length()-1);
System.out.println("
文件名
:
"+fileName);
// 获得文件内容:
InputStream is = part.getInputStream();
// 获得upload的路径:
String path = this.getServletContext().getRealPath("
/
upload
");
OutputStream os = new FileOutputStream(path+"
/
"
+
fileName
)
;
byte[] b
=
new
byte[
1024
];
int len
=
0
;
while
(
(
len
=
is
.
read
(
b
)
)
!
=
-1
)
{
os.
write
(
b
,
0
,
len
)
;
}
is
.
close
(
)
;
os.
close
(
)
;
}
protected void doPost
(
HttpServletRequest request
,
HttpServletResponse response
)
throws ServletException
,
IOException
{
doGet
(
request
,
response
)
;
}
}
|
使用随机的唯一文件名:
* 使用UUID作为随机的文件名.
1.1.4.2 文件上传问题:一个目录下存放的文件过多.
一个目录下文件过多,导致打开都很慢,更别说是读写操作.
目录分离:
* 按时间分 :一个月一个目录,一个星期一个目录,一天一个目录
* 按数量分 :一个目录下存5000个文件,创建一个新的目录,再去存放.
* 按用户分 :为每个用户创建一个单独目录 存放文件.
* 按目录分离算法分 :
* 使用唯一文件名.hashCode(); -- 得到一个代表当前这个文件的int类型值.
* int类型占4个字节32位.可以让hashCode值&0xf; 得到一个int值,用这个int值作为一级目录.
* 让hashCode右移4位 &0xf ;得到一个int值,用这个int值作为二级目录.依次类推.
1.1.4.3 Servlet3.0异步请求:
[AppleScript]
纯文本查看
复制代码
01
02
03
04
05
06
07
08
09
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
|
/
*
*
*
异步请求的Servlet
*
/
@WebServlet
(
urlPatterns
=
"/AsyncServlet"
,
asyncSupported
=
true
)
public
class
AsyncServlet extends HttpServlet
{
private static final long serialVersionUID
=
1
L;
protected void doGet
(
HttpServletRequest request
,
HttpServletResponse response
)
throws ServletException
,
IOException
{
AsyncContext
context
=
request.startAsync
(
request
,
response
)
;
context
.start
(
new
MyRunnable
(
context
)
)
;
for
(
int i
=
1
;i
<
=
10
;i
+
+
)
{
System.out.println
(
i
)
;
try
{
Thread.sleep
(
500
)
;
}
catch
(
InterruptedException e
)
{
e.printStackTrace
(
)
;
}
}
}
protected void doPost
(
HttpServletRequest request
,
HttpServletResponse response
)
throws ServletException
,
IOException
{
doGet
(
request
,
response
)
;
}
}
class
MyRunnable implements Runnable
{
private AsyncContext
context
;
public MyRunnable
(
AsyncContext
context
)
{
this.
context
=
context
;
}
@Override
public void
run
(
)
{
for
(
char i
=
'a';i
<
=
'z';i
+
+
)
{
try
{
context
.getResponse
(
)
.getWriter
(
)
.println
(
i
)
;
Thread.sleep
(
100
)
;
}
catch
(
Exception e
)
{
e.printStackTrace
(
)
;
}
}
}
}
|