好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

使用Servlet处理一个上传的文件

servlet中可以使用post请求 上传文件 ,使用getreader()和getinputstream()自己处理,也可以使用getpart()或getparts()封装了一些功能的方法处理,getparts()可以同时上传多个文件。接下来使用四个demo来练习一下使用方法

一.使用getreader()和getinputstream()

demo1

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<!-- 这是html代码块,窗体网页上显示的是一个选择文件的input框和一个upload的button -->

<!doctype html>

<html>

  <head>

   <meta http-equiv= "content-type" content= "text/html; charset=utf-8" >

   <title></title>

  </head>

  <body>

   <form action= "upload" method= "post" enctype= "multipart/form-data" >

   选择文件:<input type= "file" name= "filename" value= "" /><br>

   <input type= "submit" value= "upload" name= "upload" />

   </form>

  </body>

</html>

?

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

//这是servlet处理部分

import java.io.datainputstream;

import java.io.fileoutputstream;

import java.io.ioexception;

import javax.servlet.servletexception;

import javax.servlet.annotation.webservlet;

import javax.servlet.http.httpservlet;

import javax.servlet.http.httpservletrequest;

import javax.servlet.http.httpservletresponse;

//servlet implementation class uploadservlet

@webservlet ( "/upload" )

public class uploadservlet extends httpservlet {

  private static final long serialversionuid = 1l;

  //@see httpservlet#dopost(httpservletrequest request, httpservletresponse response)

  protected void dopost(httpservletrequest request, httpservletresponse response)

    throws servletexception, ioexception {

   //读取请求body

   byte [] body = readbody(request);

   //取得所有body内容的字符串表示

   string textbody = new string(body, "iso-8859-1" );

   //取得上传的文件的文件名(取得路径并分离)

   string filename = getfilename(textbody);

   //取得文件内容在body中的首尾索引

   position p = getfileposition(request, textbody);

   //将内容输出到文件

   writeto(filename, body, p);

  }

  //存放索引的类

  class position{

   int begin;

   int end;

   position( int begin, int end) {

    this .begin = begin;

    this .end = end;

   }

  }

  //读取请求body

  private byte [] readbody(httpservletrequest request) throws ioexception {

   int formdatalength = request.getcontentlength();

   //获得servletinputstream对象

   //getreader()和getinputstream()只能则一调用,否则会抛出illegalstateexception异常

   datainputstream datastream = new datainputstream(request.getinputstream());

   byte [] body = new byte [formdatalength];

   int totalbytes = 0 ;

   while (totalbytes < formdatalength) {

    int bytes = datastream.read(body, totalbytes, formdatalength);

    totalbytes += bytes;

   }

   return body;

  }

  //取得上传文件名称

  private string getfilename(string reqbody) {

   //获取filename的value,10是filename="的长度

   //通过后台调试我发现filename=后加的是带着双引号的路径名,在获取路径名时不需要分号所以在分离时就将分号也分离掉了

   string filename = reqbody.substring(reqbody.indexof( "filename=\"" ) + 10 );

   //找到文件名这行的末尾,过滤掉对于获取文件名而言的无用信息

   filename = filename.substring( 0 , filename.indexof( "\n" ));

   //获取不包含路径名的文件名

   filename = filename.substring(filename.lastindexof( "\\" ) + 1 , filename.lastindexof( "\"" ));

   //此时后台打印分离路径后的文件名并将其作为返回值返回

   system.out.println(filename);

   return filename;

  }

  //取得文件开始和结束位置

