去年的时候 从刚到南京就开始做这个对账项目:

业务过程不方便说了,牵扯到的技术问题有以下几个:

1、java的socket传输

2、java的ftp主动方式传输

3、第三方提供的一个dll 做CA签名用的

4、java操作文件

5、java解析xml字符串

5、java更新数据库

=================================

主要就是以上的几个问题,因为刚参加工作不久,所以在经验上比较匮乏,走了不少的弯路,现在想想,很多简单的问题,

当时怎么就想的那么复杂呢!!!

反思反思!!!

=================================

首先,socket传输,这部分比较简单,只不过服务器端不是我写的,而且在socket的发送和接收的时候都需要进行一个简单的压缩加密、解密。所以,在传输的时候用简单的Buffer就不行了。

这一部分可以参见

http://hanbin.blog.51cto.com/1518861/879790

http://hanbin.blog.51cto.com/1518861/879788

这两篇文章 。。。

=================================

接下来说ftp传输,本来在最开始的时候 使用的一直以来一个比较成熟的FTP传输工具,但是在实际使用的时候发现这个工具不可以使用。后来才了解到ftp服务器的访问方式是主动方式。

后来使用了一个开源库:edtftpj

使用这个就比较方便了,比我自己写的好用太多了。

下面是FTP部分的代码:

  1. /*  
  2.   * To change this template, choose Tools | Templates  
  3.   * and open the template in the editor.  
  4.   */ 
  5.  package test;  
  6.    
  7.  import com.enterprisedt.net.ftp.FTPClient;  
  8.  import com.enterprisedt.net.ftp.FTPConnectMode;  
  9.  import com.enterprisedt.net.ftp.FTPMessageCollector;  
  10.  import com.enterprisedt.net.ftp.FTPTransferType;  
  11.  import com.enterprisedt.util.debug.Logger;  
  12.  import java.io.File;  
  13.  import java.io.FileInputStream;  
  14.  import java.io.FileOutputStream;  
  15.  import java.net.URL;  
  16.    
  17.  /**  
  18.   *  
  19.   * @author Icer  
  20.   */ 
  21.  public class FtpClient {  
  22.    
  23.      private FTPClient ftp = null;  
  24.    
  25.      public FTPClient connFtpServer(String host, int port, String username, String password) {  
  26.              ftp = new FTPClient();  
  27.          try {  
  28.                
  29.              ftp.setRemoteHost(host);  
  30.              ftp.setRemotePort(port);  
  31.              FTPMessageCollector listener = new FTPMessageCollector();  
  32.              ftp.setMessageListener(listener);  
  33.                
  34.              System.out.println("Connecting");  
  35.              ftp.connect();  
  36.    
  37.              System.out.println("Logging in");  
  38.              ftp.login(username, password);  
  39.                
  40.              System.out.println("Setting up passive,ASCII transfers");  
  41.              ftp.setConnectMode(FTPConnectMode.PASV);  
  42.              ftp.setType(FTPTransferType.ASCII);  
  43.                
  44.          } catch (Exception e) {  
  45.              e.printStackTrace();  
  46.          }  
  47.          return ftp;  
  48.      }  
  49.    
  50.      public void upload(String localfile, URL url) {  
  51.          String host = url.getHost();  
  52.          int port = url.getPort();  
  53.          File filePath = new File(url.getPath());  
  54.          String directory = filePath.getParent().substring(1);  
  55.          String filename = filePath.getName();  
  56.          try {  
  57.              ftp.chdir(directory);  
  58.              ftp.put(new FileInputStream(localfile), filename);  
  59.          } catch (Exception e) {  
  60.              e.printStackTrace();  
  61.              System.out.println("upload failed");  
  62.          }  
  63.      }  
  64.        
  65.        
  66.      public void upload(String localpath, String filename) {  
  67.          try {  
  68.              if(ftp.connected()){  
  69.               
  70.                 ftp.put(localpath, filename);  
  71.                 ftp.dir();  
  72.                   
  73.                  System.out.println("hello");  
  74.              } else {  
  75.                  System.out.println("wrong");  
  76.              }  
  77.                
  78.          } catch (Exception e) {  
  79.              System.out.println("upload failed");  
  80.              e.printStackTrace();  
  81.          }  
  82.      }  
  83.    
  84.      public void DownloadFile(String localpath,String filename) {  
  85.          try {  
  86.              ftp.chdir("");  
  87.              String[] files = ftp.dir(""true);  
  88.                
  89.              for (int i = 0; i < files.length; i++) {  
  90.                   
  91.                  System.out.println(files[i]);  
  92.                    
  93.                  ftp.get(new FileOutputStream(localpath + filename), filename);  
  94.                    
  95.              }  
  96.          } catch (Exception e) {  
  97.              e.printStackTrace();  
  98.              System.out.println("upload failed");  
  99.          }  
  100.      }  
  101.    
  102.      public void disConn() {  
  103.          try {  
  104.              ftp.quit();  
  105.          } catch (Exception e) {  
  106.              System.out.println("disconnection failed");  
  107.              e.printStackTrace();  
  108.          }  
  109.      }  
  110.       
  111.        
  112.      public static void main(String[] args) throws Exception{  
  113.           
  114.      }  
  115.  } 

