【Struts2】(8)文件上传和下载

10 篇文章 0 订阅

一. 文件上传的基本方法

1. 最简单的上传文件

我们新建一个Action类:
public class UploadAction {

	private File myFile;

	public File getMyFile() {
		return myFile;
	}

	public void setMyFile(File myFile) {
		this.myFile = myFile;
	}

	public String upload() {
		try {
			FileUtils.copyFile(myFile, new File("d:/temp.jpg"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "success";
	}
}
使用了FileUtils.copyFile将一个文件复制到另一个文件。
然后配置struts文件和对象的jsp文件:
<struts>
	<include file="common.xml"></include>
	<package name="basicstruts2" extends="common" namespace="/test">
		<action name="upload" class="com.thr.struts2.action.UploadAction">
			<result>/upload_success.jsp</result>
		</action>

	</package>
</struts>
<body>
	<form action="/web/test/upload.action" enctype="multipart/form-data" method="post">
		选择文件:<input name="myFile" type="file"/><br />
		<input type="submit" name="method:upload"	value="上传" />
	</form>
	
</body>
运行,选择一个文件之后点击提交就可以是上传文件了。 

2. 获取文件名

如果我们想获取源文件相关的信息,例如文件名等,就需要这样子修改Action文件:
public class UploadAction {

	private File myFile;
	private String myFileFileName;
	private String myFileContentType;

	public File getMyFile() {
		return myFile;
	}

	public void setMyFile(File myFile) {
		this.myFile = myFile;
	}

	public String getMyFileFileName() {
		return myFileFileName;
	}

	public void setMyFileFileName(String myFileFileName) {
		this.myFileFileName = myFileFileName;
	}

	public String getMyFileContentType() {
		return myFileContentType;
	}

	public void setMyFileContentType(String myFileContentType) {
		this.myFileContentType = myFileContentType;
	}

	public String upload() {
		try {
			System.out.println("文件名:" + myFile.getName());
			System.out.println(myFileFileName);
			System.out.println(myFileContentType);
			FileUtils.copyFile(myFile, new File("d:/" + myFileFileName));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "success";
	}
}
注意新创建的两个String变量,一个在myFile后面加FileName,另一个是在后面加ContentType,这两个变量一个是用来获取文件名,另一个是用来指定处理文件类型的,这样在传输文件的时候就可以按照原有的文件名进行上传了。

3. 上传到自己的web路径

可以使用
			FileUtils.copyFile(myFile,
					new File(ServletActionContext.getServletContext()
							.getRealPath("/upload/" + "/" + myFileFileName)));
来上传到自己的空间下,这里在upload目录后又跟了一个"/"是因为它将/upload/整体解析为一个目录了,所以要在加一个斜杠。
为了避免上传时会遇到报错,还可以加入下面两个常量:
	<constant name="struts.multipart.saveDir" value="D:/web/temp"></constant>
	<constant name="struts.multipart.maxSize" value="80000000"></constant>
第一个是用来指定上传保存的临时目录,第二是允许上传文件的最大容量。

二. 上传文件至数据库

1. 以文件转换成字节数组格式上传至数据库

我们增加一个方法:
	public String upload2() {
		Connection conn = DB.getConnection();
		String sql = "insert into t_user(id, my_file) values(?, ?)";
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setInt(1, 12);
			ps.setBytes(2, FileUtils.readFileToByteArray(myFile));
			ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		DB.closeConnection(conn);
		return "success";
	}
使用FileUtils的readFileToByteArray方法可以将文件类型转换为字节数组类型,然后插入到数据库。

2. 以字节数组转换器保存至数据库

要直接将byte数组存至数据库,就要写一个转换器:
public class FileConverter extends DefaultTypeConverter {

	@Override
	public Object convertValue(Object arg0, Class arg1) {

		if (arg0 instanceof File[]) {
			try {
				byte[] bytes = FileUtils
						.readFileToByteArray(((File[]) arg0)[0]);
				return bytes;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		throw new RuntimeException("不是文件类型,无法转换!");
	}
}
配置和之前配转化器一样,穿件UploadAction-conversion.properties:
myBytes=com.thr.struts2.converter.FileConverter
在UploadAction中创建myBytes成员变量,生成set和get方法:
	public String upload3() {
		Connection conn = DB.getConnection();
		String sql = "insert into t_user(id, my_file) values(?, ?)";
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setInt(1, 15);
			ps.setBytes(2, myBytes);
			ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		DB.closeConnection(conn);
		return "success";
	}
记得修改jsp页面的变量名为myBytes,这样就可以直接以byte数组存入数据库了。

三. 复杂参数传递和多文件上传

1. 复杂参数传递

新写一个CollectionAciton类,里面包括了一个List和一个Map:
public class CollectionAction {

	private List<Contact> contacts;
	private Map<String, Contact> contactsMap;

	public List<Contact> getContacts() {
		return contacts;
	}

	public void setContacts(List<Contact> contacts) {
		this.contacts = contacts;
	}

	public Map<String, Contact> getContactsMap() {
		return contactsMap;
	}

	public void setContactsMap(Map<String, Contact> contactsMap) {
		this.contactsMap = contactsMap;
	}

	public String execute() {
		return "success";
	}

}
里面装的类型就是我们之前的Contact类。
配置struts文件,写一个jsp文件用来显示上传内容:
	<form action="/web/test/collection.action" enctype="multipart/form-data" method="post">
		List:<br />
		Contact:<br />
		qq:<input name="contacts[0].qq" />,
		tel:<input name="contacts[0].tel" />,
		phone:<input name="contacts[0].phone" />,<br />
		Contact2:<br />
		qq:<input name="contacts[1].qq" />,
		tel:<input name="contacts[1].tel" />,
		phone:<input name="contacts[1].phone" />,<br />
		Map:<br />
		Contact:<br />
		qq:<input name="contactsMap['contact'].qq" />,
		tel:<input name="contactsMap'contact'].tel" />,
		phone:<input name="contactsMap'contact'].phone" />,<br />
		Contact2:<br />
		qq:<input name="contactsMap['contact2'].qq" />,
		tel:<input name="contactsMap['contact2'].tel" />,
		phone:<input name="contactsMap['contact2'].phone" />,<br />
		<input type="submit" value="上传" />
	</form>
通过这个文件,我们看到了如果使用OGNL表达式来传递复杂的参数。

2. 多文件上传

想要实现多文件上传,只需在jsp页面中添加多个input就可以了:
	<form action="/web/test/upload.action" enctype="multipart/form-data" method="post">
		选择文件1:<input name="multiFile" type="file"/><br />
		选择文件2:<input name="multiFile" type="file"/><br />
		<input type="submit" name="method:multiUpload"	value="上传" />
	</form>
然后在Action中指定我们的变量:
	private File[] multiFile;
	private String[] multiFileFileName;
	private String[] multiFileContentType;
这样子就可以获取我们上传的文件信息啦。

四. 文件下载

我们先修改一下数据库增加varchar类型的fileName和contentType类型。我们上传几个文件到数据库。
创建一个用来下载文件的Action:
public class DownloadAction {

	private InputStream stream;
	private int id;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public InputStream getStream() {
		InputStream inputStream = null;
		Connection conn = DB.getConnection();
		String sql = "select myFile, fileName, contentType from t_user where id=?";
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setInt(1, id);
			ResultSet rs = ps.executeQuery();
			rs.next();
			inputStream = rs.getBinaryStream("myFile");
			ActionContext.getContext()
					.put("fileName", rs.getString("fileName"));
			ActionContext.getContext().put("contentType",
					rs.getString("contentType"));
		} catch (SQLException e) {
			e.printStackTrace();
		}
		DB.closeConnection(conn);
		return inputStream;
	}

	public String execute() {
		return "success";
	}

}
id用来接收页面上传过来的id,我们将文件名和文件类型保存到了ActionContext中,方便在配置文件中动态读取。
然后配置struts文件:
		<action name="download" class="com.thr.struts2.action.DownloadAction">
			<result type="stream">
				<param name="contentType">%{#contentType}</param>
				<param name="inputName">stream</param>
				<param name="contentDisposition">attachment;filename="%{#fileName}"</param>
			</result>
		</action>
最后写下载页面:
<body>
	<a href="/web/test/download.action?id=16">下载id16</a><br />
	<a href="/web/test/download.action?id=17">下载id17</a><br />
	<a href="/web/test/download.action?id=18">下载id18</a><br />
	
</body>
id=16、17、18对应我们数据库中保存的3个id的文件。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值