  private position getfileposition(httpservletrequest request, string textbody) throws ioexception {

   //取得文件区段边界信息

   string contenttype = request.getcontenttype();

   string boundarytext = contenttype.substring(

     contenttype.lastindexof( "=" ) + 1 , contenttype.length());

   //取得实际上传文件的起始与结束位置

   int pos = textbody.indexof( "filename=\"" );

   pos = textbody.indexof( "\n" , pos) + 1 ;

   pos = textbody.indexof( "\n" , pos) + 1 ;

   pos = textbody.indexof( "\n" , pos) + 1 ;

   int boundaryloc = textbody.indexof(boundarytext, pos) - 4 ;

   int begin = ((textbody.substring( 0 , pos)).getbytes( "iso-8859-1" )).length;

   int end = ((textbody.substring( 0 , boundaryloc)).getbytes( "iso-8859-1" )).length;

   return new position(begin, end);

  }

  //输出至文件

  private void writeto(string filename, byte [] body, position p) throws ioexception {

   //默认上传的文件是在f:\\javaeearoundfiles目录下

   fileoutputstream fos = new fileoutputstream( "f:\\javaeearoundfiles\\later\\" + filename);

   fos.write(body, p.begin, (p.end - p.begin));

   fos.flush();

   fos.close();

  }

}

二.使用getpart()和getinputstream()

demo2

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

//html代码块

<!-- 该html供uploadpartdemo和uploadpartdemo2共同使用,使用时通过更改body的form的action属性值控制 -->

<!doctype html>

<html>

  <head>

   <meta http-equiv= "content-type" content= "text/html; charset=utf-8" >

   <title></title>

  </head>

  <body>

   <form action= "uploadphoto" method= "post"

   enctype= "multipart/form-data" >

   上传相片:<input type= "file" name= "photo" /><br><br>

   <input type= "submit" value= "上传" name= "upload" />

   </form>

  </body>

</html>

?

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

//uploadphotodemo.java

import java.io.filenotfoundexception;

import java.io.fileoutputstream;

import java.io.ioexception;

import java.io.inputstream;

import javax.servlet.servletexception;

import javax.servlet.annotation.multipartconfig;

import javax.servlet.annotation.webservlet;

import javax.servlet.http.httpservlet;

import javax.servlet.http.httpservletrequest;

import javax.servlet.http.httpservletresponse;

import javax.servlet.http.part;

//servlet implementation class uploadpartdemo

//tomcat中必须设置@mutipartconfig标注才能使用getpart()相关api

@multipartconfig

@webservlet ( "/uploadphoto" )

public class uploadpartdemo extends httpservlet {

  private static final long serialversionuid = 1l;

  //@see httpservlet#dopost(httpservletrequest request, httpservletresponse response)

  protected void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {

   // todo auto-generated method stub

   //getpart()获取part对象

   part part = request.getpart( "photo" );

   string filename = getfilename(part);

   writeto(filename, part);

  }

  private string getfilename(part part) {

   string header = part.getheader( "content-disposition" );

   //获取完整路径

   string filename = header.substring(header.indexof( "filename=\"" ) + 10 , header.lastindexof( "\"" ));

   //filename after substring is: f:\entertainment\pictures\e5e893df874df44d99f06bc52504a65c.jpg

   system.out.println( "filename after substring is: " + filename);

   //获取文件名

   filename = filename.substring(filename.lastindexof( "\\" ) + 1 );

   //filename after 2 substring is: e5e893df874df44d99f06bc52504a65c.jpg

   system.out.println( "filename after 2 substring is: " + filename);

   return filename;

  }

  private void writeto(string filename, part part) throws ioexception, filenotfoundexception {

   inputstream is = part.getinputstream();

   fileoutputstream fos = new fileoutputstream( "f:\\javaeearoundfiles\\later\\" + filename);

   byte [] buffer = new byte [ 1024 ];

   int length = - 1 ;

   while ((length = is.read(buffer)) != - 1 ) {

    fos.write(buffer, 0 , length);

   }

   is.close();

   fos.close();

  }

}

这个demo和第一个代码最大的区别就是,通过getpart()方法获得了part对象,通过part对象的getheader()方法指定标头获得对应的值。

在tomcat中要在servlet上设置@multipartconfig才能取得part对象,否则getpart会得到null

