Struts2文件上传

笔者学习了Struts2文件上传和下载,

一、首先学习一下文件上传的原理:

表单元素的enctype属性:

enctype属指定的是表单数据的编码方式,该属性有如下三个值。

    1、application/x-www-form-urlencoded:这是默认编码模式,它只处理表单域的value属性值。采用这种编码方式的表单会将表单域的值处理成URL编码方式。

    2、multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据。这种编码方式会把文件与域指定文件的内容也封装到请求参数里。

    3、text/plain:当表单得Action属性为mailto:URL的形式时使用这种编码方式比较方便,这种方式主要适用于直接通过表单发送邮件的情况。


为了实现文件上传必须设置enctype属性设置为“”multipart/form-data",并把接受页面的代码改为直接使用二进制流处理的代码。

如果程序手动获取该请求中包含的二进制流,并将二进制流中包含的内容解析出来,程序就可以实现手动上传——完全无须任何框架的支持。


注意:一旦设置了表单的enctype="multipart/form-data" 属性,就将无法通过HttpServletRequest对象的getParamter放法取得请求参数。


二、手动上传

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ page import="java.io.*,java.util.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

</head>
<body>
<%
InputStream is=request.getInputStream();
BufferedReader br =new BufferedReader(new InputStreamReader(is));
String buffer =null;

while((buffer=br.readLine())!=null)
{
	if(buffer.endsWith("--")&&buffer.startsWith("---------------------------"))	
	{
		if(br.readLine().indexOf("filename")>1)
		{
			br.readLine();
			br.readLine();
			
			File file =new File(request.getRealPath("/")+UUID.randomUUID()+".txt");
			PrintStream ps =new PrintStream(new FileOutputStream(file));
			String content =null;
			while((content = br.readLine())!=null)
			{
				if(content.startsWith("----------------------"))
				{
					break;
				}
				ps.println(content);
			}
			ps.flush();
			ps.close();
		}
	}
}

%>
</body>
</html>


通过分析HttpServletRequest的二进制流,解析出二进制流中所包含的全部表单域,分析出每个表单域的类型,并允许开发者取得文件域的内容字节,文件名和文件内容等信息,也可以取得其他表单域的值。



Struts2的文件上传

Struts2默认使用的是Jakarta的Common-FileUpload文件上传框架,首先需要导入文件需要的架包, 即commons-io-1.3.2.jar和commons-fileupload-1.2.1.jar。

将上传页面的表单域的entype属性设置为“multipart/form-data”
upload.html页面:
<form action="uploadPro" method="post" enctype="multipart/form-data">
     文件标题:<input type="text" name="title"/><br>
     选择文件:<input type="file" name="upload"/><br>
  <input type="submit" value="上传">

</form>

UploadAction

package com.zmy.action;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.UUID;

import com.opensymphony.xwork2.ActionSupport;

/**
 * @author Administrator
 *
 */
public class UploadAction extends ActionSupport {
	private String title;
	private String upload;
	private String uploadContentType;
	private String uploadFileName;
	private String savePath;

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getUpload() {
		return upload;
	}

	public void setUpload(String upload) {
		this.upload = upload;
	}

	public String getUploadContentType() {
		return uploadContentType;
	}

	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}

	public String getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	public String getSavePath() {
		return savePath;
	}

	public void setSavePath(String savePath) {
		this.savePath = savePath;
	}

	@Override
	public String execute() throws Exception {
		// TODO Auto-generated method stub
		String newName=UUID.randomUUID()+uploadFileName.substring(uploadFileName.lastIndexOf("."));
		//以服务器的文件保存地址和随机文件名上传文件输入流
		FileOutputStream fos=new FileOutputStream(getSavePath()+"\\"+newName);
/*创建一个向具有指定名称的文件中写入数据的输出文件流。创建一个新 FileDescriptor 对象来表示此文件连接。
首先,如果有安全管理器,则用 name 作为参数调用 checkWrite 方法。
如果该文件存在,但它是一个目录,而不是一个常规文件;或者该文件不存在,但无法创建它;抑或因为其他某些原因而无法打开它,则抛出 FileNotFoundException。
name - 与系统有关的文件名*/
		FileInputStream fis=new FileInputStream(getUpload());
		byte[] buffer =new byte[1024];
		int len=0;
		while((len=fis.read(buffer))>0)
		{
			fos.write(buffer,0,len);
		}
		setUploadFileName(newName);
		return SUCCESS;
	}
}
Struts2直接将文件域中包含的上传文件名和文件类型的信息直接封装到uploadFileName和uploadContentType属性中。

即如果表单中包含一个name属性为xxx的文件域,则对应得Action需要使用三个属性来封装文件域的信息:

类型为File的xxx属性封装了该文件域对应得文件内容。

类型为String的xxxFileName属性封装了该文件域对应的文件的文件名。

类型为String的xxxContentType属性封装了该文件域对应的文件的文件类型。

savePath属性,该属性的值通过配置文件来设置,从而允许动态设置该属性的值--这是典型的依赖注入。


配置文件上传的Action

与之前的区别是,该Action还配置了一个<param.../>元素,该元素用于为该Action的属性动态分配属性值。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值