哎,首先发泄一下情绪。。。这个fileupload搞了我一天时间,为何???问题出在我查看ext-3.1.1\examples\form\file-upload.html的时候发现它的例子有BUG。。。去ext的官方论坛看了下这问题不小,好多人遇到。。。
是个什么BUG呢?
我完全按照file-upload.html的例子做完发现当我设置fileUpload: true后上传文件后居然返回json解析出错...然后进行debug...发现由于ext的FileUploadField是伪ajax上传的做法,也就是生成了个frame,造成返回json后解析出其他一些内容,更奇怪的是各个浏览器解析的内容并不相同- -,泪流满面。。。
查看了下国外论坛,这方面的BUG报的不少,解决基本没有介绍。。。或者试了失败。。。
算了自己调试吧,经过调试,使用response.setContentType("text/html;charset=utf-8");后会莫名多出很多html代码在json中,换成response.setContentType("text/plain;charset=utf-8");以后火狐多了<pre>json对象</pre>,IE7多了<PRE>json对象</PRE>,Opera多了<PRE>json对象,很奇怪Opera并没有</PRE>标签。。。其他浏览器没有查,估计也就差不多是pre这个标签。。。
算了 看来只有修改下源码把pre标签去掉才能正确解析json了。。。
来看代码吧:(自己导入json相关包以及ext相关js和css)
先上jsp:
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ include file="/common/taglib.jsp"%>
<html>
<head>
<script type="text/javascript">
var contextPath = '${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}';
</script>
//新加入uploadfile必须的2个文件----fileuploadfield.css和FileUploadField.js都在ext-3.1.1\examples\ux\fileuploadfield目录下
<link rel="stylesheet" type=text/css href="${ctxPath }/styles/fileuploadfield.css" />
<script type="text/javascript" src="${ctxPath }/scripts/fileupload/FileUploadField.js"></script>
<script type="text/javascript">
Ext.onReady(function(){
Ext.QuickTips.init();
var fp = new Ext.FormPanel({
renderTo: 'fi-form',
fileUpload: true,//要上传必须的属性
width: 500,
frame: true,
title: 'File Upload Form',
autoHeight: true,
bodyStyle: 'padding: 10px 10px 0 10px;',
labelWidth: 50,
defaults: {
anchor: '95%',
allowBlank: false,
msgTarget: 'side'
},
items: [{
xtype: 'hidden',
name: 'path',
value: "file\\"
},{
xtype: 'fileuploadfield',
id: 'form-file',
emptyText: 'Select an image',
fieldLabel: 'Photo',
name: 'myUpload',//与struts1的form的FormFile属性相对应
buttonText: '浏览'
//buttonCfg: {
//iconCls: 'upload-icon'
//}
}],
buttons: [{
text: 'Save',
handler: function(){
if(fp.getForm().isValid()){
fp.getForm().submit({
url: contextPath + '/search.do?method=uploadFile',
waitMsg: 'Uploading your photo...',
success: function(fp, o){
alert(o.result.message);
}
});
}
}
},{
text: 'Reset',
handler: function(){
fp.getForm().reset();
}
}]
});
});
</script>
</head>
<body>
<div id="fi-form"></div>
</body>
</html>
后台searchAction的方法:
public static final String ROOT = "upload\\";
public ActionForward uploadFile(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
SearchForm searchForm = (SearchForm)form;
String myUploadFileName = searchForm.getMyUpload().getFileName();
System.out.println(myUploadFileName);
String path = request.getParameter("path");
System.out.println(path);
String rootPath = getServlet().getServletContext().getRealPath("/");
rootPath += ROOT;
String sp = rootPath + path;
System.out.println(sp);
MyUtils.mkDirectory(sp);
try {
//此处借用了lhq的Util类
MyUtils.upload(myUploadFileName, sp, searchForm.getMyUpload());
} catch (RuntimeException e) {
e.printStackTrace();
}
MessageVO vo = new MessageVO();
vo.setMessage("aaa");
//务必要加上success属性以便ext识别
vo.setSuccess(true);
JSONObject object = JSONObject.fromObject(vo);//注意使用text/plain而不要使用text/html或者text/xml
response.setContentType("text/plain;charset=utf-8");
response.getWriter().write(object.toString());
return null;
}
MessageVO.java:
package com.xuyi.vo;
public class MessageVO {
boolean success;
String message;
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
SearchForm.java:
package com.xuyi.web.form;
import org.apache.struts.upload.FormFile;
public class SearchForm extends BaseForm {
/**
*
*/
private static final long serialVersionUID = -2466145267901361949L;
FormFile myUpload;
public FormFile getMyUpload() {
return myUpload;
}
public void setMyUpload(FormFile myUpload) {
this.myUpload = myUpload;
}
}
MyUtils.java:
package com.xuyi.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.struts.upload.FormFile;
public class MyUtils {
/**
* 上传文件
*
* @param savePath
* 文件的保存路径
* @param uploadFile
* 被上传的文件
* @return newFileName
*/
public static String upload(String uploadFileName, String savePath, FormFile uploadFile) {
String newFileName = getUUIDName(uploadFileName, savePath);
FileOutputStream fos = null;
InputStream fis = null;
try {
fos = new FileOutputStream(savePath + newFileName);
fis = uploadFile.getInputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fos.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return newFileName;
}
public static String getUUIDName(String fileName, String dir) {
String[] split = fileName.split("\\.");
String extendFile = "." + split[split.length - 1].toLowerCase();
return java.util.UUID.randomUUID().toString() + extendFile;
}
/**
* 根据路径创建一系列的目录
*
* @param path
*/
public static boolean mkDirectory(String path) {
File file = null;
try {
file = new File(path);
if (!file.exists()) {
return file.mkdirs();
}
} catch (RuntimeException e) {
e.printStackTrace();
} finally {
file = null;
}
return false;
}
}
最后附上解决方案:
首先后台的response注意使用text/plain而不要使用text/html或者text/xml
response.setContentType("text/plain;charset=utf-8");
然后修改ext-all.js中以下代码:
doDecode = function(json){ //加入部分begin if(json.indexOf('<pre>') != -1 || json.indexOf('<PRE>') != -1 ){ json = json.replace('<pre>','').replace('<PRE>','').replace('</pre>','').replace('</PRE>',''); } //加入部分end return eval("(" + json + ')'); }
纯粹个人意见,刚接触ext有不足之处请大家多多指点,还有哪位有更好的解决方法也请说下,请教了!