您的位置:首页 > 运维架构 > Linux

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

2014-09-29 14:48 701 查看
功能概述,看代码中注释应该可以理解

为了文件安全对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服务器(一)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: