
在java中上传文件似乎总有点麻烦,没.net那么简单,记得最开始的时候用smartUpload实现文件上传,最近在工作中使用spring的MultipartFile实现文件上传,感觉挺简单,在这里和大家分享一下.
一.主要有两个java类,和一般的servlet放在一起即可.
1.FileUploadBean.java
package chb.demo.web
import org.springframework.web.multipart.MultipartFile
/**
* @author chb
*
*/
public class FileUploadBean {
private MultipartFile file
public void setFile(MultipartFile file) {
this.file = file
}
public MultipartFile getFile() {
return file
}
}
2.FileUploadController.java
package chb.demo.web
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import org.springframework.validation.BindException
import org.springframework.web.multipart.MultipartFile
import org.springframework.web.servlet.ModelAndView
import org.springframework.web.servlet.mvc.SimpleFormController
/**
* @author chb
*
*/
public class FileUploadController extends SimpleFormController {
protected ModelAndView onSubmit(
HttpServletRequest request,
HttpServletResponse response,
Object command,
BindException errors){
try
{
// cast the bean
FileUploadBean bean = (FileUploadBean) command
// let's see if there's content there
MultipartFile file = bean.getFile()
if (file == null) {
throw new Exception("上传失败:文件为�空")
}
if(file.getSize()>10000000)
{
throw new Exception("上传失败:文件大小不能超过10M")
}
//得到文件�名
String filename=file.getOriginalFilename()
if(file.getSize()>0){
try {
SaveFileFromInputStream(file.getInputStream(),"D:/",filename)
} catch (IOException e) {
System.out.println(e.getMessage())
return null
}
}
else{
throw new Exception("上传失败:上传文件不能为�空")
}
// well, let's do nothing with the bean for now and return:
try {
return super.onSubmit(request, response, command, errors)
} catch (Exception e) {
System.out.println(e.getMessage())
return null
}
}
catch(Exception ex)
{
System.out.println(ex.getMessage())
return null
}
}
/**保存文件
* @param stream
* @param path
* @param filename
* @throws IOException
*/
public void SaveFileFromInputStream(InputStream stream,String path,String filename) throws IOException
{
FileOutputStream fs=new FileOutputStream( path + "/"+ filename)
byte[] buffer =new byte[1024*1024]
int bytesum = 0
int byteread = 0
while ((byteread=stream.read(buffer))!=-1)
{
bytesum+=byteread
fs.write(buffer,0,byteread)
fs.flush()
}
fs.close()
stream.close()
}
}
二.配置文件中如下配置:
1.web.xml,利用spring mvc模式,大家应该都很熟悉了
<servlet>
<servlet-name>chb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>chb</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
2.chb-servlet.xml,这里要配置映射,并可以设定最大可上传文件的大小
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- Multi-Action 用来标识method的变量名定义-->
<bean id="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName">
<value>action</value>
</property>
<property name="defaultMethodName">
<value>index</value>
</property>
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties availablethe maximum file size in bytes -->
<property name="maxUploadSize" value="10000000"/>
</bean>
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/upload.do">fileUploadController</prop>
</props>
</property>
</bean>
<bean id="fileUploadController" class="chb.demo.web.FileUploadController">
<property name="commandClass" value="chb.demo.web.FileUploadBean"/>
<!-- 上传失败时跳转页面 -->
<property name="formView" value="/user/err.jsp"/>
<!-- 上传成功时跳转页面 -->
<property name="successView" value="/user/confirmation.jsp"/>
</bean>
</beans>
三.设定jsp页面
<form id="form1" method="post" action="upload.do" enctype="multipart/form-data">
<tr>
<td width="25%" align="right">上传文件:</td>
<td><input id="file" type="file" NAME="file" style="width:300px"></td>
</tr>
<tr align="center" valign="middle">
<td height="60" colspan="2"><input type="submit" ID="BtnOK" value="确认上传"></td>
</tr>
</form>
ok,现在就可以上传文件了,挺简单吧?这里我只列出了基本步骤,至于具体的 *** 作(比如中文问题)可能就需要大家自己再完善完善了.
struts2单文件上传:首先是一个jsp文件上传页面,这个比较简单,就是一个表单,里面有个文件上传框
<!--在进行文件上传时,表单提交方式一定要是post的方式,因为文件上传时二进制文件可能会很大,还有就是enctype属性,这个属性一定要写成multipart/form-data,
不然就会以二进制文本上传到服务器端-->
<form action="fileUpload.action" method="post" enctype="multipart/form-data">
username: <input type="text" name="username"><br>
file: <input type="file" name="file"><br>
<input type="submit" value="submit">
</form>
接下来是FileUploadAction部分代码,因为struts2对上传和下载都提供了很好的实习机制,所以在action这段我们只需要写很少的代码就行:
public class FileUploadAction extends ActionSupport
{
private String username
//注意,file并不是指前端jsp上传过来的文件本身,而是文件上传过来存放在临时文件夹下面的文件
private File file
//提交过来的file的名字
private String fileFileName
//提交过来的file的MIME类型
private String fileContentType
public String getUsername()
{
return username
}
public void setUsername(String username)
{
this.username = username
}
public File getFile()
{
return file
}
public void setFile(File file)
{
this.file = file
}
public String getFileFileName()
{
return fileFileName
}
public void setFileFileName(String fileFileName)
{
this.fileFileName = fileFileName
}
public String getFileContentType()
{
return fileContentType
}
public void setFileContentType(String fileContentType)
{
this.fileContentType = fileContentType
}
@Override
public String execute() throws Exception
{
String root = ServletActionContext.getServletContext().getRealPath("/upload")
InputStream is = new FileInputStream(file)
OutputStream os = new FileOutputStream(new File(root, fileFileName))
System.out.println("fileFileName: " + fileFileName)
// 因为file是存放在临时文件夹的文件,我们可以将其文件名和文件路径打印出来,看和之前的fileFileName是否相同
System.out.println("file: " + file.getName())
System.out.println("file: " + file.getPath())
byte[] buffer = new byte[500]
int length = 0
while(-1 != (length = is.read(buffer, 0, buffer.length)))
{
os.write(buffer)
}
os.close()
is.close()
return SUCCESS
}
}
首先我们要清楚一点,这里的file并不是真正指代jsp上传过来的文件,当文件上传过来时,struts2首先会寻找struts.multipart.saveDir(这个是在default.properties里面有)这个name所指定的存放位置,我们可以新建一个struts.properties属性文件来指定这个临时文件存放位置,如果没有指定,那么文件会存放在tomcat的apache-tomcat-7.0.29\work\Catalina\localhost\目录下,然后我们可以指定文件上传后的存放位置,通过输出流将其写到流里面就行了,这时我们就可以在文件夹里看到我们上传的文件了。
文件上传后我们还需要将其下载下来,其实struts2的文件下载原理很简单,就是定义一个输入流,然后将文件写到输入流里面就行,关键配置还是在struts.xml这个配置文件里配置:
FileDownloadAction代码如下:
public class FileDownloadAction extends ActionSupport
{
public InputStream getDownloadFile()
{
return ServletActionContext.getServletContext().getResourceAsStream("upload/通讯录2012年9月4日.xls")
}
@Override
public String execute() throws Exception
{
return SUCCESS
}
}
我们看,这个action只是定义了一个输入流,然后为其提供getter方法就行,接下来我们看看struts.xml的配置文件:
<action name="fileDownload" class="com.xiaoluo.struts2.FileDownloadAction">
<result name="success" type="stream">
<param name="contentDisposition">attachmentfilename="通讯录2012年9月4日.xls"</param>
<param name="inputName">downloadFile</param>
</result>
</action>
struts.xml配置文件有几个地方我们要注意,首先是result的类型,以前我们定义一个action,result那里我们基本上都不写type属性,因为其默认是请求转发(dispatcher)的方式,除了这个属性一般还有redirect(重定向)等这些值,在这里因为我们用的是文件下载,所以type一定要定义成stream类型,告诉action这是文件下载的result,result元素里面一般还有param子元素,这个是用来设定文件下载时的参数,inputName这个属性就是得到action中的文件输入流,名字一定要和action中的输入流属性名字相同,然后就是contentDisposition属性,这个属性一般用来指定我们希望通过怎么样的方式来处理下载的文件,如果值是attachment,则会d出一个下载框,让用户选择是否下载,如果不设定这个值,那么浏览器会首先查看自己能否打开下载的文件,如果能,就会直接打开所下载的文件,(这当然不是我们所需要的),另外一个值就是filename这个就是文件在下载时所提示的文件下载名字。在配置完这些信息后,我们就能过实现文件的下载功能了。
struts2多文件上传:
其实多文件上传和单文件上传原理一样,单文件上传过去的是单一的File,多文件上传过去的就是一个List<File>集合或者是一个File[]数组,首先我们来看一下前端jsp部分的代码,这里我用到了jquery来实现动态的添加文件下载框以及动态的删除下载框:
<script type="text/javascript" src="script/jquery-1.8.1.js"></script>
<script type="text/javascript">
$(function()
{
$("#button").click(function()
{
var html = $("<input type='file' name='file'>")
var button = $("<input type='button' name='button' value='删除'><br>")
$("#body div").append(html).append(button)
button.click(function()
{
html.remove()
button.remove()
})
})
})
</script>
</head>
<body id="body">
<form action="fileUpload2.action" method="post" enctype="multipart/form-data">
username: <input type="text" name="username"><br>
file: <input type="file" name="file">
<input type="button" value="添加" id="button"><br>
<div></div>
<input type="submit" value="submit">
</form>
</body>
file的名字必须都命名成file才行,然后处理多文件上传的action代码如下:
public class FileUploadAction2 extends ActionSupport
{
private String username
//这里用List来存放上传过来的文件,file同样指的是临时文件夹中的临时文件,而不是真正上传过来的文件
private List<File>file
//这个List存放的是文件的名字,和List<File>中的文件相对应
private List<String>fileFileName
private List<String>fileContentType
public String getUsername()
{
return username
}
public void setUsername(String username)
{
this.username = username
}
public List<File>getFile()
{
return file
}
public void setFile(List<File>file)
{
this.file = file
}
public List<String>getFileFileName()
{
return fileFileName
}
public void setFileFileName(List<String>fileFileName)
{
this.fileFileName = fileFileName
}
public List<String>getFileContentType()
{
return fileContentType
}
public void setFileContentType(List<String>fileContentType)
{
this.fileContentType = fileContentType
}
@Override
public String execute() throws Exception
{
String root = ServletActionContext.getServletContext().getRealPath("/upload")
for(int i = 0i <file.size()i++)
{
InputStream is = new FileInputStream(file.get(i))
OutputStream os = new FileOutputStream(new File(root, fileFileName.get(i)))
byte[] buffer = new byte[500]
@SuppressWarnings("unused")
int length = 0
while(-1 != (length = is.read(buffer, 0, buffer.length)))
{
os.write(buffer)
}
os.close()
is.close()
}
return SUCCESS
}
}
这样同样将其写到一个输出流里面,这样我们就可以在文件夹里看到上传的多个文件了
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)