EBS中利用Socket与外系统通信

某银行要求做一个签到签退功能,日终EBS系统发送报文与核心系统对帐,规定利用Socket来做传送,记录下步骤:

1、编辑: $INST_TOP/ora/10.1.3/j2ee/oacore/application-deployments/oacore/html/orion-web.xml ($ORA_CONFIG_HOME/10.1.3/j2ee/oacore/application-deployments/oacore/html/orion-web.xml) 添加Servlet映射,同时需要编辑:$FND_TOP/admin/template/orion_web_xml_1013.tmp这个配套的模板, 以避免做autocfg时配置丢失,示例内容如下:

<!-- Socket mapping by huangrx 20130101-->
<servlet>
  <servlet-name>xxtServlet</servlet-name>
  <servlet-class>xxt.oracle.apps.gl.chk.server.xxtServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>xxtServlet</servlet-name>
  <url-pattern>/xxtServlet</url-pattern>
</servlet-mapping>

2、 在xxtServlet类的init方法中添加Socket调用,值得注意的是,如果单独在该Servelt的init()方法中编写Server端代码,并进行监听, 会造成Tomcat或其他Web服务器启动超时, 正确的做法应该是单独写一个监听处理线程类,然后在init()中,用多线程的方式来启动该线程:

xxtServlet

package xxt.oracle.apps.gl.chk.server;

import java.io.IOException;

import java.lang.Runnable;
import java.lang.Thread;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

publicclass xxtServlet extendsHttpServlet
{
  privatestaticfinallong serialVersionUID =1L;
  private xxtSocketServer socket =null;

  public xxtServlet()
  {
    super();
  }

  // Init Method
  publicvoid init(ServletConfig config)throwsServletException
  {
    super.init(config);

    // 线程调起服务
    newThread(newSocketRunnable()).start();
  }

  // Get Method

  protectedvoid doGet(HttpServletRequest request,
                       HttpServletResponse response)throwsServletException,
                                                            IOException
  {
    System.out.println("***************ServletServer doGet");
  }

  // Post Method

  protectedvoid doPost(HttpServletRequest request,
                        HttpServletResponse response)throwsServletException,
                                                             IOException
  {
    System.out.println("***************ServletServer doPost");
  }

  privateclassSocketRunnableimplementsRunnable
  {
    publicvoid run()
    {
      try
      {
        // xxtSocketServer中处理Socket
        socket =new xxtSocketServer();
      }catch(IOException e)
      {
        e.printStackTrace();
      }
      socket.service();
      System.out.println("***************Load on start");
    }
  }
}

xxtSocketServer

package xxt.oracle.apps.gl.chk.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import java.net.ServerSocket;
import java.net.Socket;

import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

