Java對文本文件MD5加密并ftp傳送到遠程主機目錄的實現(xiàn)方法
需求描述:
客戶出完賬之后需要把出賬的數(shù)據(jù)以文本文件的方式傳送給收入管理系統(tǒng),客戶以前是通過本地的一個工具軟件上傳的,由于安全監(jiān)管的原因,不允許在本地使用工具上傳,因此客戶希望我們在已經(jīng)上線使用的系統(tǒng)開發(fā)一個功能實現(xiàn)他們的需求。
業(yè)務梳理:
我梳理一下具體的細節(jié),具體的流程如圖所示:

程序實現(xiàn):
一、首先是設計頁面
由于是在原系統(tǒng)的基礎上新增功能,需要提前做好菜單的配置工作。我設計的頁面如下圖,一個是下拉選擇框(用戶選擇相對應的業(yè)務),一個是選擇文件,一個是月份(表示需要傳送的文件是哪個月),一個是上傳按鈕,用戶選擇文件之后選擇月份點擊上傳按鈕之后即可觸發(fā)上傳操作。

以下是JSP界面的源碼:
<%@ include file="/common/taglibs.jsp"%>
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page isELIgnored="false"%>
<s:form enctype="multipart/form-data" method="post" onsubmit="return valid();">
<page:applyDecorator name="simpleQuery">
<table cellspacing="1" border="0">
<title><s:text name="erp接口上傳小程序" /></title>
<s:hidden name="fileName"></s:hidden>
<tr><td>業(yè)務類型
<select id="" name="OperationType" class="formselect">
<option></option>
<option value="1">集團預出賬</option>
<option value="2">集團正式出賬</option>
</select>
</td>
<td>接口月份:
<as:datepicker id="startDate" name="rpmonth" readonly="false" disabled="false"
formatFlag="date6" showDefault="true" cssClass="required validate-datetime"> </as:datepicker>
</td>
</tr>
<tr><td width="10%">選擇文件
<s:file id="upload" name="upload"></s:file>
</td>
<td >
</td>
<td >
<input id="impbut" type="button" value="上傳" onclick="importHandle()" class="button" />
</td>
</tr>
</table>
</page:applyDecorator>
</s:form>
<script type="text/javascript">
function importHandle() {
var fileName = $('upload').value;
if (fileName == null || fileName == undefined || fileName == "") {
validation.userDefined("請選擇要上傳的文件");
return;
}
fileName = fileName.split(".");
if (fileName[fileName.length - 1] == "txt" || fileName[fileName.length - 1] == "TXT") {
document.forms[0].action = "interfaceupload_UPLOAD_interfaceupload.do";
document.forms[0].submit();
} else {
validation.userDefined("文件格式錯誤,您上傳的格式不被允許");
return;
}
}
</script>
二、點擊上傳按鈕之后的函數(shù)為:importHandle(),提交的請求為interfaceupload_UPLOAD_interfaceupload.do
<input id="impbut" type="button" value="上傳" onclick="importHandle()" class="button" />
系統(tǒng)是由struts2實現(xiàn)的,因此要在配置中加入這一段請求相對應的action的配置
<!-- erp接口文件上傳 --> <action name="interfaceupload_UPLOAD_interfaceupload" class="aicu.application.mps.voice.international.web.revenue.FileImportAction"> <result name="success">/WEB-INF/jsp/revenue/interfaceupload.jsp</result> <param name="uploadServiceId">interfaceupload</param> </action>
三、做好了相對應的準備工作,繼續(xù)來寫接下來的業(yè)務邏輯。
編寫aicu.application.mps.voice.international.web.revenue.FileImportAction類
package aicu.application.mps.voice.international.web.revenue;
import aicu.application.mps.voice.international.web.revenue.FileUploadAction;
public class FileImportAction extends FileUploadAction {
public String execute() throws Exception {
System.out.println("hello");
smartUpload();
return SUCCESS;
}
}
由于FileImportAction繼承了FileUploadAction,所以相對應的請求都會由>FileUploadAction的execute()來處理。
首先是獲取上傳上來的文件對象,通過聲明上傳文件的對象,內容類型,文件名,服務ID,然后在生成set()方法和get()方法便能獲取到文件對象。
protected File upload;// 實際上傳文件
protected String uploadContentType; // 文件的內容類型
protected String uploadFileName; // 上傳文件名
protected String uploadServiceId;//上傳服務ID
public File getUpload() {
return upload;
}
public void setUpload(File upload) {
this.upload = upload;
}
public String getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
public String getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
public String getUploadServiceId() {
return uploadServiceId;
}
public void setUploadServiceId(String uploadServiceId) {
this.uploadServiceId = uploadServiceId;
}
然后是對當前的文本文件進行MD5加密,生成同名的MD5文件,文件中只有一行加密之后的MD5字符串。
由于通過struts上傳的文件是存放在臨時目錄下,我處理的思路是,先把文件copy到指定的路徑下
String datapath = getRealPath()+"upload"+File.separator+UUID.randomUUID()+File.separator; File newFile=new File(new File(datapath),uploadFileName); if (!newFile.getParentFile().exists()) newFile.getParentFile().mkdirs(); FileUtils.copyFile(upload, newFile);
然后是生成MD5同名文件
FileMD5 filemd5=new FileMD5(); String md5str=filemd5.getMD5(newFile);
實現(xiàn)的思路是調用byteToHexString方法得到加密之后MD5的字符串,通過writeFileContent實現(xiàn)把文本寫入同名的MD5文件中。FileMD5類的getMD5(File file)方法:
public String getMD5(File file) {
Boolean bool = false;
FileInputStream fis = null;
String filename=file.getName();
String[] newfilepath=filename.split("\\.");
String filenameTemp = file.getParent()+file.separator+newfilepath[0]+ ".md5";
File md5file = new File(filenameTemp);
try {
MessageDigest md = MessageDigest.getInstance("MD5");
fis = new FileInputStream(file);
byte[] buffer = new byte[2048];
int length = -1;
long s = System.currentTimeMillis();
while ((length = fis.read(buffer)) != -1) {
md.update(buffer, 0, length);
}
byte[] b = md.digest();
String filecontent=byteToHexString(b);
if (!md5file.exists()) {
md5file.createNewFile();
bool = true;
System.out.println("success create file,the file is "
+ md5file.getName());
writeFileContent(filenameTemp, filecontent);
}
else {
md5file.delete();
System.out.println("success delete file,the file is "
+ md5file.getName());
md5file.createNewFile();
bool = true;
System.out.println("success create file,the file is "
+ md5file.getName());
writeFileContent(filenameTemp, filecontent);
}
return byteToHexString(b);
} catch (Exception ex) {
ex.printStackTrace();
return null;
} finally {
try {
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
byteToHexString方法,主要是實現(xiàn)對文本文件的MD5加密,得到加密之后的MD5文件
private String byteToHexString(byte[] tmp) {
String s;
char str[] = new char[16 * 2];
int k = 0;
for (int i = 0; i < 16; i++) {
byte byte0 = tmp[i];
str[k++] = hexdigits[byte0 >>> 4 & 0xf];
str[k++] = hexdigits[byte0 & 0xf];
}
s = new String(str);
return s;
}
writeFileContent方法,實現(xiàn)把文本寫入同名的MD5文件中
public boolean writeFileContent(String filepath, String newstr) throws IOException {
Boolean bool = false;
//String filein = newstr + "\r\n";
String filein = new String(newstr);
String temp = "";
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader br = null;
FileOutputStream fos = null;
PrintWriter pw = null;
try {
File file = new File(filepath);
fis = new FileInputStream(file);
isr = new InputStreamReader(fis);
br = new BufferedReader(isr);
StringBuffer buffer = new StringBuffer();
for (int i = 0; (temp = br.readLine()) != null; i++) {
buffer.append(temp);
buffer = buffer.append(System.getProperty("line.separator"));
}
buffer.append(filein);
fos = new FileOutputStream(file);
pw = new PrintWriter(fos);
pw.write(buffer.toString().toCharArray());
pw.flush();
bool = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (pw != null) {
pw.close();
}
if (fos != null) {
fos.close();
}
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (fis != null) {
fis.close();
}
}
return bool;
}
四、獲取到文本文件和生成同名的文件名之后,緊接著就是獲取相對應的ftp主機,用戶名,密碼以及路徑信息了。我把這相對應的信息保存在數(shù)據(jù)庫中。首先我們把獲取到的業(yè)務類型放入一個HashMap中。
parameterMap=new HashMap();
parameterMap.put("audit_flag",OperationType);
然后我們配置ibaits的sqlid
<!-- 根據(jù)業(yè)務選擇路徑,zhongfs于2017-12-05添加 --> <select id="checkFtpType" resultClass="java.util.LinkedHashMap"> select ftphost, proguser, progpass, remotedirectory from t_ftp_config s where 1 = 1 <isNotEmpty prepend="AND" property="audit_flag"> <![CDATA[ s.audit_flag = #audit_flag# ]]> </isNotEmpty> </select>
然后執(zhí)行該sqlid的查詢,把結果放入List 中
List<Map> resultType=EasyDataFatcherOnIbatis.queryBySqlKey("checkFtpType",false,parameterMap);
下面是根據(jù)該sqlid查詢出來的List結果中,取出相關的信息
String host = (String)resultType.get(0).get("FTPHOST");
String user = (String)resultType.get(0).get("PROGUSER");
String pass = (String)resultType.get(0).get("PROGPASS");
String path = (String)resultType.get(0).get("REMOTEDIRECTORY");
//每月會自動生成一個月份的子目錄
String relpath=path+rpmonth+"/";
至此,便可以獲取到相對應的ftp主機,用戶名,密碼以及路徑信息了。
五、最后一步是實現(xiàn)上傳,我是用的FTPClient來實現(xiàn)的。
實現(xiàn)的操作都寫在了FtpBBSUtil的FtpSento方法中,其中datapath表示需要傳送文件的目錄。
FtpBBSUtil.getFtpBBS().FtpSento(datapath, host, user, pass, relpath);
FtpBBSUtil的FtpSento方法如下所示:
public void FtpSento(String localPath, String host, String user,
String pass, String path) throws Exception {
login(host, 21, user, pass);
File parentFile = new File(localPath);
File[] files = parentFile.listFiles();
String outPath = path;
for (File aFile : files) {
if (aFile != null && aFile.getName() != null) {
put(aFile, outPath, new String((aFile.getName())
.getBytes("GB18030"), "ISO8859-1"));
}
}
logout();
}
總結
本篇文章描寫了Java如何實現(xiàn)對某一目錄下的文件夾下的文本文件實現(xiàn)MD5加密,并生成同名的MD5文件,根據(jù)配置信息,獲取主機ip,用戶名密碼,傳送的路徑,然后實現(xiàn)ftp遠程傳送功能。如果你有類似的需求,希望可以幫助到你,或者你能從中獲取到靈感。
相關文章
Java 使用 HttpClient 發(fā)送 GET請求和 POST請求
本文主要介紹了Java 使用 HttpClient 發(fā)送 GET請求和 POST請求,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08
解決bean對象注入報錯:Field in required a bean&nb
這篇文章主要介紹了解決bean對象注入報錯:Field in required a bean of type‘‘that could not be found.問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-06-06
java中int轉string與string轉int的效率對比
這篇文章主要介紹了java中int轉string與string轉int的效率對比,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
springboot使用Thymeleaf報錯常見的幾種解決方案
這篇文章主要介紹了springboot使用Thymeleaf報錯常見的幾種解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11
使用Swagger2實現(xiàn)自動生成RESTful?API文檔
在開發(fā)?RESTful?API?的過程中,文檔是非常重要的一部分,可以幫助開發(fā)者了解?API?的功能和使用方法,本文將使用Swagger2?實現(xiàn)自動生成?RESTful?API?文檔,需要的可以參考一下2023-06-06

