上传文件一直是我头疼的问题,那些流的问题很恼火,这几天终于有理出一点头绪,在这里记录一下,方便以后不记得了可以回忆回忆。
首先是我的action,我这个上传是要在添加文件的时候上传一个附件,所以这个action 有很多个方法,只是在struts.xml里面的配置不同返回的东西不一样而已。我这个上传的和添加数据是同一个方法里面的。当然你也可以写成两个方法。
方法:saveAttachments
//文件标题从jsp接受进行保存
private String fileTitle;
//文件路径
private String fileUrl;
// 上传文件域对象
private File file;
// 上传文件名
private String fileFileName;
//第一步:获取发出请求的路径(tomcat编译后的文件目录)
String uploadDir = ServletActionContext.getServletContext().getRealPath(Constants.FILE_SEP +"upload")+ Constants.FILE_SEP;
File dirPath = new File(uploadDir);
if (!dirPath.exists()) {//判断存放附件的文件夹upload是否存在
dirPath.mkdirs(); //否则创建当前目录
}
//file1对象 是用来判断上传的文件是否存在(根据上传文件的文件名判断),避免重复上传覆盖了前面文件的内容。
String address = dirPath.getAbsolutePath() + Constants.FILE_SEP + fileFileName;
File file1 = new File(address); //存进数据库的path
fileUrl = "upload"+Constants.FILE_SEP+fileFileName;
//为保存赋值
attachment = new Attachments();
if(fileTitle == null){
fileTitle= fileFileName;
}
attachment.setFileName(fileTitle);
attachment.setUploadDate(new Date());
attachment.setFilePath(fileUrl);
//传
//禁止上传包含中文的文件(不要这个判断可以上传中文的)
String anotherString = null;
try {
anotherString = new String(fileFileName.getBytes("GBK"), "ISO8859_1");
}
catch (java.io.UnsupportedEncodingException ex) {
}
if(fileFileName.length()!=anotherString.length()){
saveMessage(getText("file.upload.string"));
}else
//判断文件大小是否是0字节(不做这个判断会报找不到文件的错误)
if(file.length()==0){
saveMessage(getText("file.upload.min"));
}else
//读取流上传
if(attachmentsManager.checkFile(address) && !file1.exists()){
Attachments att = attachmentsManager.save(attachment);
if(att!=null && file!=null){
InputStream stream; //输入
OutputStream bos; //输出
try {
stream = new FileInputStream(file);
bos = new FileOutputStream(uploadDir + fileFileName);
int bytesRead;
byte[] buffer = new byte[1024];
while ((bytesRead = stream.read(buffer, 0, 1024)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.close();
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
saveMessage(getText("file.upload.success"));
}else{
saveMessage(getText("file.upload.fail"));
}
}else{
saveMessage(getText("file.upload.exist"));
}
return showUpload(); //我这里返回的我是显示数据列表的方法,可以根据自己的情况在struts.xml里面配置
}
下面是我所遇到的问题:
问题一:
由于我这里的下载是同超链接下载的,不能下载带中的文件,所以在上传的时候做了判断,不能上传中文的。
问题二:
严重: Servlet.service() for servlet default threw exception
java.io.FileNotFoundException: F:\apache-tomcat-6.0.18\work\Catalina\localhost\Struts2FileUpload\upload_7eaf9265_121967f32c7__7ff5_00000001.tmp (系统找不到指定的文件。)
这种错误一般有两个原因:
原因一:就是action取名的时候变量名没有注意,Struts2上传文件是接收到前台的参数进行后台给变量赋值时,变量的名称的定义不是随便的,struts2有一种自动的机制,(具体的我也不是很清楚,只是知道名字取对了他会自动为你保存的)能够将文件名,文件类型自动保存到一个变量里面(File 对象的变量+你的变量名)。
原因二:就是上传了文件为0字节的文件,在上传前之前判断一下就可以了。
我的下载方法:
我用的是超链接下载(网上看了好多,这个比较简单,可不好的就是不能下载中文名称的文件):
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
这样可以获取到当前你服务器的地址了比如:(http://localhost:8080/......)
<a href ="前面获取路径的那个变量+数据库里面存的文件名" target="_blank"> 下 载 </a>
用文件流下载的方式:
用这种方法的一个好处是可以下载中文文件,
下面是我的java代码:
public String downFile(){
//获取前台传过来的id。
String id = getRequest().getParameter("id");
//根据传过来的id找到对应的文件名称。
Attachments att = attachmentsManager.get(Long.valueOf(id));
HttpServletResponse resp = ServletActionContext.getResponse();
String path = ServletActionContext.getServletContext().getRealPath(Constants.FILE_SEP);
String filename = Constants.FILE_SEP +att.getFilePath(); // 生成文件的文件名称 这个需要动态的获取
OutputStream out;// 输出响应正文的输出流
InputStream in;// 读取本地文件的输入流
// 获得本地输入流
File file = new File(path + filename);
try {
in = new FileInputStream(file);
// 设置响应正文的MIME类型
resp.setContentType("Content-Disposition;charset=GB2312");
resp.setHeader("Content-Disposition", "attachment;" + " filename="
+ new String(filename.getBytes(), "ISO-8859-1"));
// 把本地文件发送给客户端
out = resp.getOutputStream();
int byteRead = 0;
byte[] buffer = new byte[512];
while ((byteRead = in.read(buffer)) != -1) {
out.write(buffer, 0, byteRead);
}
in.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
在jsp页面调用这个方法即可,别忘了得把id传到方法里面。
设置上传文件大小。在struts.xml里面
<constant name="struts.multipart.maxSize" value="10000000" />”