您的位置:首页 > 编程语言 > Java开发

Java web中上传文件

2016-07-06 09:59 399 查看


Java web中上传文件

先来看一下上传对form表单有什么要求?

必须是form表单提交。
表单中的method必须是post,不能是get
表单中的enctype的属性值必须是:multipart/form-data。当不是multipart的时候,就算<input type="file">提交的效果也和普通的text类型一样。
表单中项使用file类型

文件上传对servlet的要求?

因为表单中上传的不再是字符内容,而是字节内容。就算是上传文本文件也是一样的。所以不能使用request.getParameter(String fieldName)方法。
那使用什么呢。这个时候可以使用request.getInputStream();方法获取ServletInputStream对象,它是InputStream类的子类,这个对象对应表单的正文部分,关于正文部分下面会介绍。

关于正文部分介绍。

这个是有可以使用HTTP抓包工具,我使用的是Firebug。在Firefox进行抓包的。如下图所示:





ServletInput中就包含第二张图片的内容。可以通过以下方法得到

[java] view
plain copy

[java] view
plain copy

[java] view
plain copy

public void doPost(HttpServletRequest request,HttpServletResponse response)throw IOException,ServletException{

request.setCharacterEncoding("utf-8");

ServletInputStream in = request.getInputStream;

String s = IOUtils.toString(in);//Apache的commons组件中的包

System.out.println(s);//结果如下

}

[java] view
plain copy

执行结果如下:

和抓包来的没什么区别

[plain] view
plain copy

------WebKitFormBoundaryH06xO2noLxVFeenm

Content-Disposition: form-data; name="username"

csdn

------WebKitFormBoundaryH06xO2noLxVFeenm

Content-Disposition: form-data; name="filename"; filename="a.txt"

Content-Type: text/plain

E:\Application\workspace\exam\src\cn\itcast\day20\CountDemo.java

E:\Application\workspace\exam\src\cn\itcast\day20\FileDemo.java

E:\Application\workspace\exam\src\cn\itcast\day20\FileDemo2.java

E:\Application\workspace\exam\src\cn\itcast\day20\FileDemo3.java

E:\Application\workspace\exam\src\cn\itcast\day20\FileDemo4.java

E:\Application\workspace\exam\src\cn\itcast\day20\FileFilterDemo.java

E:\Application\workspace\exam\src\cn\itcast\day20\JavaFileList.java

E:\Application\workspace\exam\src\cn\itcast\day20\PrintWriterDemo.java

E:\Application\workspace\exam\src\cn\itcast\day20\PropertiesDemo.java

E:\Application\workspace\exam\src\cn\itcast\day20\SequenceDemo.java

E:\Application\workspace\exam\src\cn\itcast\day20\SequenceInputStreamDemo.java

E:\Application\workspace\exam\src\cn\itcast\day20\SequenceVideoDemo.java

E:\Application\workspace\exam\src\cn\itcast\day20\SplitFileDemo.java

------WebKitFormBoundaryH06xO2noLxVFeenm--



上传的任务就是将这些信息解析出来如果是文件部分保存到文件中,不是文件部分该给谁给谁。

4.按照上面的上传文件中ServletInputStream流的格式我自己写了一个,只能上传文本文件的上传方法。(能力有限)

[javascript] view
plain copy

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//得到流对象

ServletInputStream in = request.getInputStream();

//将流中的对象写入到一个字符串中。可能使用StringBuffer更好

int len = 0;

byte buf[] = new byte[1024];

String content = "";

while((len = in.read(buf))!=-1){

content = content + new String(buf, 0, len);

}

//将内容按行分割

String[] contents = content.split("\n");

//将数组转换成数组

List<String> lists = Arrays.asList(contents);

//是否包含这个Content-Type: text/plain。也就是文本文件内容的开始了

System.out.println("执行:"+lists.contains(new String("Content-Type: text/plain")));

//获取开始和结束位置

int start = 0;

int end = 0;

for (int i=1;i<lists.size();i++) {

if(lists.get(0).equals(lists.get(i))){

end = i;

}

}

System.out.println(start+":"+end);

//将数组按开始位置和结束位置截取

List<String> fileList = lists.subList(end+4, lists.size()-1);

//保存的文件

FileWriter writer = new FileWriter("F:\\a.txt");

//遍历数组如入文件

for (String s : fileList) {

writer.write(s);

writer.write("\n");

}

writer.close();

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request,response);

}




使用Apache的commons组件包实现上传(还是这个强大):

快速入门(得到的效果和上面的一样):

[java] view
plain copy

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//获取解析器工厂

