架设用Webservice实现文件上传功能CentOS服务器(二)--WebService

功能概述,看代码中注释应该可以理解

  • 为了文件安全对url进行适当的保护处理
  • 简单的配置功能,如文件大小限制,文件存放位置设定等
  • 返回文件内容方法还需完善

代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import common.IniEditor;
import common.Logger;
import common.SecurityUtil;

/**
 * 文件上傳Web Service 組件,提供給AP使用,AP文件統一存放在File Server而非DB,以方便集中管理AP 所產生文件,並且避免因大量文件存放DB而導致DB管理(如備份)問題。
 *該組件主要提供:
 *<ol>
 *<li>
 *<b>文件上傳保存:</b>由AP提供目錄規劃,按目錄存放文件,AP 只保存該接口返回的File ID;並提供隱藏存放路徑的保密措施;
 *</li>
 *<li>
 *<b>文件刪除:</b>AP 提供File ID(加密後),刪除指定文件;
 *</li>  
  *<li>
 *<b>取得文件:</b>AP 提供File ID(加密後),返回指定文件路徑,或文件內容(二進制);
 *</li>  
 *@version 1.0
 *
 * @author rayd
 *
 */
public class FileService {

    private final static String LOG_FILENAME = "fileserver.log";
    private final static String LOG_FILENAME_ERROR = "fileserver_error.log";
    private final static String CFG_FILESERVER = "fileserver";
    private final static String LINE_BIAS = "/";
    private final static String ERROR_FLAG= "error_";

    /**
     * 上傳文件,依照AP 提供的路徑存放文件,爲文件安全考慮,每次均當作一份新的文件進行保存,即使是同一份文件也不會覆蓋,若要覆蓋,請調用者先執行@see deleteFile 刪除 命令。
     * @param b_bytes 文件內容,二進制,Default最大10M,可設定
     * @param s_path 存放路徑,如/131/purchase/po1310001,該接口會按年月區分目錄,如以上目錄實際會保存到”/201409/131/purchase/po1310001“目錄。
     * @param s_extName 文件类别,可以爲pdf/.pdf/test.pdf
     * @return File ID ,進加密處理的文件識別ID ;若不成功,將返回以error_開頭的信息,AP 可以此作爲成功與否的判斷。
     *
     */
    public String uploadFile(byte[] b_bytes, String s_path, String s_extName){

        StringBuilder retUrl = new StringBuilder();
        StringBuilder sbEncrypt = new StringBuilder();
        String msg = ERROR_FLAG;
        String filePath = "";
        String fileName = "";
        String extName = "";
        String file_dir = "";
        String log_dir = "";
        String ymPath = "";
        String path_first = "";
        String server_vpath="";
        String server_host="";
        String customPath="";
        //String encrypt_path="";
        Date date;
        SimpleDateFormat df;
        UUID uuid;
        int max_size = 0;
        
        //get config value
        try {
            //get ini value
            max_size = Integer.parseInt(getConfig(CFG_FILESERVER, "max_size"));
            path_first = getConfig(CFG_FILESERVER, "path_first");
            server_host = getConfig(CFG_FILESERVER, "server_host");
            server_vpath = getConfig(CFG_FILESERVER, "server_vpath");
            file_dir = getConfig(CFG_FILESERVER, "file_dir");
            //log path
            log_dir = file_dir + File.separator + "log" + File.separator;
            
        } catch (NumberFormatException e1) {
            msg += "可能缺少必要的配置項,或max_size配置項值應爲數字!";
            return msg;
        } catch (Exception e1) {
            msg += "系統配置讀取異常,可能缺少必要的配置項!";
            return msg;
        }

        // 前置检查
        if (b_bytes == null || b_bytes.length == 0) {
            msg += "沒有接收到任何文件內容,這樣來去空空不失望嗎?";
            return msg;
        }
        //path
        if (s_path == null || s_path.length() == 0) {
            msg += "請指定文件存放路徑,如 /po/no/,不知要放到哪裏,真是要到Cloud端嗎?";
            return msg;
        }
        //filename
        if (s_extName == null || s_extName.length() == 0) {
            msg += "請指定文件類型,如.pdf or pdf or abc.pdf!";
            return msg;
        }
        
        // size限制,设定max_size为0时,不限制;
        if (max_size != 0 && b_bytes.length > 1024 * 1024 * max_size) {
            msg += "上傳文件過大,好吧,別再挑戰人類的極限!";
            Logger.Log(msg, LOG_FILENAME_ERROR, log_dir);
            return msg;
        }

        retUrl.append(server_host).append(server_vpath);

        date = new Date();
        if (path_first.isEmpty() || path_first.equalsIgnoreCase("none")) {

        } else {
            retUrl.append(LINE_BIAS);
            //  yyyyMM or yyyy/MM
            df = new SimpleDateFormat(path_first);
            ymPath = df.format(date).toString();
        }
        sbEncrypt.append(ymPath);
        
        // guid做为文件名称
        uuid = UUID.randomUUID();

        // "\" to "/"
        customPath = s_path.replace("\\", LINE_BIAS);

        // po012.pdf
        // .pdf
        // pdf
        int pos1 = s_extName.lastIndexOf(‘.‘);
        if (pos1 >= 0) {
            extName = s_extName.substring(pos1);
        } else {
            extName = "." + s_extName;
        }

        fileName = uuid.toString() + extName;
        filePath = file_dir + File.separator + ymPath;

        if (!customPath.startsWith(LINE_BIAS)) {
            filePath += File.separator;
            sbEncrypt.append(LINE_BIAS);
        }
        filePath += customPath;
        sbEncrypt.append(customPath);
        if (!customPath.endsWith(LINE_BIAS)) {
            filePath += File.separator;
            sbEncrypt.append(LINE_BIAS);
        }
        sbEncrypt.append(fileName);

        FileOutputStream fos = null;
        
        try {
            
            
            File file = new File(filePath);
            // 创建多个目录
            if (!file.exists())
                file.mkdirs();

            fos = new FileOutputStream(filePath + fileName);
            fos.write(b_bytes);
            fos.flush();
            
            msg = SecurityUtil.encryptPath(retUrl.toString() ,sbEncrypt.toString());
            Logger.Log("文件保存成功:" + retUrl.toString()+sbEncrypt.toString() , LOG_FILENAME, log_dir);
            //Logger.Log("密碼:" + msg , LOG_FILENAME, log_dir);
        } catch (IOException ex) {
            msg = "文件存儲失敗:" + ex.getMessage();
            Logger.Log(msg + "ErrMsg: " + ex.getStackTrace(),
                    LOG_FILENAME_ERROR, log_dir);
        } catch (Exception e) {
            
        } finally {
            if (fos != null)
                try {
                    fos.close();
                } catch (IOException e) {
                    //e.printStackTrace();
                    msg += "上傳文件不能正常關閉,這狀況真的是千古難遇,建議您去買彩票!";
                    Logger.Log(msg + " ErrMsg: " + e.getStackTrace(),
                            LOG_FILENAME_ERROR, log_dir);
                }
        }

        return msg;
    }

    /**
     * 刪除指定的文件
     * @param s_fileId AP保留的FileID
     * @return 返回信息,1:代表刪除成功,其他代碼失敗信息;若不成功,將返回以error_開頭的信息,AP 可以此作爲成功與否的判斷。
     *
     */
    public String deleteFile(String s_fileId){
        String msg = ERROR_FLAG;
        String filePath;
        
        String fileName = "";
        String file_dir = "";
        String log_dir = "";
        String server_vpath="";
        
        if(s_fileId.isEmpty()){
            msg += "沒有傳入任何路徑與文件!親,又調皮了!";
            return msg;
        }
        //get config value
        try {
            //get ini value
            server_vpath = getConfig(CFG_FILESERVER, "server_vpath");
            file_dir = getConfig(CFG_FILESERVER, "file_dir");
            //log path
            log_dir = file_dir + File.separator + "log" + File.separator;
            filePath = SecurityUtil.decryptPath(s_fileId);
            int pos1 = filePath.indexOf(server_vpath);
            fileName = file_dir +filePath.substring(pos1+server_vpath.length()) ;
            File file = new File(fileName);
            
            if (!file.exists()){
                msg += "指定的文件不存在,請確認文件路徑與名稱拼寫正確!親,別玩了!\r\n s_fileId =" + s_fileId;
            }else{
                file.delete();
        
                msg="1";
                Logger.Log("文件刪除成功!" + "\r\n s_fileId=" + s_fileId + "\r\n fileName = " + fileName , LOG_FILENAME, log_dir);
            }

        } catch (Exception e1) {
            msg += "文件刪除異常!";
            return msg;
        }
        //file.deleteOnExit();
        return msg;
    }
    
