使用Servlet3.0完成一个文件上传的功能

1.1.1 需求:
在网站上有商品维护,上传商品图片,需要使用文件上传:
1.1.2 分析: 1.1.2.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:获得到文件名及文件内容.
1.1.3 代码实现:
【步骤一】:设置一个文件上传页面.
【步骤二】:点击提交,提交到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 ) ;
 
}
 
  
 
}
1.1.4 总结: 1.1.4.1 文件上传问题:文件名重名.
使用随机的唯一文件名:
* 使用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 ( ) ;
 
}
 
}
 
}
 
 
}

猜你喜欢

转载自blog.csdn.net/qq_40208605/article/details/80910088