DiskFileItemFactory factory = new DiskFileItemFactory();

//获得解析器

ServletFileUpload fileUpload = new ServletFileUpload(factory);

try {

//解析request

List<FileItem> items = fileUpload.parseRequest(request);

//遍历解析得到的FileItem对象

for(FileItem item : items){

//如果字段名是username

if(item.getFieldName().equalsIgnoreCase("username")){

//得到提交过来的值

System.out.println(item.getString());

//如果是这个说明是文件

}else if(item.getFieldName().equalsIgnoreCase("fileName")){

//得到提交过来的值,如果是文本文件能输出,否则是乱码

item.write(new File("F:\\","b.txt"));

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

完全体演示:

[java] view
plain copy

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//解决中文文件名问题

/**

* 也可以是fileUpload.setHeaderEncoding("utf-8");优先级高

*/

request.setCharacterEncoding("utf-8");

//获取解析器工厂,在factory中设置 (1024*20,new File("F://temp");如果文件过大

//设置文件超过20kb就缓存,缓存文件是在F盘的temp文件下

DiskFileItemFactory factory = new DiskFileItemFactory();

//获得解析器

ServletFileUpload fileUpload = new ServletFileUpload(factory);

//设置上传的全部大小,包括<input type='text'>

// fileUpload.setSizeMax(1024*900);

//设置上传文件的大小,1024为1kb

fileUpload.setFileSizeMax(300*1024);

// fileUpload.setHeaderEncoding("utf-8");

try {

//解析request

List<FileItem> items = fileUpload.parseRequest(request);

//遍历解析得到的FileItem对象

for(FileItem item : items){

//如果字段名是username

if(item.getFieldName().equalsIgnoreCase("username")){

//得到提交过来的值

System.out.println(item.getString());

//如果是这个说明是文件

}else if(item.getFieldName().equalsIgnoreCase("fileName")){

//得到文件名

String fileName = item.getName();

//防止有些浏览器上传文件的时候,上传文件的带盘符的绝对路径。我们只要文件名就行

int index = fileName.lastIndexOf("\\");

if(index!=-1){

fileName = fileName.substring(index+1);

}

//获取后缀名.假设我只上传静态图片格式的文件,也就是格式是jpg,bmp,png这三种。其他的都不要

index = fileName.lastIndexOf(".");

//说明没有后缀名

if(index==-1){

//一般情况是,通过request.setAttribute("msg","您上传的文件没有后缀名,请重新上传");

//转发到request.getRequestDispatcher("路径").forward(request, response);

//return;

//这里我就全输出了

System.out.println("上传的文件没有后缀名");

return;

}

String extension = fileName.substring(index+1);

//上传文件如果不是以上面三个后缀名结尾,就输出错误信息

if (!extension.equalsIgnoreCase("bmp")

&& !extension.equalsIgnoreCase("jpg")

&& !extension.equalsIgnoreCase("png")) {

System.out.println("上传的文件必须是bmp或jpg或png");

return;

}

//上传文件肯定是多个,命名也是一个问题。使用Apache的commons组件的类

fileName = getuuid()+"."+extension;

//上传的文件放到哪,只能放在WEB-INF下面.如果你下面还要放分目录的话。有很多的算法

//有按时间的,用户的,文件名的hash值的等等。看需求

//我来按时间,也就是每天一个文件夹

String timeStamp = new SimpleDateFormat("yyyy.MM.dd").format(new Date());

String savePath = this.getServletContext().getRealPath("/WEB-INF/myupload")+"\\"+timeStamp;

File f = new File(savePath);

f.mkdirs();

item.write(new File(savePath,fileName));<pre name="code" class="java"><span style="white-space:pre"> </span>item.delete();//删除临时文件</pre> }}} catch (Exception e) {if(e instanceof FileUploadBase.FileSizeLimitExceededException){System.out.println("上传文件不能大于300kb");return;}else{e.printStackTrace();}}}public static String getuuid() {return UUID.randomUUID().toString().replace("-",

"");}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}

<pre></pre>

<pre></pre>

如果还要判断上传文件的宽度和高度。只需在后面加上:

[java] view
plain copy

<span style="white-space:pre"> </span>File f = new File(savePath);

f.mkdirs();

File saveFile = new File(savePath,fileName);

item.write(saveFile);

item.delete();//删除临时文件

ImageIcon icon = new ImageIcon(saveFile.getAbsolutePath());

Image image = icon.getImage();

image.getHeight(null);//得到图片的高

image.getWidth(null);//得到文件的宽

//如果不满足条件

saveFile.delete();

其他类型的文件也就类似了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: