加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-16 23:20:55 所属栏目:安全 来源:网络整理
导读:功能概述,看代码中注释应该可以理解 为了文件安全对url进行适当的保护处理 简单的配置功能,如文件大小限制,文件存放位置设定等 返回文件内容方法还需完善 代码: import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;im
功能概述,看代码中注释应该可以理解
  • 为了文件安全对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_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,"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 += "指定的文件不存在,請確認文件路徑與名稱拼寫正確!親,別玩了!rn s_fileId =" + s_fileId;
?? ??? ??? ?}else{
?? ??? ??? ??? ?file.delete();
?? ??? ?
?? ??? ??? ??? ?msg="1";
?? ??? ??? ??? ?Logger.Log("文件刪除成功!" + "rn s_fileId=" + s_fileId + "rn fileName = " + 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,"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 += "指定的文件不存在,請確認文件路徑與名稱拼寫正確!親,別玩了!rn s_fileId =" + s_fileId;
?? ??? ??? ?}else{
?? ??? ??? ??? ?
?? ??? ??? ??? ?msg=byte2hex(readFile(fileName));
?? ??? ??? ??? ?Logger.Log("文件讀取成功!" + "rn s_fileId=" + s_fileId + "rn fileName = " + 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,"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 += "指定的文件不存在,請確認文件路徑與名稱拼寫正確!親,別玩了!rn 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,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服务器(一)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读