All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.logicbus.backend.message.MultiPartForm Maven / Gradle / Ivy

There is a newer version: 1.6.17
Show newest version
package com.logicbus.backend.message;

import java.io.File;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import com.logicbus.backend.message.tools.JsonFactory;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileCleaningTracker;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alogic.idnote.IdNote;
import com.alogic.idnote.IdNoteFactory;
import com.alogic.idnote.IdNoteGroup;
import com.anysoft.util.IOTools;
import com.anysoft.util.JsonTools;
import com.anysoft.util.PropertiesConstants;
import com.anysoft.util.Settings;
import com.logicbus.backend.Context;
import com.logicbus.backend.ServantException;
import com.logicbus.backend.server.http.HttpContext;

/**
 * MultiPartForm
 * 
 * 处理multipart/form-data类型的输入数据,主要用于处理Http上传文件。
 * 
 * @author duanyy
 * @since 1.6.3.31
 * 
 * @version 1.6.4.30 [20160126 duanyy] 
* - 文件上传消息处理透传Context对象
* * @version 1.6.5.6 [20160523 duanyy]
* - 淘汰MessageDoc,采用Context替代
* - 增加getContentType和getContentLength
* * @version 1.6.7.9 [20170201 duanyy]
* - 采用SLF4j日志框架输出日志
* * @version 1.6.11.4 [20171222 duanyy]
* - 缺省上传目录设定到ketty.temp.home
* * @version 1.6.12.36 [20190611 duanyy]
* - 支持主机mask
*/ public class MultiPartForm implements Message { /** * a logger of log4j */ protected static final Logger logger = LoggerFactory.getLogger(MultiPartForm.class); protected static IdNoteGroup idnote = null; protected static boolean hostMask = true; protected static JsonFactory jsonFactory = null; static { jsonFactory = Settings.getToolkit(JsonFactory.class); hostMask = PropertiesConstants.getBoolean(Settings.get(),"servant.hostmask",hostMask); idnote = IdNoteFactory.get(PropertiesConstants.getString(Settings.get(), "servant.code.group", "servant.code")); } protected static FileItemFactory factory = null; protected static final String ID = "uploadItemFactory"; protected static String getHost(String host){ return hostMask ? host.replaceFirst("\\d{1,}\\.\\d{1,}\\.\\d{1,}\\.","*.*.*."):host; } /** * 文件列表 */ protected List fileItems = null; /** * Json结构的根节点 */ protected Map root = null; private long contentLength = 0; /** * 获取FileItemFactory * @return FileItemFactory */ public static FileItemFactory getFileItemFactory(){ if (factory == null){ synchronized (MultiPartForm.class){ if (factory == null){ Settings settings = Settings.get(); factory = (FileItemFactory)settings.get(ID); if (factory == null){ File repos = new File( PropertiesConstants.getString(settings, "http.upload.home", "${ketty.temp.home}/upload") ); if (!repos.exists()){ repos.mkdirs(); } factory = new DiskFileItemFactory( PropertiesConstants.getInt(settings, "http.upload.threshold", DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD * 10), repos); } } } } return factory; } /** * 获取JSON结构的根节点 * * @return JSON结构的根节点 */ public Map getRoot(){ return root; } /** * 获取文件列表 * @return 文件列表 */ public List getFileItems(){ return fileItems; } @Override public String getContentType() { return "application/json;charset=utf-8"; } @Override public long getContentLength() { return contentLength; } @Override public void init(Context ctx) { if (!(ctx instanceof HttpContext)){ throw new ServantException("core.e1001", "The context's class must be HttpContext when using UploadFiles"); } HttpContext httpCtx = (HttpContext)ctx; ServletFileUpload fileUpload = new ServletFileUpload(getFileItemFactory()); try { fileItems = fileUpload.parseRequest(httpCtx.getRequest()); } catch (FileUploadException e) { logger.error(ExceptionUtils.getStackTrace(e)); throw new ServantException("core.e1015",e.getMessage()); } root = new HashMap(); // NOSONAR } @Override public void finish(Context ctx, boolean closeStream) { Map theRoot = getRoot(); JsonTools.setString(theRoot, "code", ctx.getReturnCode()); if (idnote != null){ IdNote note = idnote.getNote(ctx.getReturnCode()); if (note != null){ JsonTools.setString(theRoot, "reason", note.getNote()); JsonTools.setString(theRoot, "advise", ctx.getReason()); }else{ JsonTools.setString(theRoot, "reason", ctx.getReason()); } }else{ JsonTools.setString(theRoot, "reason", ctx.getReason()); } JsonTools.setString(theRoot, "duration", String.valueOf(ctx.getDuration())); JsonTools.setString(theRoot, "host", getHost(ctx.getHost())); JsonTools.setString(theRoot, "serial", ctx.getGlobalSerial()); OutputStream out = null; try { String data = jsonFactory.toJsonString(theRoot); String jsonp = ctx.GetValue("jsonp", ""); if (jsonp != null && jsonp.length() > 0){ data = jsonp + "(" + data + ")"; } out = ctx.getOutputStream(); ctx.setResponseContentType(getContentType()); byte[] bytes = data.getBytes(); contentLength += bytes.length; Context.writeToOutpuStream(out, bytes); out.flush(); }catch (Exception ex){ logger.error(ExceptionUtils.getStackTrace(ex)); }finally{ if (closeStream) { IOTools.close(out); } } } /** * 处理已上传的文件 * @param ctx 上下文 * @param cookies 处理的cookies * @param handler 处理器 */ public void handle(Context ctx,Object cookies,FileItemHandler handler){ if (fileItems != null && !fileItems.isEmpty()){ Map result = new HashMap(); // NOSONAR for (FileItem item:fileItems){ if (item != null && !item.isFormField()){ contentLength += item.getSize(); Map fileResult = new HashMap(); // NOSONAR fileResult.put("field", item.getFieldName()); fileResult.put("name", item.getName()); fileResult.put("size",item.getSize()); handler.handle(ctx,cookies,item, fileResult); result.put(item.getFieldName(), fileResult); } } getRoot().put("files", result); } } /** * FileItem处理器 * * @author duanyy * */ public static interface FileItemHandler { /** * 处理文件 * @param ctx 上下文 * @param cookies 处理的cookies * @param item FileItem * @param result 用于输出文件的处理状态 */ public void handle(Context ctx,Object cookies,FileItem item,Map result); } /** * Upload临时文件自动删除 * * @author duanyy * */ public static class Cleaner implements ServletContextListener{ @Override public void contextDestroyed(ServletContextEvent sce) { Settings settings = Settings.get(); DiskFileItemFactory f = (DiskFileItemFactory)settings.get(ID); FileCleaningTracker tracker = f.getFileCleaningTracker(); if (tracker != null){ logger.info("The uploaded temp files will be deleted."); tracker.exitWhenFinished(); } } @Override public void contextInitialized(ServletContextEvent sce) { Settings settings = Settings.get(); logger.info("Files uploading will be supported."); DiskFileItemFactory f = new DiskFileItemFactory(); f.setFileCleaningTracker(new FileCleaningTracker()); settings.registerObject(ID, f); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy