EXT2.0+STRUTS2框架上的文件下传和中文文件上载
1.struts-xml配置文件的设置:
<constant name="struts.multipart.maxSize" value="15097152"/><!-- 文件上传中整个请求内容允许的最大字节数为15M -->
<!-- 提供文件上传功能 -->
<interceptor-ref name="fileUpload"/>
<!-- 附件 Action -->
<action name="attachmentsAction" class="*.*.action.AttachmentsAction">
<!--这里这个设置是必须的。不要调用文件拦截器。。后面在ACTION就可以知道此处的重要性--!>
<interceptor-ref name="fileUploadStack"/>
<result type="json"></result>
</action>
2.ext页面attachment.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<html>
<head>
<title>附件管理</title>
<link href="/ext/resources/css/ext-all.css" rel="stylesheet" type="text/css" />
<script language="JavaScript" type="text/javascript" src="/ext/ext-base.js"></script>
<script language="JavaScript" type="text/javascript" src="/ext/ext-all.js"></script>
<script language="JavaScript" type="text/javascript" src="/ext/ext-lang-zh_CN.js"></script>
<script language="JavaScript" type="text/javascript">
var center;
var addFrom;
Ext.onReady(function(){
addForm = new Ext.FormPanel({
id: 'addForm',
fileUpload:true,
frame:true,
labelWidth: 60,
bodyStyle: 'padding:5px 5px 0',
labelAlign:'left',
items:[{
border: false,
layout:'column',
collapsible: true,
items: [{
columnWidth : 0.98,
border: false,
layout : 'form',
defaultType : 'textfield',
items : [
{fieldLabel:'文件1', xtype:'textfield', inputType:'file', name: 'upload', cls:'nobordertext', anchor:'98%',allowBlank: true},
{fieldLabel: '摘要1', maxLength:'255', name: 'description', maxLengthText:'供方负责人的字数不能超过50', anchor:'98%'}
,{fieldLabel:'文件2', xtype:'textfield', inputType:'file', name: 'upload', cls:'nobordertext', anchor:'98%'},
{fieldLabel: '摘要2', maxLength:'255', name: 'description', maxLengthText:'供方负责人的字数不能超过50', anchor:'98%'},
{fieldLabel:'文件3', xtype:'textfield', inputType:'file', name: 'upload', cls:'nobordertext', anchor:'98%'},
{fieldLabel: '摘要3', maxLength:'255', name: 'description', maxLengthText:'供方负责人的字数不能超过50', anchor:'98%'}
]
}
]
}
],
buttons: [
{text: '确定',handler: saveForm},
{text: '关闭',handler: function(){
addForm.getForm().reset();
window.close();
}
}
]
});
center = new Ext.Panel({
id: 'center',
region:'center',
border: false,
autoScroll: true,
enableTabScroll:true,
items: [addForm]
});
var panel = new Ext.Panel({
id: 'panel',
layout:'fit',
border: false,
items: [center]
});
var viewport = new Ext.Viewport({
id: 'viewport',
layout: 'fit',
autoScroll: true,
items:[panel]
});
});
function saveForm(){
var _url ="/*/*/attachmentsAction!saveAttachmentsInfo.html";
addForm.getForm().submit({
url: _url,
method: 'post',
//params:{fkId: addForm.findById("fkId").getValue()},
//提交成功的回调函数
success:function(form,action){
if (action.result.msg=='success') {
addForm.getForm().reset();
window.close();
} else if (action.result.msg=='notFile') {
Ext.Msg.alert('提示','上传的文件不存在!请重试!');
} else if(action.result.msg=='SizeLimitExceededException') {
Ext.Msg.alert('提示','您上传的文件太大!文件不能超过15M');
}
},
failure:function(form,action){
Ext.MessageBox.hide();
Ext.MessageBox.alert('Error',action.result.msg);
Ext.Msg.alert('错误','服务器出现错误请稍后再试!');
}
});
}
</script>
</head>
<body>
</body>
</html>
3.java处理页面AttachmentsAction.java
{
//这里对应的是EXT页面定义的file控件的NAME名称。。这个是struts2提供给我们的属性
//您可以修改成其他的名称,,只要upload ,uploadFileName,uploadContentType 保持一致即可
private List<File> upload = new ArrayList<File> ();
private List<String> uploadFileName = new ArrayList<String> ();
private List<String> uploadContentType = new ArrayList<String> ();
private List<String> description = new ArrayList<String> ();
final static int MAX_SIZE = 15 * 1024 * 1024; // 设置上传文件最大为 15M
final static String dir = "/Attachments/";
。。省略掉set。get方法
/**
* 保存多个Attachments对象。
* 这里介绍的是把文件保存到服务器的文件夹中。。并不是保存在数据库里.
* author by xj
* @return
* @throws Exception
*/
public String saveAttachmentsInfo() throws Exception {
//取的系统当前时间
Calendar cal1 = new GregorianCalendar();
SimpleDateFormat theDate = new SimpleDateFormat("yyyy-MM-dd");
String strDate = theDate.format(cal1.getTime());
String year = "2000";
String month = "12";
if (strDate.length() > 9) {
year = strDate.substring(0,4);
month = strDate.substring(5,7);
}
//得到文件的相对路径
String uploadDir = dir + year + "/" + month + "/";
//获得文件的绝对路径
String realUploadDir = ServletActionContext.getServletContext().getRealPath(uploadDir);
// the directory to upload to用于存放上传文件的目录
File dirPath = new File(realUploadDir);
if (!dirPath.exists()) {
dirPath.mkdirs();
}
String name = "";
String address = "";
String measurements = "";
String descriptionName = "";
String link = "";
String msg = "{success:true, msg:'failure'}";
if (upload.size() > 0){
for(int i=0; i < upload.size();i++){
Boolean isFile = upload.get(i).exists();
if (isFile){
//保存附件数据库信息
//取得原始文件名
name = uploadFileName.get(i);
//取得文件的后缀名
String suffix = "";
if (name != null && (!name.equals(""))){
attachments.setName(name);
if (name != null && (!name.equals(""))) {
suffix = name.substring(name.lastIndexOf("."), name.length());
}
}
//对数据库操作... 这里我们需要的是记录的ID作为保存文件的名字
attachments = new Attachments();
String aId = attachmentsManager.createAttachmentsInfo(attachments);
String fileUrl = realUploadDir + "/" + aId + suffix;
this.copy(upload.get(i), new File(fileUrl));
link = link + "文件名为" + name + " 上传成功!/n";
msg = "{success:true, msg:'success', link:'" + link + "'}";
}else{
link = "上传的文件不存在";
msg = "{success:true, msg:'notFile', link:'" + link + "'}";
}
}
} else {
link = "文件太大";
msg = "{success:true, msg:'SizeLimitExceededException', link:'" + link + "'}";
}
HttpServletResponse response = ServletActionContext.getResponse();
response.reset();
response.setContentType("text/html;charset=UTF-8");
out = response.getWriter();
out.print(msg);
return NONE;
}
private void copy(File src, File dst) throws Exception{
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(src);
out = new FileOutputStream(dst);
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
out.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 从服务器上下载文件
* @return
* @throws Exception
*/
public String downLoadFileInfo() throws Exception{
logger.info("=============AttachmentsAction downLoadFileInfo=============");
HttpServletRequest req = ServletActionContext.getRequest();
this.setSuccess(true);
HttpServletResponse response = ServletActionContext.getResponse();
response.reset();
String id = req.getParameter("id");
if (id != null && (!id.equals(""))) {
Attachments attachments = attachmentsManager.getAttachmentsInfoById(id);
//获得文件的绝对路径的前缀
String path = ServletActionContext.getServletContext().getRealPath(attachments.getAddress());
//取得文件的后缀名
String suffix = "";
if (attachments.getName() != null && (!attachments.getName().equals("")))
suffix = attachments.getName().substring(attachments.getName().lastIndexOf("."), attachments.getName().length());
//获得文件在服务器中的名字
String systemFileName = id + suffix;
//获得文件的在服务器上的绝对路径
String realPath = path + "\\" + systemFileName;
//当文件名是中文时
//String downFileName = new String(attachments.getName().getBytes("ISO8859-1"), "UTF-8");//这里我不需要做这次转换
String downFileName = attachments.getName();
//设置响应头和下载保存的文件名
response.setContentType("application/msdownload;charset=UTF-8");
//这里就是解决中文名称文件下载的关键地方
response.setHeader("Content-Disposition","attachment; filename=\"" + java.net.URLEncoder.encode(downFileName, "UTF-8"));
//打开文件的输出流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(response.getOutputStream());
this.downLoadFileFromSystem(realPath, bufferedOutputStream);
}
return NONE;
}
/**
* 从服务器上下载文件
* @param realPath
* @param bufferedOutputStream
* @throws Exception
*/
private void downLoadFileFromSystem(String realPath, BufferedOutputStream bufferedOutputStream) throws Exception{
try {
//打开指定文件的流信息
FileInputStream fileInputStream = new FileInputStream(realPath);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = fileInputStream.read(buffer, 0, 8192)) != -1) {
bufferedOutputStream.write(buffer,0,bytesRead);
}
fileInputStream.close();
bufferedOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.这里所用到的commons-fileupload-1.1.1.jar。不能使用commons-fileupload-1.0.jar文件。。因为我们需要的是文件拦截器需要用到的是org.apache.commons.fileupload.servlet.servletfileupload. 1.0的jar不支持。。
同时建议两个架包不要同时使用。