您的位置:首页 > 其它

文件上传下载——通过ahxu扩展后的组件DiskFileUploadEx上传单个excel

2011-06-23 10:42 471 查看
通过ahxu扩展后的组件DiskFileUploadEx,DiskFileUploadEx是对DiskFileUpload的扩展,增加了一些新功能:进度条的显示、上传文件的格式的限制等等。

思路:

1、通过DiskFileUploadEx的parseRequestEx方法对HTTP请求消息进行解析,解析出FORM表单中的每个字段的数据,并将它们分别包装成独立的FileItem对象,然后将这些FileItem对象加入进一个List类型的集合对象中返回。

2、针对每一个FileItem对象,将他们从客户端本地,以流的形式,保存到服务器端指定的目录

3、文件上传成功后,将字节流转换成字符流,转换成BufferedReader ,利用它的readline()方法,获取每一行数据。

InputStream is = new FileInputStream(filePath);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));

4、针对每一行数据进行校验,如果校验失败,将错误信息存到errorlist中,等所有的数据都校验后,一起返回

5、每50条数据,提交到数据库

6、如果有错误数据,则返回错误信息;如果没有错误数据,从数据库中查询处正确的数据返回给用户

<%
String filePath = "";//文件路径
boolean upTure=false;
List fileItemList=null;
//DiskFileUpload fu = new DiskFileUpload();//初使化使用原有apache的upload
DiskFileUploadEx fu = new DiskFileUploadEx();//初使化ahxu扩展后的组件
fu.setSizeMax(1024*1024*1000);//原有apache的upload:设置允许上传的最大值

fu.setAllowFiles(".xls;.XLS;.DEL;.del;.csv;.CSV;.zip;.ZIP");//ahxu扩展后:设置允许的上传文件类型

try{
//fileItemList=fu.parseRequest(request);//使用原有apache的upload:由request接收上传文件
fileItemList=fu.parseRequestEx(request);//ahxu扩展后的:接收上传文件
Iterator fileItemListIte=fileItemList.iterator();
while(fileItemListIte.hasNext()){
FileItem file=(FileItem)fileItemListIte.next();
String fileName = file.getName();
filePath = FileExposeUtil.getRootPath()+"jsp/rptbak/uploadtemp/"+fileName.substring(fileName.lastIndexOf("//",fileName.length()));
filePath = filePath.replace('/', '//');
FileExposeUtil.saveFile(file.getInputStream(), filePath);//将客户端本地的文件以流的形式上传到服务器指定路径
}
upTure=true;
}catch (Exception e){
e.printStackTrace();
out.println("上传失败<br>");
out.println(e.getMessage());
/*显示不被允许上传的文件列表,原有apache的upload无此部分 begin*/
if(e instanceof DiskFileUploadEx.InvalidFileUploadException){
out.println("<p>以下文件不被允许:</p>");
Iterator unAllowFileS=((DiskFileUploadEx.InvalidFileUploadException)e).getInvalidFileList().iterator();
while(unAllowFileS.hasNext()){
out.println((String)unAllowFileS.next()+"<br>");
}
/*显示不被允许上传的文件列表,原有apache的upload无此部分 end */
}
}
finally{
Thread.sleep(1000);
fu.dispose();//ahxu扩展后的组件:接收上传文件后的清理工作,原有apache组件没有此过程
}
%>