    /**
     * 讀取指定的文件,以二進制內容返回
     * @param s_fileId AP保留的File ID
     * @return 返回文件二進制內容,若讀取失敗,將返回以error_開頭的信息,AP 可以此作爲成功與否的判斷。
     *
     *
     */
    public String getFile(String s_fileId){
        String msg = ERROR_FLAG;
        String filePath;
        
        String fileName = "";
        String file_dir = "";
        String log_dir = "";
        String server_vpath="";
        
        if(s_fileId.isEmpty()){
            msg += "沒有傳入任何路徑與文件!親,又調皮了!";
            return msg;
        }
        //get config value
        try {
            //get ini value
            server_vpath = getConfig(CFG_FILESERVER, "server_vpath");
            file_dir = getConfig(CFG_FILESERVER, "file_dir");
            //log path
            log_dir = file_dir + File.separator + "log" + File.separator;
            filePath = SecurityUtil.decryptPath(s_fileId);
            int pos1 = filePath.indexOf(server_vpath);
            fileName = file_dir +filePath.substring(pos1+server_vpath.length()) ;
            File file = new File(fileName);
            
            if (!file.exists()){
                msg += "指定的文件不存在,請確認文件路徑與名稱拼寫正確!親,別玩了!\r\n s_fileId =" + s_fileId;
            }else{
                
                msg=byte2hex(readFile(fileName));
                Logger.Log("文件讀取成功!" + "\r\n s_fileId=" + s_fileId + "\r\n fileName = " + fileName , LOG_FILENAME, log_dir);
            }

        } catch (Exception e1) {
            msg += "文件讀取異常!";
            return msg;
        }
        //file.deleteOnExit();
        return msg;
    }
    
    /**
     * 取得指定的文件URL
     * @param s_fileId AP保留的FileID
     * @return 文件明文路徑,若讀取失敗,將返回以error_開頭的信息,AP 可以此作爲成功與否的判斷。
     *     
     */
    public String getFileUrl(String s_fileId){
        String msg = ERROR_FLAG;
        String filePath;
        
        String fileName = "";
        String file_dir = "";
        String log_dir = "";
        String server_vpath="";
        
        if(s_fileId.isEmpty()){
            msg += "沒有傳入任何路徑與文件!親,又調皮了!";
            return msg;
        }
        //get config value
        try {
            //get ini value
            server_vpath = getConfig(CFG_FILESERVER, "server_vpath");
            file_dir = getConfig(CFG_FILESERVER, "file_dir");
            //log path
            log_dir = file_dir + File.separator + "log" + File.separator;
            filePath = SecurityUtil.decryptPath(s_fileId);
            int pos1 = filePath.indexOf(server_vpath);
            fileName = file_dir +filePath.substring(pos1+server_vpath.length()) ;
            File file = new File(fileName);
            
            if (!file.exists()){
                msg += "指定的文件不存在,請確認文件路徑與名稱拼寫正確!親,別玩了!\r\n s_fileId =" + s_fileId;
            }else{
                msg = filePath;
            }

        } catch (Exception e1) {
            msg += "文件取得異常!";
            return msg;
        }
        //file.deleteOnExit();
        return msg;
    }
    
    
    
    // get ini config file
    private String getConfig(String s_section, String s_name){
        String val = "";
        String msg = "";
        String rootPath =getClass().getProtectionDomain().getCodeSource()
                .getLocation().getPath();
        String iniFile = rootPath    + "fileservice.ini";
        
        IniEditor conf = new IniEditor();
        try {
            conf.load(iniFile);
        } catch (IOException e) {
            msg = "配置文件(fileservice.ini)不存在或讀取異常!";
            Logger.Log(msg , LOG_FILENAME, rootPath);
        }
        val = conf.get(s_section, s_name);

        return val;

    }
    
