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

来源:互联网 发布:kotlin转java 编辑:程序博客网 时间:2024/04/28 09:53

一. 文件上传的基本方法

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 {@Overridepublic 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 0
原创粉丝点击