需求描述:
客户出完账之后需要把出账的数据以文本文件的方式传送给收入管理系统,客户以前是通过本地的一个工具软件上传的,由于安全监管的原因,不允许在本地使用工具上传,因此客户希望我们在已经上线使用的系统开发一个功能实现他们的需求。
业务梳理:
我梳理一下具体的细节,具体的流程如图所示:
程序实现:
一、首先是设计页面,由于是在原系统的基础上新增功能,需要提前做好菜单的配置工作。我设计的页面如下图,一个是下拉选择框(用户选择相对应的业务),一个是选择文件,一个是月份(表示需要传送的文件是哪个月),一个是上传按钮,用户选择文件之后选择月份点击上传按钮之后即可触发上传操作。
以下是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 >
</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>二、点击上传按钮之后的函数为:importHandle(),提交的请求为interfaceupload_UPLOAD_interfaceupload.do
<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>三、做好了相对应的准备工作,继续来写接下来的业务逻辑。
编写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;
}四、获取到文本文件和生成同名的文件名之后,紧接着就是获取相对应的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主机,用户名,密码以及路径信息了。
五、最后一步是实现上传,我是用的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实现对文本文件MD5加密并ftp传送到远程主机目录的更多相关文章
-
利用Java自带的MD5加密
package test.md5; import java.security.MessageDigest; public class MD5Util { public final static Str ...
-
利用Java自带的MD5加密java.security.MessageDigest;
MD5加密算法,即"Message-Digest Algorithm 5(信息-摘要算法)",它由MD2.MD3.MD4发展而来的一种单向函数算法(也就是HASH算法),它是国际著 ...
-
JAVA中简单的MD5加密类(MD5Utils)
MD5加密分析: JDK API: 获取对象的API: 加密的API: package cn.utils; import java.security.MessageDigest; im ...
-
Hook Java API以获得MD5加密前数据
Java实现MD5加密 在Java中,我们用MD5对数据进行加密,代码大概是这样的: import java.security.MessageDigest; import java.security. ...
-
java ldap用户密码md5加密
在这里不过多介绍ldap,因为这样的文章特别多,这里就简单直接的记录这一个问题. 在springboot中通过引入spring-boot-starter-data-ldap,使用LdapTemplat ...
-
JAVA实现AES和MD5加密
package test; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; ...
-
Java 实现32位MD5加密
MD5介绍[链接] Java代码实现 public class Md5Util { private String Md5Util(String s) { try { MessageDigest md ...
-
解决java,C#,php,python MD5加密不一致问题
JAVA写法 public static String md5Base64(final String str, final String key) throws Exception { if ((nu ...
-
java中使用MD5加密技术
在项目中经常会对一些信息进行加密,现在常用的信息加密技术有:MD5.RSA.DES等,今天主要说一下,md5加密,以及如何在java代码根据自己的业务需求使用md5. MD5简介: MD5即Messa ...
随机推荐
-
react+redux教程(六)redux服务端渲染流程
今天,我们要讲解的是react+redux服务端渲染.个人认为,react击败angular的真正“杀手锏”就是服务端渲染.我们为什么要实现服务端渲染,主要是为了SEO. 例子 例子仍然是官方的计数器 ...
-
Power BI官方视频(2) Power BI嵌入到应用中的3种方法
今天给大家介绍3种将Power BI嵌入到应用中的方法. 本文原文地址:Power BI官方视频(2) Power BI嵌入到应用中的3种方法 Power BI系列文章地址:微软Power BI技术文 ...
-
在 Windows 上安装 Laravel 5.x
由于工作中要用到 Laravel ,所以在此记录以备忘. 下载并设置 PHP 进入 http://windows.php.net/download/ 下载 PHP 5.5.x 的最新版本.如果你用的是 ...
-
c#动态调用Webservices
方式一: Hashtable ht = new Hashtable(); ht.Add("a", "testhelloworld"); XmlDocument ...
-
Ubuntu终端常用的快捷键
Ubuntu终端常用的快捷键 Ubuntu中的许多操作在终端(Terminal)中十分的快捷,记住一些快捷键的操作更得心应手.在Ubuntu中打开终端的快捷键是Ctrl+Alt+T.其他的一些常用的快 ...
-
PostgreSQL的时间/日期函数使用
PostgreSQL的常用时间函数使用整理如下: 一.获取系统时间函数 1.1 获取当前完整时间 select now(); david=# select now(); now ----------- ...
-
iOS-App生命周期
iOS APP 生命周期 官方文档: https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneO ...
-
解决ArcGIS10.3属性表中文乱码问题
问题描述:在10.3刚出为不久,就发现有时属性表会出现中文乱码的问题. 解决方法:在Cmd命令行中输入以下命令: reg add HKEY_CURRENT_USER\Software\ESRI\Des ...
-
Objdump-查看汇编指令
作用 Objdump可以用来看汇编指令 查看汇编指令 测试文件 编译指令 gcc -g -o objtest 1.8.c objdump -S objtest |more /main 查看结果
-
Windows开发技术的历史
原文地址:http://www.kuqin.com/windows/20090315/40172.html Windows已经有22年的历史,这22年来,微软官方主力推行的编程语言与API有四个分水岭 ...