    //讀取文件
    private static byte[] readFile(String fileName) {
        File file = new File(fileName);
        byte[] buffer = null;
        InputStream in = null;
        try {
            // 一次读一个字节
            in = new FileInputStream(file);
            buffer = new byte[in.available()];
            in.read(buffer);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }
    
    // 二进制转字符串  
    private static String byte2hex(byte[] b)   
    {  
       StringBuffer sb = new StringBuffer();  
       String tmp = "";  
       for (int i = 0; i < b.length; i++) {  
        tmp = Integer.toHexString(b[i] & 0XFF);  
        if (tmp.length() == 1){  
            sb.append("0" + tmp);  
        }else{  
            sb.append(tmp);  
        }  
          
       }  
       return sb.toString();  
    }  

}

参考:
架设用Webservice实现文件上传功能CentOS服务器(一)

时间: 2024-12-20 09:15:25

架设用Webservice实现文件上传功能CentOS服务器(二)--WebService的相关文章

架设用Webservice实现文件上传功能CentOS服务器(一)--Tomcat

1.查看版本 //通用 lsb_release -a //查内核版本 uname -a //centos or redhat rpm -q centos-release rpm -q redhat-release 2.安装tomcat tomcat一般安装目录 /usr/local/tomcat,先查看是否已经有安装. //确认jdk是否有安装及其版本 java -version //若出现不了版本信息,需先安装jdk,此不赘述.  //上传安装文件 scp apache-tomcat-7.0.

使用Commons FileUpLoad组件实现文件上传功能

Commons 是Apache开放的源码组织的一个java子项目,该项目主要涉及一些开发中常用的模块,如文件上传,命令行处理,数据库连接池等.FileUpLoad就是其中的一个用于处理HTTP文件上传的子项目.Commons FileUpLoad组建具有以下几个特点: 1.使用简单:Commons FileUpLoad组件可以方便的嵌入JSP文件中,在JSP文件中仅编写少量代码就可完成文件上传功能,十分方便. 2.能够全程控制上传的内容:使用Commons FileUpLoad组件提供的对象及操

nodejs 实现简单的文件上传功能

首先需要大家看一下目录结构,然后开始一点开始我们的小demo. 文件上传总计分为三种方式: 1.通过flash,activeX等第三方插件实现文件上传功能. 2.通过html的form标签实现文件上传功能,优点:浏览器兼容好. 3.通过xhr level2的异步请求,可以百度formData对象. 这里使用2做个练习. node插件请看下package.json文件 { "name": "upload", "version": "0.1

配置php.ini实现PHP文件上传功能

本文介绍了如何配置php.ini实现PHP文件上传功能.其中涉及到php.ini配置文件中的upload_tmp_dir.upload_max_filesize.post_max_size等选项,这些选项是文件上传成败的关键.我们以php.5.3.5的Windows版本为例说明. php.ini中文件上传功能配置选项说明 用文本工具(推荐EditPlus)打开php.ini 配置文件,查找 File Uploads ,在这个区域有以下3个选项: file_uploads = On 是否允许HTT

Spring MVC使用commons fileupload实现文件上传功能

通过Maven建立Spring MVC项目,引入了Spring相关jar依赖. 1.为了使用commons fileupload组件,需要在pom.xml中添加依赖: <properties> <spring.version>3.0.7.RELEASE </spring.version> <junit.version>3.8.1</junit.version> <fileupload.version>1.2.2</fileupl

如何在Web页面中集成文件上传功能

当前,个人主页制作非常流行.当用户开发好自己的页面时,需要将文件传输到服务器上,解决这个问题的方法之一 是运行FTP服务器并将每个用户的FTP默认目录设为用户的Web主目录,这样用户就能运行FTP客户程序并上传文件到指定的 Web目录.由于Windows NT 和 Windows98均不提供直接的基于窗口形式的FTP客户程序,用户必须懂得如何使用基于命令行 的FTP客户,或掌握一种新的基于窗口形式的FTP客户程序.因此,这种解决方案仅对熟悉FTP且富有经验的用户来说是可行 的. 如果我们能把文件

一个简单的blog系统(三) 增加文件上传功能

1. 一个完整的博客怎么能缺少图片呢,目前上传文件的方法有三种: (1)使用Express自带的文件上传功能,不涉及数据库. (2)使用Formidable外部模块,不涉及数据库. (3)上传到MongoDB,涉及到数据库. 可以看出,第一种方式最简单,Express通过bodyParser()解析请求体,因此我们可以使用bodyParser()来实现文件的上传功能. 2.实现过程 2.1 首先打开header.ejs,在<li><a href="/post" tit

用c++开发基于tcp协议的文件上传功能

用c++开发基于tcp协议的文件上传功能 2005我正在一家游戏公司做程序员,当时一直在看<Windows网络编程> 这本书,把里面提到的每种IO模型都试了一次,强烈推荐学习网络编程的同学阅读,比 APUE 讲的更深入 这是某个银行广告项目(p2p传输视频)的一部分 IO模型采用的阻塞模式,文件一打开就直接上传 用vc 2003编译,生成win32 dll 麻雀虽小五脏俱全,CSimpleSocket,CReadStream dll 输出一虚类 extern "C" __d

Node.js入门教程——如何实现文件上传功能

作者:zhanhailiang 日期:2014-11-16 本文将介绍如何使用Node.js实现文件上传功能. 1. 初始化项目信息:npm init [root@~/wade/nodejs/nodejs-upload-image-demo]# npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to gu