由于项目有个需求是要去ftp服务器上取文件,文件为xml格式,解析后定时抽取入库。
一开始分了三步,第一步取文件,第二步解析,第三步抽取入库。后来做完后又要根据将文件抽取入库失败的移动到error目录上。所以最后大致上可以分成四步。由于定时器可以利用spring+quartz实现,用到的是spring配置文件,所以就不记录了。
在刚开始动手时,由于没搭建好ftp服务器测试,所以就先做了第二步xml的解析。开始时将解析方法声明为parseXML(File file),将文件放到了本地磁盘上测试,通过。然后开始有点坑的就来了,当搭建好ftp服务器后,就尝试第一步,ftp上取文件。就去调用 commons.net上的FTPClient。
第一步,ftp服务器上取文件。
第一小步,肯定就是连接上ftp服务器,度娘,连接ftp如下:
public void connectServer(String ip, int port, String userName, String userPwd) { ftpClient = new FTPClient(); try { int reply; // 连接 ftpClient.connect(ip, port); // 登录 ftpClient.login(userName, userPwd); reply = ftpClient.getReplyCode(); } catch (Exception e) { log.error("ftp链接失败", e); } }
第二小步就是获取ftp上的文件:
FTPFile[] ftpFIles = ftpClient.listFiles();
第二步:解析xml文件
文件取到了,当然就是去解析xml了,然后坑爹的就来了,之前定好的方法parseXML(File file),接受的是File文件,然而ftpClient获取下来的文件是FtpFile格式。一开始想着怎么去转,花费了一些时间,可能有转过去的方法,但是我没找到。然后度娘上又给了一个是将FtpFile格式的xml解析的,没办法,就换成了 parseXML(FTPFile fPath)。由于SAXReader里的read方法可以接受inputstream流,所以只要将FtpFile转换成流就ok了,ins = ftpClient.retrieveFileStream(fPath.getName());
这里有个坑,就是每次调用ftpClient.retrieveFileStream()后,需要调用ftpClient.getReply()这个方法,把接下来的226消费掉,如果没有写,下一次ftpClient.retrieveFileStream()返回的InputStream对象会一直为null!!!代码如下:
public List<Map<String, Object>> parseXML(FTPFile fPath) { List<Map<String, Object>> parseList = new ArrayList<Map<String, Object>>(); String rtn = ""; Document document = null; InputStream ins = null; try { SAXReader saxreader = new SAXReader(); ins = this.ftpClient.retrieveFileStream(fPath.getName()); document = saxreader.read(ins); Element rootEle = document.getRootElement(); //<dataroot> //得到所有的一级子元素 List firstElements = rootEle.elements(); Iterator it = firstElements.iterator(); while(it.hasNext()){ //依次得到每一个一级子元素 Element firstElement = (Element) it.next(); //<YW_LZXX> //得到一级子元素下面的所有元素,及其附带值 List second_Elements=firstElement.elements(); Iterator second_Element=second_Elements.iterator(); Map<String, Object> map = new HashMap<String, Object>(); while(second_Element.hasNext()){ Element sec_Element=(Element)second_Element.next(); map.put(sec_Element.getName(), sec_Element.getText()); } parseList.add(map); } ftpClient.getReply(); } catch (Exception e) { log.error("xml解析失败", e); } finally { if(ins != null){ try { ins.close(); } catch (IOException e) { log.error("IO关闭失败", e); } } } return parseList; }