publicclass xxtSocketServer
{

  privateServerSocket serverSocket;
  privateExecutorService executorService;
  privatefinalint POOL_SIZE =10;

  privatestaticProperties prop =newProperties();
  static{
    try
    {
      prop.load(xxtDBConn.class.getResourceAsStream("config.properties"));
    }catch(IOException e)
    {
      System.out.println("File:config.properties no find,PLS check out!");
      e.printStackTrace();
    }
  }
  privatestaticint EBS_PORT =Integer.parseInt(prop.getProperty("ebs_port")); 

  // 报文头5位
  publicstaticString getString(String src)
  {
    while(src.length()<5)
    {
      src = "0" + src;
    }
    return src;
  }

  public xxtSocketServer()throwsIOException
  {
    try
    {
      serverSocket = newServerSocket(EBS_PORT);
      executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()* POOL_SIZE);
    }catch(IOException e)
    {
      e.printStackTrace();
    }

  }

  publicvoid service()
  {
    while(true)
    {
      Socket socket =null;
      try
      {
        socket = serverSocket.accept();
        // new Handler(socket);
        executorService.execute(newHandler(socket));
      }catch(Exception e)
      {
        e.printStackTrace();
      }
    }
  }
 
  /////////////////////////////////////////////////////////
  publicstaticvoid main(String[] args)throwsIOException
  {
    new xxtSocketServer().service();
  } 

  privateclassHandlerimplementsRunnable
  {

    privateSocket socket;
    privateBufferedReader br =null;
    privatePrintWriter pw =null;

    privateint bit;
    privateString endTag ="</of>";

    /**
     * @param socket
     */
    publicHandler(Socket socket)
    {
      this.socket = socket;
      System.out.println("******************Server Start**********************");

    }

    publicvoid run()
    {
      try
      {
        /*
         * System.out.println("New connection accepted " + socket.getInetAddress() + ":" + socket.getPort()); 
* pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); */ br = newBufferedReader(newInputStreamReader(socket.getInputStream())); pw = newPrintWriter(socket.getOutputStream()); String msg =""; /* * while ((msg = br.readLine()) != null) { * System.out.println("Receive From Client:" + msg); * pw.println(msg);
* pw.flush();
* if (msg.length() != msg.replaceAll(endTag, "").length())
* { break; }
*} */ while((bit = br.read())!=-1) { char chr =(char)bit; msg +=String.valueOf(chr); endTag =(endTag +String.valueOf(chr)).substring(1); if(endTag !=null&&endTag.equals("</of>")) { break; } } String str =""; if(msg.trim()==null|| msg.trim().equals("")) { str ="00105<of><checkd></checkd><cnt></cnt><detail><acctno></acctno><onlnbl></onlnbl><blncdn></blncdn></detail></of>"; } else { xxtXMLServer.parseStringXml(msg.trim()); str = xxtXMLServer.createXML(xxtXMLServer.getHashMap()); str = getString(str.length() + "" ) + str; } System.out.println("Server Return Xml:"+ str); pw.write(str); pw.flush(); }catch(Exception e) { e.printStackTrace(); }finally { try { System.out.println("******************Server Close**********************"); if(br !=null) br.close(); if(pw !=null) pw.close(); if(socket !=null) socket.close(); }catch(IOException e) { e.printStackTrace(); } } } } }

由于是初稿,代码没做优化,目前遇到的问题是,在停止应用时要停两次才能结束,还未找到解决方法。
在网络上摘抄另一种多线程调用的方法:

publicvoid init(ServletConfig config){
       newThread(){
             publicvoid run(){
                   try{
                         ServerSocket server =newServerSocket(1234);
                         Socket socket =null;
                         while(true){
                              socket = server.accept();
                              SocketServer sServer =newSocketServer(socket);
                              sServer.start();
                        }
                  }catch(IOException e){
                        System.out.println(e.getMessage());
                  }
            }
      }.start();
}

publicclassSocketServerextendsThread{
       privateSocket socket;

       publicSocketServer(Socket socket){
             this.socket = socket;
      }

       publicvoid run(){
            String output ="";
             try{
                  BufferedReaderis=newBufferedReader(newInputStreamReader(socket.getInputStream()));
                  PrintWriter os =newPrintWriter(socket.getOutputStream());
                  String line =null;
                  line =is.readLine();
                  System.out.println(line);
                  output ="server send";
                  os.println(output);
                  os.flush();
                  is.close();
                  os.close();
                   socket.close();
            }catch(IOException e){
                  e.printStackTrace();
            }
      }
}

R12中System.out的信息及抛出的异常信息可查看:
$LOG_HOME/ora/10.1.3/opmn/oacore_default_group_1中的oacorestd.err和oacorestd.out这两个文件以更精确定位,当然也可以用log4j或自定义类来捕捉。
另外,由于核心系统是用C语言开发,在Java SocketServer端不使用字节来read而使用br.readline()时,就直接卡住了,一种解决方法是在Client端发送的数据后面加上chr(13).chr(10)表示先回车再换行,将其转换成java能够识别的格式就没有问题了。

posted @ 2013-08-30 15:19  新新向荣  阅读(531)  评论(0编辑  收藏  举报