再说CA签名的部分,因为这块第三方提供的DLL,用Java调用要用JNI重写DLL ,对VC那块不熟的我,就用.NET做了个守护程序,负责对两个文件夹里面的文件分别进行签名和签名认证,并将其结果分别写到一个文件中,供Java程序读取调用。

PS:在这个过程中,遇到了一个问题,会出现java程序和.NET这边的程序同时访问同一个文件的情况,就是那个签名结果文件。后来的时候,我将这个文件复制了一份,让java查找复制后的文件,如果找到,再回去找到源文件,这样就没有同时访问的问题了。

这部分,其实就是调用一下人家的函数,没啥技术含量,唯一一个就是用了下多线程来控制签名和认证的两个函数的运行。

=======================

Java操作文件:

这部分也不是什么大问题,主要就是文件的编码问题:在eclipse下好好的程序 放在netbeans下用的时候就出现了乱码,文件里的中文读出来乱码,所以文件头的包长也就计算不正确了。

后来,使用了这样的代码:

  1. /**  
  2.       * @parameter fileName 要读取的文件名  
  3.       * @return 文件内容  
  4.  */ 
  5.      public static String readFile(String fileName) {  
  6.          String context = "";  
  7.          File f = new File(fileName);  
  8.          BufferedReader bufReader = null;  
  9.          try {  
  10.              InputStreamReader isr = new InputStreamReader(new FileInputStream(fileName), "GBK");  
  11.              bufReader = new BufferedReader(isr);  
  12.              context = bufReader.readLine();  
  13.    
  14.          } catch (IOException ie) {  
  15.              ie.printStackTrace();  
  16.          } finally {  
  17.              try {  
  18.                  bufReader.close();  
  19.              } catch (Exception e) {  
  20.                  e.printStackTrace();  
  21.              }  
  22.          }  
  23.    
  24.          return context;  
  25.      } 

原来是直接用Reader去读的,比较悲惨。。。以后引以为戒,能自己设定编码的情况 一定自己hold住。。。

========================

