Java实现对文本文件MD5加密并ftp传送到远程主机目录

需求描述:javascript

若是想学习Java工程化、高性能及分布式、深刻浅出。微服务、Spring,MyBatis,Netty源码分析的朋友能够加个人Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给你们。css

客户出完帐以后须要把出帐的数据以文本文件的方式传送给收入管理系统,客户之前是经过本地的一个工具软件上传的,因为安全监管的缘由,不容许在本地使用工具上传,所以客户但愿咱们在已经上线使用的系统开发一个功能实现他们的需求。java

业务梳理:git

我梳理一下具体的细节,具体的流程如图所示:web

程序实现:sql

1、首先是设计页面,因为是在原系统的基础上新增功能,须要提早作好菜单的配置工做。我设计的页面以下图,一个是下拉选择框(用户选择相对应的业务),一个是选择文件,一个是月份(表示须要传送的文件是哪一个月),一个是上传按钮,用户选择文件以后选择月份点击上传按钮以后便可触发上传操做。数据库

如下是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>业务类型
    <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 >
&nbsp;
</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>安全


2、点击上传按钮以后的函数为:importHandle(),提交的请求为interfaceupload_UPLOAD_interfaceupload.doapp

<input id="impbut" type="button" value="上传" onclick="importHandle()" class="button" />


系统是由struts2实现的,所以要在配置中加入这一段请求相对应的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>   


3、作好了相对应的准备工做,继续来写接下来的业务逻辑。

编写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);


实现的思路是调用byteToHexString方法获得加密以后MD5的字符串,经过writeFileContent实现把文本写入同名的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方法,主要是实现对文本文件的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方法,实现把文本写入同名的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;
      }


4、获取到文本文件和生成同名的文件名以后,紧接着就是获取相对应的ftp主机,用户名,密码以及路径信息了。我把这相对应的信息保存在数据库中。首先咱们把获取到的业务类型放入一个HashMap中。

   parameterMap=new HashMap();
   parameterMap.put("audit_flag",OperationType);


而后咱们配置ibaits的sqlid

   <!-- 根据业务选择路径,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>

 

而后执行该sqlid的查询,把结果放入List 中

List<Map> resultType=EasyDataFatcherOnIbatis.queryBySqlKey("checkFtpType",false,parameterMap);
下面是根据该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主机,用户名,密码以及路径信息了。

5、最后一步是实现上传,我是用的FTPClient来实现的。
实现的操做都写在了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如何实现对某一目录下的文件夹下的文本文件实现MD5加密,并生成同名的MD5文件,根据配置信息,获取主机ip,用户名密码,传送的路径,而后实现ftp远程传送功能。若是你有相似的需求,但愿能够帮助到你,或者你能从中获取到灵感。

若是想学习Java工程化、高性能及分布式、深刻浅出。微服务、Spring,MyBatis,Netty源码分析的朋友能够加个人Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给你们。   

相关文章
相关标签/搜索