/**
* 7*. 把流保存到本地文件(路径包含文件名)
*
* @param is
* @param filePath
* @param fileName
* @throws IOException
*/
public static void saveFile(InputStream is, String filePath) throws IOException {
File file = new File(filePath.substring(0, filePath.lastIndexOf("//")));
if (!file.exists()) {
file.mkdirs();
}
OutputStream os = null;
PrintWriter writer = null;
BufferedReader reader = null;
try {
os = new FileOutputStream(filePath);
String line;
reader = new BufferedReader(new InputStreamReader(is));
writer = new PrintWriter(new OutputStreamWriter(os));
line = reader.readLine();
while (line != null) {
writer.println(line);
line = reader.readLine();
}
writer.flush();
} catch (Exception e) {
e.printStackTrace();
throw new ServiceException("文件上传出错!");
} finally {
try {
if (os != null) {
os.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (writer != null) {
writer.close();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (reader != null) {
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}


import ahxu.commons.upload.DefaultReportItem;
import ahxu.commons.upload.ReportItem;
public Long[] importSellersJdbc(String rptBakNo, String infoMo, String filePath, HttpSession ses,boolean keepOldData) throws Exception {
if (!FileExposeUtil.checkFileExist(filePath)) {
throw new ServiceException("文件上传错误,请重试!");
}
String dataId = DateUtil.parse(new java.util.Date(), "yyyyMMddHHmmss") + RandomUtils.nextLong();
ses.setAttribute("com.ahxu.commons.upload.DefaultReportItemManage.", dataId);
String fileName = filePath.substring(filePath.lastIndexOf("//") + 1, filePath.length());
long totalSize = (FileExposeUtil.getFileSize(filePath) / 1024) * 10;
Calendar calendar = Calendar.getInstance();
long oldTime = calendar.getTimeInMillis();
ReportItem item = new DefaultReportItem(fileName, calendar.getTimeInMillis(), totalSize, 0, calendar.getTimeInMillis());
ses.setAttribute(dataId, item);
String otherEerror = null;

String line; // 用来保存每行读取的内容

long succes = 0;// 导入成功数

InputStream is = new FileInputStream(filePath);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));//InputStreamReader从byte到char的适配器模式

//BufferedReader 提供了缓冲的功能,因此可以按行读取readLine是BufferedReader 中的方法
//Reader是没有的,因此BufferedReader 是半透明的装饰模式
//BufferedInputStream 虽然有缓冲的功能,但没有readLine方法
line = reader.readLine(); // 读取第一行

Long errorNum = null;

/**
* 临时添加变量
*/

Connection conn = null;
PreparedStatement pstm = null;
PreparedStatement pstm1 = null;
String tableName = "DS_SELLER";

List checkError = new ArrayList();
long currentTime = 0;
try {
conn = getConnection();
conn.setAutoCommit(false);// 保证事务

// 开始导入
logger.info("start import selller >>>>>>> " + rptBakNo
+ DateUtil.parse(new java.util.Date(), FinalConfig.DB2_DATETIME_FORMAT));

System.out.println("*********************************************************************************");
currentTime = System.currentTimeMillis();
System.out.println("*************导入开始时间:" + DateUtil.getCurrentDateAndTime());
System.out.println("*************正在导入..................");

int i = 0;
int errorCode = 0;
String sql = "insert into " + tableName + " values(nextVal for seq,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
pstm = conn.prepareStatement(sql);

while (line != null) { // 如果 line 为空说明读完了
// 封装记录
if (conn != null) {
i++;
String errorsSign = null;
line = line.replaceAll(",", ",");

//将每行数据存放到array 中,针对每个字段进行校验
String[] array = line.split(",");
.....

//每50行提交一次数据
if (i % 50 == 0) {
int[] tp = new int[0];
try {
tp = pstm.executeBatch();
conn.commit();
pstm.clearBatch();
succes += tp.length;
ReportItem item2 = new DefaultReportItem(fileName, oldTime, totalSize, i, calendar
.getTimeInMillis());
ses.setAttribute(dataId, item2);
oldTime = calendar.getTimeInMillis();
} catch (Exception e) {
System.out.println("*************导入数据期间发生错误,可能的原因为:" + e.getMessage());
e.printStackTrace();
otherEerror = "导入过程中有错误,可能仅成功导入一部分数据。系统原因:" + e.getMessage();
}
}
}
line = reader.readLine(); // 读取下一行

if (tempNum != 0 && tempNum % 1000 == 0) {
errorNum = addErrors(checkError, otherEerror, errorNum);
checkError.clear();
}
}
try {
int[] tp = pstm.executeBatch();
pstm1.execute();
conn.commit();
pstm.clearBatch();
succes += tp.length;
} catch (Exception e) {
System.out.println("*************导入数据期间发生错误,可能的原因为:" + e.getMessage());
conn.rollback();
otherEerror = "导入过程中有错误,可能仅成功导入一部分数据。系统原因:" + e.getMessage();
}

} catch (Exception e) {
System.out.println("*************导入数据期间发生错误,可能的原因为:" + e.getMessage());
conn.rollback();
e.printStackTrace();
if (e.toString().indexOf("请与管理员联系生成对应的报备单即可") != -1) {
throw e;
} else if (e instanceof ServiceException) {
throw e;
} else {
throw new ServiceException("系统错误,请于管理员联系。系统原因:" + e.getMessage());
}
} finally {
try {
is.close();
} catch (Exception e1) {
e1.printStackTrace();
}
try {
reader.close();
} catch (Exception e2) {
e2.printStackTrace();
}
try {
pstm.clearBatch();
pstm.close();
pstm1.close();
} catch (Exception e4) {
e4.printStackTrace();
}
try {
conn.close();
} catch (Exception e3) {
e3.printStackTrace();
}
}
logger.info("end import seller >>>>>>>  " + rptBakNo
+ DateUtil.parse(new java.util.Date(), FinalConfig.DB2_DATETIME_FORMAT));

if (otherEerror != null || checkError.size() > 0) {
errorNum = addErrors(checkError, otherEerror, errorNum);
}
Long[] ret = new Long[2];
ret[0] = errorNum;
ret[1] = new Long(succes);

System.out.println("*************导入结束时间:" + DateUtil.getCurrentDateAndTime());
System.out.println("*************导入耗时:" + (System.currentTimeMillis() - currentTime) / 1000 + " 秒");
System.out.println("*************                                                         ***********");
System.out.println("*********************************************************************************");
return ret;
}


DiskFileUpload常用方法:

1.setSizeMax方法
setSizeMax方法用于设置请求消息实体内容的最大允许大小,以防止客户端故意通过上传特大的文件来塞满服务器端的存储空间,单位为字节。

2. parseRequest方法
parseRequest 方法是DiskFileUpload类的重要方法,它是对HTTP请求消息进行解析的入口方法,如果请求消息中的实体内容的类型不是“multipart/form-data”,该方法将抛出FileUploadException异常。parseRequest 方法解析出FORM表单中的每个字段的数据,并将它们分别包装成独立的FileItem对象,然后将这些FileItem对象加入进一个List类型的集合对象中返回。parseRequest 方法的完整语法定义如下:
public List parseRequest(HttpServletRequest req)
parseRequest 方法还有一个重载方法,该方法集中处理上述所有方法的功能,其完整语法定义如下:
parseRequest(HttpServletRequest req,int sizeThreshold,long sizeMax,String path)
这两个parseRequest方法都会抛出FileUploadException异常

3 FileItem类
FileItem类用来封装单个表单字段元素的数据,一个表单字段元素对应一个FileItem对象,通过调用FileItem对象的方法可以获得相关表单字段元素的数据。FileItem是一个接口,在应用程序中使用的实际上是该接口一个实现类,该实现类的名称并不重要,程序可以采用FileItem接口类型来对它进行引用和访问,为了便于讲解,这里将FileItem实现类称之为FileItem类。FileItem类还实现了Serializable接口,以支持序列化操作。
对于“multipart/form-data”类型的FORM表单,浏览器上传的实体内容中的每个表单字段元素的数据之间用字段分隔界线进行分割,两个分隔界线间的内容称为一个分区,每个分区中的内容可以被看作两部分,一部分是对表单字段元素进行描述的描述头,另外一部是表单字段元素的主体内容

FileItem类中的几个常用的方法:
1). isFormField方法
isFormField方法用于判断FileItem类对象封装的数据是否属于一个普通表单字段,还是属于一个文件表单字段,如果是普通表单字段则返回true,否则返回false。
该方法的完整语法定义如下:
public boolean isFormField()

2). getName方法
getName方法用于获得文件上传字段中的文件名,对于图1.3中的第三个分区所示的描述头,getName方法返回的结果为字符串“C:/bg.gif”。
如果FileItem类对象对应的是普通表单字段,getName方法将返回null。即使用户没有通过网页表单中的文件字段传递任何文件,但只要设置了文件表单字段的name属性,浏览器也会将文件字段的信息传递给服务器,只是文件名和文件内容部分都为空,但这个表单字段仍然对应一个FileItem对象,此时,getName方法返回结果为空字符串"",读者在调用Apache文件上传组件时要注意考虑这个情况。
getName方法的完整语法定义如下:
public String getName()
注意:如果用户使用Windows系统上传文件,浏览器将传递该文件的完整路径,如果用户使用Linux或者Unix系统上传文件,浏览器将只传递该文件的名称部分。

3).getFieldName方法
getFieldName方法用于返回表单字段元素的name属性值,也就是返回图1.3中的各个描述头部分中的name属性值,例如“name=p1”中的“p1”。
getFieldName方法的完整语法定义如下:
public String getFieldName()

4). write方法
write方法用于将FileItem对象中保存的主体内容保存到某个指定的文件中。如果FileItem对象中的主体内容是保存在某个临时文件中,该方法顺利完成后,临时文件有可能会被清除。该方法也可将普通表单字段内容写入到一个文件中,但它主要用途是将上传的文件内容保存在本地文件系统中。其完整语法定义如下:
public void write(File file)

5).getString方法
getString方法用于将FileItem对象中保存的主体内容作为一个字符串返回,它有两个重载的定义形式:
public java.lang.String getString()
public java.lang.String getString(java.lang.String encoding)
throws java.io.UnsupportedEncodingException
前者使用缺省的字符集编码将主体内容转换成字符串,后者使用参数指定的字符集编码将主体内容转换成字符串。如果在读取普通表单字段元素的内容时出现了中文乱码现象,请调用第二个getString方法,并为之传递正确的字符集编码名称。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: