网站编写很多时候要实现附件上传和下载。
而我这里说下自己用ajax技术写文件上传和下载的过程和方法。
先不急着说实现的方法,在写之前先确定几件事:
1.文件存哪
2.哪些功能要用到上传和下载。(这点很重要,如我做的指标项管理是要在上传的时候可以添加文件,添加文件的过程是,在文件控件选择文件点击上传,这时候文件应该上传到临时文件夹里,而数据库应该有个表记录上传的文件,具体的字段有,主键文件id,文件路径,文件原名称,文件转化后唯一名称等。而上传成功后返回前台该文件的id,若要显示文件名,也可多传一个文件原名称)。
确定后实现上传,具体流程:
1.页面上定义一个file控件和上传操作按钮,也可以定义一些文本框查看返回数据。
具体代码:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head> <title>文件上传测试</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src='<c:url value="/resource/js/data.js" />'></script>
<script src="${pageContext.request.contextPath}/resource/m/boot.js" type="text/javascript"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/resource/m/miniui/jquery-1.7.2.min.js"/></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/resource/js/ajaxfileupload.js"></script>
<LINK href="<c:url value='/resource/css/custom.css'/>" type="text/css" rel="stylesheet">
</head>
<body>
<div id="tabUnploadForm">
<fieldSet>
<legend style="font-size:18px">上传测试</legend>
<table>
<tr>
<td>
<input type="file" id="uploadfile" name="file" />
</td>
</tr>
<tr>
<td ><input id="upload3" type="button" value="上传测试"onclick="return uploadFile3();"/></td>
</tr>
<tr>
<td>
文件id:
</td>
<td>
<input id ="tmpfileid" class = "mini-textbox " name="tmpfileid"/>
</td>
<td>
文件路径:
</td>
<td>
<input id ="uploaddir" class = "mini-textbox " name="uploaddir"/>
</td>
<td>
文件名:
</td>
<td>
<input id ="filename" class = "mini-textbox " name="filename"/>
<input id ="savename" class= "mini-textbox" name="savename"/>
</td>
<td width="10%"><a href="/hzrsmh/portal/common/download.action?fileType=00&fileid=106"/>下载</td>
</tr>
</table>
</fieldSet>
</div>
<script type="text/javascript">
function uploadFile3(){
$.ajaxFileUpload({
url:'<c:url value="/portal/common/uploadFile.action"/>',
secureuri:false,
fileElementId : 'uploadfile',
dataType : 'json',
success:function(data,status){
alert("上传成功");
var tf = mini.get("tmpfileid");
var ul = mini.get("uploaddir");
var fn = mini.get("filename");
var sn = mini.get("savename");
tf.setValue(data.result[0].tmpfileid);
ul.setValue(data.result[0].uploaddir);
fn.setValue(decodeURI(data.result[0].filename));
sn.setValue(data.result[0].savename);
},
error:function(data,status,e){
alert(e);
alert(data.msg);
}
});
}
</script>
</body>
</html>
注:上传要导入ajaxfileupload.js,界面使用miniui,要导入jquery-1.7.2.min.js
2.在action中获得返回的文件,文件名和编码类型,具体action继承于BaseUploadAction,它的作用是打包一些数据传输的方法,节省代码。
BaseUploadAction(未给出import):
public abstract class BaseUploadFileAction extends ActionSupport implements AjaxProvider, ModelDriven, SessionAware,
ParameterAware, ServletRequestAware, ServletResponseAware{
private Writer writer;
private String defaultEncoding;
public static final String ERRORS = "{success:false,result:[{}],exception:[{msg:'%s'}]}";
protected Map session;
protected Map parameters;
protected HttpServletRequest servletRequest;
protected HttpServletResponse servletResponse;
private String responseData;
private String errorResultLocation;
private boolean ajaxSuccess;
public BaseUploadFileAction() {
this.defaultEncoding = "UTF-8";
}
@Override
public String execute() throws Exception {
String result = null;
try {
result = operate();
}
catch (Exception e) {
writerJson(String.format(ERRORS, getErrorMsg(e)));
e.printStackTrace();
return null;
}
writerJson(result);
return null;
}
public String getErrorMsg(Throwable throwable) {
if (throwable instanceof BusinessException) {
return throwable.getMessage();
}
return getErrorMsg(throwable.getCause());
}
public void writerJson(String json) throws IOException {
if(json ==null ||json.trim().length()==0)
return;
HttpServletResponse response = ServletActionContext.getResponse();
String contentType = "text/html" + ";charset=" + defaultEncoding;
response.setContentType(contentType);
response.getWriter().write(json);
response.getWriter().flush();
}
public Object getModel() {
return getValueObject();
}
public Map getSession() {
return this.session;
}
public void setSession(Map session) {
this.session = session;
}
public Map getParameters() {
return this.parameters;
}
public void setParameters(Map parameters) {
this.parameters = parameters;
}
public HttpServletRequest getServletRequest() {
return this.servletRequest;
}
public HttpServletResponse getServletResponse() {
return this.servletResponse;
}
public void setServletRequest(HttpServletRequest servletRequest) {
this.servletRequest = servletRequest;
}
public void setServletResponse(HttpServletResponse servletResponse) {
this.servletResponse = servletResponse;
}
public String getErrorResultLocation() {
return this.errorResultLocation;
}
public String getResponseData() {
return this.responseData;
}
public boolean hasAjaxErrors() {
String object = (String)ActionContext.getContext().get("com.framework.core.web.ajax.errors.flag");
return Boolean.parseBoolean(object);
}
public boolean isAjaxSuccess() {
return this.ajaxSuccess;
}
public void setAjaxSuccess(boolean ajaxSuccess) {
this.ajaxSuccess = ajaxSuccess;
}
public void setErrorResultLocation(String errorResultLocation) {
this.errorResultLocation = errorResultLocation;
}
public void setResponseData(String arg0) {
this.responseData = responseData;
}
protected abstract String operate();
protected abstract ValueObject getValueObject();
}
ajaxFIleUpload(import没给出):
public class AjaxFileUploadAction extends BaseUploadFileAction{
private File file;
private String fileFileName;
private String fileContentType;
WpsTmpFileService wpsTmpFileService ;
public void setWpsTmpFileService(WpsTmpFileService wpsTmpFileService){
this.wpsTmpFileService = wpsTmpFileService;
}
@Override
protected ValueObject getValueObject() {
// TODO Auto-generated method stub
return null;
}
@Override
protected String operate() {
// TODO Auto-generated method stub
String json = null;
String username = UserContextUtils.getOperatorName();
Long userid = UserContextUtils.getOperatorId();
String path = servletRequest.getRealPath("")+"/upload/temp/";
try{
WpsTmpFileVO tmpFileVO = new WpsTmpFileVO();
WpsTmpFileDTO tmpFileDTO= wpsTmpFileService.uploadFileToTmp(file, path, fileFileName, username, userid);
tmpFileVO.setFileName(tmpFileDTO.getFilename());
tmpFileVO.setTmpFileId(tmpFileDTO.getTmpfileid());
tmpFileVO.setUploadDir(tmpFileDTO.getUploaddir());
tmpFileVO.setSavename(tmpFileDTO.getSavename());
//生成json操作
json = String.format("{success:true,result:[{tmpfileid:'%s',uploaddir:'%s',filename:'%s',savename:'%s'}]}",tmpFileVO.getTmpFileId(),tmpFileVO.getUploadDir(),tmpFileVO.getFileName(),tmpFileVO.getSavename());
this.servletResponse.setContentType("text/plain;charset=utf-8");
this.servletResponse.getWriter().write(json);
this.servletResponse.getWriter().flush();
}catch(IOException e){
e.printStackTrace();
}
return null;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public String getFileFileName() {
return fileFileName;
}
public void setFileFileName(String fileFileName) {
this.fileFileName = fileFileName;
}
public String getFileContentType() {
return fileContentType;
}
public void setFileContentType(String fileContentType) {
this.fileContentType = fileContentType;
}
}
3.在service层中先进行文件上传操作,再将文件信息保存到表中并返回sequence生成的文件id。
public class WpsTmpFileServiceImpl implements WpsTmpFileService{
private static final String DEFAULT_VALUE="00";
WpsTmpFileDao wpsTmpFileDao ;
public void setWpsTmpFileDao(WpsTmpFileDao wpsTmpFileDao){
this.wpsTmpFileDao = wpsTmpFileDao;
}
//上传文件操作,上传到upload/temp/
public WpsTmpFileDTO uploadFileToTmp(File file ,String path,String filename,String username,Long userid){
String fileName = getRandomName(filename);
String filepath = path+fileName;
String url = filepath;
url = url.replaceAll("\\\\", "/");
File saveFile = new File(new File(path),"新文件名.jpg");
if(!saveFile.getParentFile().exists()){
saveFile.getParentFile().mkdirs();
}
try
{
InputStream in = new FileInputStream(file);//把文件读入
OutputStream out = new FileOutputStream(url);//建立一个上传文件的输出流
int bytesRead;
byte[] buffer = new byte[1024];
while ((bytesRead = in.read(buffer, 0, 1024)) != -1) {
out.write(buffer, 0, bytesRead);//将文件写入服务器
}
out.close();
in.close();
}
catch (Exception e)
{
e.printStackTrace();
}
filepath="/upload/temp/";
return SaveToTable(filepath,fileName,username,userid,filename);
}
//将文件数据保存到临时文件表
public WpsTmpFileDTO SaveToTable(String filepath , String filename ,String username,Long userid,String savename){
WpsTmpFileDTO tmpFileDTO = new WpsTmpFileDTO();
Date now = new Date();
tmpFileDTO.setFilename(filename);
tmpFileDTO.setType(DEFAULT_VALUE);
tmpFileDTO.setUploaddir(filepath);
tmpFileDTO.setUsername(username);
tmpFileDTO.setUserid(userid);
tmpFileDTO.setUploadtime(now);
tmpFileDTO.setSavename(savename);
WpsTmpFile tmpFile = ModelUtils.copyAs(tmpFileDTO, WpsTmpFile.class);
return wpsTmpFileDao.SaveAndGet(tmpFile);
}
//获取文件类型
public static String getPostfix(String path){
if(path ==null || "".equals(path.trim())){
return "";
}
if(path.contains(".")){
return path.substring(path.lastIndexOf(".")+1,path.length());
}
return "";
}
//生成文件随机名
public static String getRandomName(String filename){
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyyMMddHHmmss");
String dateStr=dateFormat.format(new Date());
Random r = new Random();
Integer integer = new Integer(r.nextInt(10000));
String s =String.valueOf(integer);
filename = dateStr+s+"."+getPostfix(filename);
return filename;
}
public WpsTmpFileDTO getFileById(String fileid){
Long lfileid = Long.parseLong(fileid);
return ModelUtils.copyAs(wpsTmpFileDao.load(lfileid), WpsTmpFileDTO.class);
}
@Override
public WpsTmpFile getTmpFileById(long tmpfileid) {
return wpsTmpFileDao.getTmpFileById(tmpfileid);
}
}
至此一套文件上传过程基本实现。