关于Java解析xml的这部分,很大众的,用dom4j.

  1. import java.io.File;  
  2.  import java.io.FileWriter;  
  3.  import java.io.IOException;  
  4.  import java.io.Writer;  
  5.  import java.util.Iterator;  
  6.    
  7.  import org.dom4j.Document;  
  8.  import org.dom4j.DocumentException;  
  9.  import org.dom4j.DocumentHelper;  
  10.  import org.dom4j.Element;  
  11.  import org.dom4j.io.OutputFormat;  
  12.  import org.dom4j.io.SAXReader;  
  13.  import org.dom4j.io.XMLWriter;  
  14.    
  15.  /**  
  16.   * @author Icer  
  17.   */ 
  18.    
  19.  public class Dom4jDemo {  
  20.    
  21.      /**  
  22.       * 解析xml格式字符串  
  23.       * @return 对账文件名  
  24.  */ 
  25.      public String parseXmlName(String xml){  
  26.          System.out.println("接收到的字符串为:" + xml);  
  27.          String findFileName = "";  
  28.          try {  
  29.              Document document = DocumentHelper.parseText(xml);  
  30.              Element root = document.getRootElement();  
  31.              for (Iterator i = root.elementIterator(); i.hasNext();) {  
  32.                  Element head = (Element) i.next();  
  33.                  for (Iterator j = head.elementIterator(); j.hasNext();) {  
  34.                      Element elem = (Element) j.next();  
  35.                      for(Iterator k = elem.elementIterator();k.hasNext();){  
  36.                          Element data = (Element) k.next();  
  37.                          System.out.println(">>>"+data.getName() + ":" + data.getText());  
  38.                          if("DZJGWJM".equals(data.getName())){  
  39.                              findFileName = data.getText();  
  40.                          }  
  41.                      }  
  42.                  }  
  43.              }  
  44.          } catch (DocumentException e) {  
  45.              System.out.println(e.getMessage() + "hello");  
  46.          }  
  47.          System.out.println("dom4j parserXml");  
  48.          return findFileName;  
  49.      }  
  50.        
  51.      /**  
  52.       *  解析接收到的xml字符串   
  53.       * @param xml  
  54.       * @return 获得ca签名后的字符串  
  55.  */ 
  56.      public  String parseXmlCa(String xml){  
  57.          System.out.println("接收到的字符串为:" + xml);  
  58.          String ca = "";  
  59.          try {  
  60.              Document document = DocumentHelper.parseText(xml);  
  61.              Element root = document.getRootElement();  
  62.              for (Iterator i = root.elementIterator(); i.hasNext();) {  
  63.                  Element head = (Element) i.next();  
  64.                  for (Iterator j = head.elementIterator(); j.hasNext();) {  
  65.                      Element elem = (Element) j.next();  
  66.                      System.out.println(">>>"+elem.getName() + ":" + elem.getText());  
  67.                      for(Iterator k = elem.elementIterator();k.hasNext();){  
  68.                          Element data = (Element) k.next();  
  69.                          System.out.println(">>>"+data.getName() + ":" + data.getText());  
  70.                          if("CA".equals(data.getName())){  
  71.                              ca = data.getText();  
  72.                          }  
  73.                      }  
  74.                  }  
  75.              }  
  76.          } catch (DocumentException e) {  
  77.              System.out.println(e.getMessage() + "hello");  
  78.          }  
  79.          return ca;  
  80.      }  
  81.            
  82.          public int parseXmlStatus(String xml){  
  83.          int status = 0;  
  84.          try {  
  85.              Document document = DocumentHelper.parseText(xml);  
  86.              Element root = document.getRootElement();  
  87.              for (Iterator i = root.elementIterator(); i.hasNext();) {  
  88.                  Element head = (Element) i.next();  
  89.                  for (Iterator j = head.elementIterator(); j.hasNext();) {  
  90.                      Element elem = (Element) j.next();  
  91.                      System.out.println(">>>"+elem.getName() + ":" + elem.getText());  
  92.                                          if("STATUS".equals(elem.getName())){  
  93.                                              status = Integer.parseInt(elem.getTextTrim());  
  94.                                          }  
  95.                  }  
  96.              }  
  97.          } catch (DocumentException e) {  
  98.              System.out.println(e.getMessage() + "hello");  
  99.          }  
  100.          return status;  
  101.          } 

更新数据库这部分就更没什么技术价值了。事务更新。地球人都懂,就不献丑了。。。

 

=====================

上面的代码均为测试代码,注释什么的都不全,凑合着看了。。。