package com.bjinfotech.practice.ajax;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
/**
* 上传文件命令服务
*/
public class FileUploadCommandService extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
private static final long serialVersionUID = -3946579508549209629L;
//Join命令字
public static final String PROTOCOL_COMMAND_JOIN_KEY="join";
//轮询命令字--返回ActiveFUS
public static final String PROTOCOL_COMMAND_POLL_KEY="uploadStatus";
//列表命令字--返回FUS列表
public static final String PROTOCOL_COMMAND_LISTFILE_KEY="listFile";
//取消上传命令字
public static final String PROTOCOL_COMMAND_CANCELUPLOAD_KEY="cancelUpload";
//下载文件命令字
public static final String PROTOCOL_COMMAND_DOWNFILE_KEY="downFile";
//文件id
public static final String PROTOCOL_COMMAND_FILEID_KEY="fileId";
//删除文件命令字
public static final String PROTOCOL_COMMAND_DELFILE_KEY="deleteFile";
Logger logger=Logger.getLogger(FileUploadCommandService.class);
public FileUploadCommandService() {
super();
}
public void init(){
UploadSessionManager.getInstance().start();
}
public void destroy(){
UploadSessionManager.getInstance().stop();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
/**
* 设置Ajax回应的header
* @param response
*/
private void setAjaxResponseHeader(HttpServletResponse response){
response.setContentType("text/xml");
response.setCharacterEncoding("UTF-8");
response.setHeader("Cache-Control", "no-cache");
}
/**
* 设置Ajax回应的header
* @param response
*/
private void setHTMLResponseHeader(HttpServletResponse response){
response.setContentType("text/html");
response.setCharacterEncoding("GBK");
response.setHeader("Cache-Control", "no-cache");
}
/**
* 设置文件下载的header
* @param response
* @param fileName
* @throws UnsupportedEncodingException
*/
private void setFileDownloadResponseHeader(HttpServletResponse response,String fileName) throws UnsupportedEncodingException{
response.setHeader("Cache-Control", "no-cache");
response.setContentType("application/octet-stream; CHARSET=utf8");
response.setHeader("Content-Disposition","attachment; filename="+
java.net.URLEncoder.encode(fileName,"UTF-8"));
}
/**
* 发送序列化的Bean
* @param response
* @param beanObj
* @throws IOException
*/
private void sendSerializedBean(HttpServletResponse response,Object beanObj) throws IOException{
setAjaxResponseHeader(response);
response.getWriter().write(XmlUnSerializer.serializeBean(beanObj));
}
/**
* 发送序列化的BeanList
* @param response
* @param beanObj
* @throws IOException
*/
private void sendSerializedBeanList(HttpServletResponse response,Object beanObj) throws IOException{
setAjaxResponseHeader(response);
response.getWriter().write(XmlUnSerializer.serializeBeanList(beanObj));
}
/**
* 回应join请求,将生成的或者重用的uploadSession id、forwardURL保存到session中,并将其作为response内容发送
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
private void responseJoinRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
logger.debug("发送Join回应");
String uSessionId=Utils.getSessionIdFromHttpRequest(request);
UploadSessionImpl uSession=null;
//新建session
if (uSessionId==null
|| uSessionId.length()==0
|| UploadSessionManager.getInstance().hasSession(uSessionId)==false){
uSession=new UploadSessionImpl(UploadSessionManager.getInstance().createSessionId());
UploadSessionManager.getInstance().addOrUpdateUploadSession(uSession);
}
//重用session
else{
uSession=UploadSessionManager.getInstance().getUploadSession(Utils.getSessionIdFromHttpRequest(request));
uSession.setActiveFUSBean(FileUploadStatusBeanManager.initFUSBean());
UploadSessionManager.getInstance().addOrUpdateUploadSession(uSession);
}
InteractionMessage im=new InteractionMessage();
im.setMsg(uSession.getId());
request.getSession().setAttribute(Constant.SESSION_KEY,uSession.getId());
logger.debug("将会话Id["+uSession.getId()+"]保存在session["+request.getSession().getId()+"]中");
sendSerializedBean(response,im);
}
/**
* 回应上传状态查询
* @param request
* @param response
* @throws IOException
*/
private void responseFileUploadStatusPoll(HttpServletRequest request,HttpServletResponse response) throws IOException{
logger.debug("发送上传状态回应");
sendSerializedBean(
response,
UploadSessionManager.getInstance().getActiveFUSBean(Utils.getSessionIdFromHttpRequest(request))
);
}
/**
* 处理取消文件上传,注意这并不能终止form的提交过程
* @param request
* @param response
* @throws IOException
*/
private void processCancelFileUpload(HttpServletRequest request,HttpServletResponse response) throws IOException{
UploadSessionImpl uSession=UploadSessionManager.getInstance().getUploadSession(Utils.getSessionIdFromHttpRequest(request));
uSession.getActiveFUSBean().setCancel(true);
UploadSessionManager.getInstance().addSession(uSession);
responseFileUploadStatusPoll(request,response);
}
/**
* 在上传文件列表中查找与文件id相关的URL
* @param request
* @param fileId 文件id
* @return 找到返回URL,否则返回null
*/
private String findFileNameInFileUploadedList(HttpServletRequest request,int fileId){
UploadSessionImpl uSession=UploadSessionManager.getInstance().getUploadSession(Utils.getSessionIdFromHttpRequest(request));
if (uSession.getFUSBeanList().size()>fileId){
FileUploadStatus fus=(FileUploadStatus)uSession.getFUSBeanList().get(fileId);
return fus.getUploadFileURL();
}
else{
return null;
}
}
/**
* 下载文件
* @param request 其中downFile参数值为下载文件名
* @param response
* @throws IOException
*/
private void downloadFile(HttpServletRequest request,HttpServletResponse response) throws IOException{
int fileId=Integer.parseInt(request.getParameter(PROTOCOL_COMMAND_FILEID_KEY));
String fileName=findFileNameInFileUploadedList(request,fileId);
if (fileName!=null){
setFileDownloadResponseHeader(response,fileName);
File uploadedFile = new File(request.getRealPath(Constant.UPLOAD_DIR)+File.separator+fileName);
DataInputStream is=new DataInputStream(new FileInputStream(uploadedFile));
DataOutputStream os=new DataOutputStream(response.getOutputStream());
byte[] readBytes=new byte[128];
while(is.read(readBytes)!=-1){
os.write(readBytes);
}
os.close();
is.close();
}
else{
InteractionMessage im=new InteractionMessage();
im.setMsg("下载文件失败:没有找到文件");
sendSerializedBean( response,im);
}
}
/**
* 删除文件,删除成功返回新的FUS列表,否则返回消息
* @param request 其中deletedFile参数值为删除文件名
* @param response
* @throws IOException
* @throws ServletException
* @throws IOException
*/
private void deleteFile(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
logger.debug("发送删除文件回应");
int fileId=Integer.parseInt(request.getParameter(PROTOCOL_COMMAND_FILEID_KEY));
String fileName=findFileNameInFileUploadedList(request,fileId);
if (fileName!=null){
File deletedFile = new File(request.getRealPath(Constant.UPLOAD_DIR)+File.separator+fileName);
if (dele