赞
踩
近期做了一个财务方面的系统(以下称“进销存”),里面有一个模块是销项发票,客户要求与金税开票系统(以下称”金税”)做接口。在网上找到了金税的接口文档。 看了接口文档后确定了使用ftp与金税交互的开发方案。
具体方案为:进销存将编辑好的发票信息按照要求生成xml文件上传至ftp服务器固定目录下,开票人员将ftp服务器固定目录下的xml导入至金税。金税设置将开票的返回结果生成.TXT文件放置到ftp服务器固定目录下。进销存开启一个定时器,读取金税的开票结果。
问题就出现在进销存读取金税的开票结果上。
进销存生成的发票信息为yyyymmddxxyyy.xml,即年月日流水号的xml,金税读取xml后返回的开票结果为yyyymmddxxyyy_开票结果.TXT。文件名称中有中文字符。
进销存读取开票结果的思路为,获取所有开票结果文件,并将文件名中的年月流水号取出来,作为修改进销存开票信息的依据。然后读取.TXT中的内容,获取开票信息,如是否开票成功,发票号,开票日期等。
/**
* 获取FTPClient对象
* @param ftpHost FTP主机服务器
* @param ftpPassword FTP 登录密码
* @param ftpUserName FTP登录用户名
* @param ftpPort FTP端口 默认为21
* @param charsetName
* @return
*/
public static FTPClient getFTPClient(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword, String charsetName) {
FTPClient ftpClient = null;
try {
ftpClient = new FTPClient();
if(!ftpClient.isConnected()){
ftpClient.connect(ftpHost, Optional.ofNullable(ftpPort).orElse(21));// 连接FTP服务器
}
ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out), true));
ftpClient.setControlEncoding(charsetName);
ftpClient.enterLocalPassiveMode();
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
logger.error("未连接到FTP,用户名或密码错误。");
ftpClient.disconnect();
} else {
logger.info("FTP字符类型" + ftpClient.getCharset().name());
logger.info("FTP连接成功。");
}
} catch (SocketException e) {
ftpClient = null;
logger.info("FTP连接失败------。");
} catch (IOException e) {
ftpClient = null;
logger.info("FTP连接失败------。");
}
return ftpClient;
}
/**
* 递归遍历出目录下面所有文件
*
* @param pathName 需要遍历的目录,必须以"/"开始和结束
* @throws IOException
*/
public static List<File> getAllFiles(FTPClient ftpClient, String pathName) {
List<File> fileList = new ArrayList<>();
try {
if (pathName.startsWith("/") && pathName.endsWith("/")) {
String directory = new String(pathName.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
// 更换目录到当前目录
ftpClient.changeWorkingDirectory(directory);
FTPFile[] files = ftpClient.listFiles();
for (FTPFile file : files) {
if (file.getName().equals(".") || file.getName().equals(".."))
continue;
if (file.isFile()) {
String fileName = file.getName();
InputStream iStream = ftpClient.retrieveFileStream(directory + new String(file.getName().getBytes("UTF-8"), "iso-8859-1"));
File tempFile = File.createTempFile(StringUtils.randomUUID(32), null);
File file1 = new File(tempFile.getParent() + File.separator + fileName);
tempFile.renameTo(file1);
FileUtils.copyInputStreamToFile(iStream, file1);
iStream.close();
ftpClient.completePendingCommand();
fileList.add(file1);
} else if (file.isDirectory()) {
fileList.addAll(getAllFiles(ftpClient, directory + file.getName() + "/"));
}
}
}
} catch (IOException e) {
logger.info(e.getMessage());
}
return fileList;
}
以上代码是我读取开票结果文件的主要代码,我获取ftpclient时设置了编码格式“UTF-8”,使其支持中文名称。其中红色部分是至关重要的,没有转码时获取文件流为null。设置后即可。看了ftp协议后才知道,FTP协议里面,规定文件名编码为iso-8859-1,所以读取时要将文件名转码为iso-8859-1。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。