@multipartconfig含有的属性如下:

filesizethreshold:整数值设置,若上传文件大小超过设置门槛,则先写入缓存文件,默认值为0 location:字符串设置,设置写入文件时的目录,使用时与write方法一起使用,下一个demo中演示如何使用,默认是空字符串 maxfilesize:限制上传文件大小,默认-1l即无限制 maxrequestsize:限制multipart/form-data请求个数,默认值为-1l

demo3

使用part的write方法进行文件的写入,html文件查看demo2注释部分

?

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

//uploadphotodemo2.java

import java.io.ioexception;

import javax.servlet.servletexception;

import javax.servlet.annotation.multipartconfig;

import javax.servlet.annotation.webservlet;

import javax.servlet.http.httpservlet;

import javax.servlet.http.httpservletrequest;

import javax.servlet.http.httpservletresponse;

import javax.servlet.http.part;

//servlet implementation class uploadpartdemo2

//设置属性,这里的最后一级不用分隔符,可以与demo2中writeto方法的路径做一下对比

@multipartconfig (location= "f:\\javaeearoundfiles\\later" )

@webservlet ( "/uploadphoto2" )

public class uploadpartdemo2 extends httpservlet {

  private static final long serialversionuid = 1l;

  //@see httpservlet#dopost(httpservletrequest request, httpservletresponse response)

  protected void dopost(httpservletrequest request, httpservletresponse response)

    throws servletexception, ioexception {

   //文件名中可能有中文字符所以进行编码设置,使用setcharacterencoding()方法

   request.setcharacterencoding( "utf-8" );

   part part = request.getpart( "photo" );

   string filename = getfilename(part);

   //使用part的write方法,写入location指定路径

   part.write(filename);

  }

  //获取文件名与demo2相同不放代码

  private string getfilename(part part) {}

}

若要实现同时上传多个文件则可以使用getparts()方法,获取到的part对象被保存在一个collection中

demo4

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<!-- 该html是三个input选框,选择三个文件 -->

<!doctype html>

<html>

  <head>

   <meta http-equiv= "content-type"

     content= "text/html; charset=utf-8" >

   <title></title>

  </head>

  <body>

   <form action= "uploadparts" method= "post"

    enctype= "multipart/form-data" >

    文件 1 :<input type= "file" name= "file1" value= "" /><br>

    文件 2 :<input type= "file" name= "file2" value= "" /><br>

    文件 3 :<input type= "file" name= "file3" value= "" /><br><br>

    <input type= "submit" value= "上传" name= "upload" />

   </form>

  </body>

</html>

?

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

import java.io.ioexception;

import javax.servlet.servletexception;

import javax.servlet.annotation.multipartconfig;

import javax.servlet.annotation.webservlet;

import javax.servlet.http.httpservlet;

import javax.servlet.http.httpservletrequest;

import javax.servlet.http.httpservletresponse;

import javax.servlet.http.part;

//servlet implementation class uploadpartsdemo

@multipartconfig (location= "f:\\javaeearoundfiles\\later" )

@webservlet ( "/uploadparts" )

public class uploadpartsdemo extends httpservlet {

  private static final long serialversionuid = 1l;

  //@see httpservlet#dopost(httpservletrequest request, httpservletresponse response)

  protected void dopost(httpservletrequest request, httpservletresponse response)

    throws servletexception, ioexception {

   request.setcharacterencoding( "utf-8" );

   //使用foreach遍历获取每一个part对象

   for (part part : request.getparts()) {

    if (part.getname().startswith( "file" )) {

     string filename = getfilename(part);

     part.write(filename);

    }

   }

  }

  //与之前的getfilename()方法相同

  private string getfilename(part part) {

}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接

原文链接:https://blog.csdn.net/sdr_zd/article/details/77952196

查看更多关于使用Servlet处理一个上传的文件的详细内容...

  阅读:9次