搞文件上传,郁闷了一天...
网上搜了一堆.都是一个样子,还写的挺复杂的.但是不清晰.搞的人晕呼呼的.
自己弄了一个最简单的.呵呵,都是Struts的功劳.
最简单,就一个上传.
代码需要注意的地方有这么几个:
一. jsp 页面
<%@ page contentType="text/html;charset=UTF-8"%><%@ include file="/commons/taglibs.jsp"%><%@ include file="/widgets/calendar/calendar.jsp"%><head> <title> <bean:message key="batchForm.label.title" bundle="uniminiboss" /> </title> <script src="${ctx}/widgets/scriptaculous/scriptaculous.js" type="text/javascript"></script> <script type="text/javascript" language="JavaScript"> function submitForm(str){ document.forms[0].action.value=str; document.forms[0].submit(); }</script></head><html:form action="/batch.do" enctype="multipart/form-data" method="POST" focus="batchFile"> <div id="top_title"> <bean:message key="batchForm.label.title" bundle="uniminiboss" /> </div> <html:hidden property="action" /> <table width="100%" border="0" cellpadding="0" cellspacing="1" bgcolor="#d4d4d4"> <tr> <td bgcolor="#e8e7f2" align="left"> <table width="75%" height="27" border="0" cellpadding="0" cellspacing="0"> <tr> <td width="15%" align="right" valign="middle"> <bean:message key="batchForm.label.batchType" bundle="uniminiboss" /> : </td> <td align="left"> <util:enumSingleSelect property="batchType" enumType="Batch" allowEmpty="true" i18n="true" bundle="/i18n/uniminiboss" /> </td> <td width="15%" align="right" valign="middle"> <bean:message key="batchForm.label.batchPath" bundle="uniminiboss" /> : </td> <td align="left"> <html:file property="batchFile"></html:file> </td> <td width="10%" align="right"> <button id="oButton" class="button_en" onclick="submitForm('list');"> <bean:message key="commonForm.button.operator" /> </button> </td> </tr> </table> </td> </tr> </table></html:form>
需要注意的有三点:
(1) enctype="multipart/form-data" ; 设置表单提交的数据格式为二进制,文件上传必须要这个;
(2) method="post" ; 提交方式必须得用post;
(3) property="batchFile"; 属性对应到ActionForm里面的类型为FormFile;(这个要注意啊!)
二. ActionForm
package com.alcatel.oms.uniminiboss.web;import org.apache.struts.upload.FormFile;import com.alcatel.oms.core.web.BaseForm;/** * 批处理Form * * @author Administrator * */public class BatchForm extends BaseForm { private static final long serialVersionUID = 1L; private Long id; private int batchType; private FormFile batchFile; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public int getBatchType() { return batchType; } public void setBatchType(int batchType) { this.batchType = batchType; } public FormFile getBatchFile() { return batchFile; } public void setBatchFile(FormFile batchFile) { this.batchFile = batchFile; }}
需要注意的地方有一点: 定义 FormFile 类型的属性,对应到jsp页面的文件上传控件的属性.
三. Action
package com.alcatel.oms.uniminiboss.web;import java.io.File;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionMapping;import org.apache.struts.upload.FormFile;import com.alcatel.oms.core.web.StrutsEntityAction;import com.alcatel.oms.uniminiboss.entity.Batch;import com.alcatel.oms.uniminiboss.manager.BatchManager;import com.alcatel.oms.uniminiboss.util.StrutsUpload;/** * 批处理Action * * @author Administrator * */public class BatchAction extends StrutsEntityAction<Batch, BatchManager> { // 记录日志 private static final Log logger = LogFactory.getLog(BatchAction.class); private BatchManager batchManager; public void setBatchManager(BatchManager batchManager) { this.batchManager = batchManager; } public ActionForward list(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { BatchForm batchForm = (BatchForm) form; try { int batchType = batchForm.getBatchType(); FormFile batchFile = batchForm.getBatchFile(); PrintWriter writer = response.getWriter(); String msg = ""; StringBuffer msgPage = new StringBuffer( "<div id='content' align='center'><div class='redTitle' id='message' style='position:relative; top:10px;'>"); if (batchType != 0 && batchFile != null && !"".equals(batchFile.getFileName())) { logger.info("file name Client: "+batchFile.getFileName()); String serverPath = this.getServlet().getServletContext().getRealPath("/upload"); String filepath = serverPath + "/" + batchFile.getFileName(); File filedir = new File(serverPath); if (!filedir.isDirectory()) { filedir.mkdirs(); } StrutsUpload upload = new StrutsUpload(); boolean loadok = upload.upload(batchFile, filepath); if (loadok) { boolean batch = batchManager.batchDispose(batchType, filepath); msg = batchManager.getMessage(); if (batch) { logger.info("Batch Succeed!"); } else { logger.info("Batch Failure!"); } } } else if (batchType == 0 && batchFile != null) { msg = "请选择处理类型。"; } else if (batchType != 0 && batchFile != null && "".equals(batchFile.getFileName())) { msg = "请选择处理文件。"; } msgPage.append(msg + "</div></div>"); writer.print(msgPage.toString()); } catch (IOException e) { e.printStackTrace(); } return mapping.findForward(LIST); }}
只要注意把从ActionForm里面拿到的FormFile,和自己定义的上传路径传递给上传方法就可以了.
四. 文件上传类StrutsUpload
package com.alcatel.oms.uniminiboss.util;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import org.apache.struts.upload.FormFile;/** * Struts文件上传 * * @author Administrator * */public class StrutsUpload { /** * 文件上传 * * @param formfile * 表单文件 * @param filepath * 上传路径 * @return 是否成功 */ public boolean upload(FormFile formfile, String filepath) { boolean loadok = false; try { if (formfile == null) { return false; } FileOutputStream output = new FileOutputStream(filepath); output.write(formfile.getFileData()); output.flush(); output.close(); loadok = true; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return loadok; }}
注意的地方到没什么了,非常简单的上传.因为得到的就是二进制数据.不用手动的转换获取了.
要说的是,这只是最简单的文件上传,还可以设置最大上传大小,内存缓冲区大小,编码格式等等... 这些需要的时候在设置吧.其他的分割字节流之类的,要是有需要也可以写一写.不过,就这样子已经可以满足正常的文件上传了.
还有一个问题,不太清楚.看谁可以帮我解决不!?
本来是为了要选择一个批处理的Excel文件,然后取得里面的数据再进行操作.
现在的问题就是,通过网络获取文件里面的数据,不依靠中间服务器?
开始是想了这样一个办法: 在整个互联网中,把源文件复制到目的地!
设想实现这么一个接口就行了.
/** * 复制网络文件 * * @param oldFile * String 原文件路径 * @param newFile * String 复制到目标路径 * @return boolean 文件是否复制成功 */ public static boolean copyWebFile(String oldFile, String newFile);
试着写了一下,问题多多...不会写了...
package com.huameng.file;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.net.URL;public class CopyFile { /** * 复制网络文件 * * @param oldFile * String 原文件路径 * @param newFile * String 复制到目标路径 * @return boolean 文件是否复制成功 */ public boolean copyWebFile(String oldFile, String newFile) { boolean bl = false; try { int bytesum = 0; int byteread = 0; URL oldfile = new URL(oldFile); System.out.println(oldfile.getFile()); (new File(newFile.substring(0, newFile.lastIndexOf("/")))).mkdirs(); // 如果文件夹不存在则建立新文件夹 InputStream input = oldfile.openStream(); // 读入原文件 OutputStream output = new FileOutputStream(newFile); // 输出文件 byte[] buffer = new byte[14440]; while ((byteread = input.read(buffer)) != -1) { bytesum += byteread; // 字节数,文件大小 output.write(buffer, 0, byteread); } input.close(); output.close(); bl = true; } catch (Exception e) { System.out.println("复制网络文件操作出错..."); e.printStackTrace(); } if (bl) { System.out.println("(copyFile)\t[ " + oldFile + " ] -> [ " + newFile + " ] ... 网络文件复制成功!"); } return bl; }}
呵呵, 要是实现了! 我就可以从他的机子里 Copy 一个病毒放到你的机子里面啦... :oops:
想过用Socket,不知道行不行.可以试试...
哎,真不知道有什么好办法没有!
相关资源:谷歌安装器(如果Go安装器无法打卡可以使用这个)