1.主要是为了加强对SOAP远程方法调用的学习,特意自己写了一个SOAP Client端.
2.要求环境:JDK1.6 以上,Axis2 以上
3.主要代码

 

  1. package com.googlecode.soap.client;   
  2.    
  3. import java.io.ByteArrayOutputStream;   
  4. import java.io.IOException;   
  5. import java.io.InputStream;   
  6. import java.io.OutputStream;   
  7. import java.io.PrintStream;   
  8. import java.net.Socket;   
  9. import java.net.URL;   
  10.    
  11. import com.googlecode.soap.client.SoapResponse.Status;   
  12. import com.googlecode.soap.util.ExecuteThreadPool;   
  13.    
  14. public class SoapServiceClient {   
  15.    
  16.     private String address;   
  17.    
  18.     private String namespace;   
  19.    
  20.         
  21.     public static long MAX_TIME_OUT = 10000; // 10秒    
  22.    
  23.     private SoapResponse response;   
  24.    
  25.     static ExecuteThreadPool executor = new ExecuteThreadPool(5);   
  26.         
  27.     public final Object lock = new Object();   
  28.    
  29.      URL url = null;   
  30.         
  31.      Socket socket = null;   
  32.            
  33.     private void init(SoapRequest request){   
  34.         this.response = null;    
  35.         request.context = this;   
  36.     }   
  37.        
  38.     public SoapServiceClient(String address) throws Exception, IOException {   
  39.         this.address = address;   
  40.         if (!this.address.endsWith("?wsdl")) {   
  41.             thisthis.address = this.address + "?wsdl";   
  42.         }   
  43.         this.url = new URL(this.address);   
  44.         socket = new Socket(url.getHost(), url.getPort());   
  45.     }   
  46.    
  47.     public String getNamespace() {   
  48.         return namespace;   
  49.     }   
  50.    
  51.     public void setNamespace(String namespace) {   
  52.         this.namespace = namespace;   
  53.     }   
  54.    
  55.     public void sendRequest(final SoapRequest request) {   
  56.            
  57.         this.init(request);   
  58.         // 多线程环境下发送   
  59.         executor.execute(new Runnable() {   
  60.    
  61.             public void run()  {   
  62.                    
  63.                 OutputStream os = null;   
  64.                 InputStream input = null;   
  65.                 PrintStream ps = null;   
  66.                 ByteArrayOutputStream bos = null;   
  67.                 try {   
  68.                     String send = request.toString();   
  69.                     if( socket.isClosed()) {   
  70.                       socket = new Socket(url.getHost(), url.getPort());   
  71.                     }   
  72.                     socket.setSoTimeout((int)MAX_TIME_OUT);   
  73.                     os = socket.getOutputStream();   
  74.                     ps = new PrintStream(os, true, request.getCode());   
  75.                     ps.println(send);   
  76.                     input = socket.getInputStream();   
  77.                     int available = input.available();   
  78.                     if (available <= 0) {   
  79.                              long currentSystem.currentTimeMillis();    
  80.                              for(;;){    
  81.                                  input = socket.getInputStream();   
  82.                                  available = input.available();   
  83.                                  if(available  > 0 ) {   
  84.                                      break;    
  85.                                  }   
  86.                                  if(System.currentTimeMillis()-current >= MAX_TIME_OUT ) {    
  87.                                      synchronized(lock) {   
  88.                                           response = new SoapResponse("TimeOut Exception", Status.TIMEOUT,null);   
  89.                                           
  90.                                           return ;   
  91.                                      }   
  92.                                 }   
  93.                              }   
  94.                      }   
  95.                     bos = new ByteArrayOutputStream();   
  96.                     byte[] buffer = new byte[256];   
  97.                     int totalRead = 0;   
  98.                     while (true) {   
  99.                         int nRead = input.read(buffer);   
  100.                         totalRead += nRead;   
  101.                         bos.write(buffer, 0, nRead);   
  102.                         if (totalRead >= available) {   
  103.                             break;   
  104.                         }   
  105.                     }   
  106.                     String responseString = bos.toString(request.getCode());   
  107.                     System.out.println("response=\r\n" + responseString);   
  108.                     synchronized(lock) {   
  109.                        response = new SoapResponse(responseString,request.getInvocation().getReturnType());   
  110.                          
  111.                     }   
  112.                 } catch (Exception e) {   
  113.                     e.printStackTrace();   
  114.                     synchronized(lock) {   
  115.                       response = new SoapResponse("RequestError", Status.ServerError,null);   
  116.                        
  117.                     }   
  118.                 }  finally {   
  119.                     try {   
  120.                         if (ps != null) {   
  121.                             ps.close();   
  122.                         }   
  123.                         if (os != null) {   
  124.                             os.close();   
  125.                         }   
  126.                         if (input != null) {   
  127.                             input.close();   
  128.                         }   
  129.                         if (bos != null) {   
  130.                             bos.close();   
  131.                         }   
  132.                         if (socket != null) {   
  133.                             socket.close();   
  134.                         }   
  135.    
  136.                     } catch (Exception e) {   
  137.                         e.printStackTrace();   
  138.                     } finally {   
  139.                         ps = nullos =nullinput = nullbos =null;    
  140.                     }   
  141.                 }   
  142.             }   
  143.         });   
  144.    
  145.     }   
  146.    
  147.     public SoapResponse getResponse() {   
  148.     if (this.response == null) {   
  149.             long current = System.currentTimeMillis();   
  150.             for (;;) {   
  151.                 if (System.currentTimeMillis() - current >= MAX_TIME_OUT) {   
  152.                     synchronized (lock) {   
  153.                         return this.response;   
  154.                     }   
  155.                 }   
  156.                 if (this.response != null) {   
  157.                     synchronized (lock) {   
  158.                         return this.response;   
  159.                     }   
  160.                 }   
  161.             }   
  162.         }   
  163.         synchronized (lock) {   
  164.             return this.response;   
  165.         }   
  166.            
  167.    
  168.     }   
  169.    
  170.        
  171.    
  172. }   
  173.  
  174. ackage com.googlecode.soap.util;   
  175.    
  176. import java.util.HashSet;   
  177. import java.util.Iterator;   
  178. import java.util.concurrent.BlockingQueue;   
  179. import java.util.concurrent.Executor;   
  180. import java.util.concurrent.LinkedBlockingQueue;   
  181. import java.util.concurrent.TimeUnit;   
  182. import java.util.concurrent.locks.ReentrantLock;   
  183.    
  184. public class ExecuteThreadPool implements Executor {   
  185.    
  186.     private final int maxPoolSize ;   
  187.        
  188.     private long idelTime = 0 ;   
  189.        
  190.     private int realSize = 0 ;   
  191.        
  192.     //线程池是否关?   
  193.     private boolean poolClosed = false;   
  194.        
  195.     private final HashSet<Worker> workers = new HashSet<Worker>();   
  196.    
  197.     private final ReentrantLock mainLock = new ReentrantLock();   
  198.    
  199.    //工作队列   
  200.     private final BlockingQueue<Runnable> workQueue  = new LinkedBlockingQueue<Runnable>();;   
  201.    
  202.     public ExecuteThreadPool(int maxPoolSize) {   
  203.         this.maxPoolSize = maxPoolSize;   
  204.     }   
  205.        
  206.     /**  
  207.      * @param maxPoolSize int 线程池中可用的线程的大小  
  208.      * @param idelTime 单位毫秒,当线程池所有的线程忙的时??  
  209.      *                 ?等待的时?超出这个等待时间,抛出异?  
  210.      *     
  211.      * */   
  212.     public ExecuteThreadPool(int poolSize,long idelTime) {   
  213.         this.maxPoolSize = poolSize;   
  214.         this.idelTime =  idelTime;   
  215.     }   
  216.        
  217.     @Override    
  218.     public void execute(Runnable command) {   
  219.         if (command == null) {   
  220.             throw new IllegalArgumentException("command argument can't be null");   
  221.         }   
  222.         if(this.poolClosed) {   
  223.             throw new RuntimeException("Current pool was closed.");   
  224.         }   
  225.         //线程池还没有满,新建线程直接运行   
  226.         if (realSize < maxPoolSize) {    
  227.             this.newThread(command).start();   
  228.         } else {    
  229.         //主线程负责workQueue工作队列。准备战斗   
  230.             this.workQueue.offer(command);      
  231.         }   
  232.     }   
  233.        
  234.     //强制关闭线程   
  235.     public void shutdown(){   
  236.          this.mainLock.lock();   
  237.          Iterator<Worker> it  = workers.iterator();   
  238.          while(it.hasNext()) {   
  239.                  Worker w = it.next();   
  240.                  ww.status = w.exited;   
  241.                  w.shutdown();    
  242.           }   
  243.          workers.clear();   
  244.          workQueue.clear();   
  245.          this.poolClosed = true;    
  246.          this.mainLock.unlock();   
  247.     }   
  248.    
  249.     private Thread newThread(Runnable command){   
  250.         //用Worker来封?command,因为Worker也继承Runnable.   
  251.         Worker worker = new Worker(command);   
  252.         Thread t = new Thread(worker);    
  253.         worker.thread = t;   
  254.         thisthis.realSize = this.realSize + 1;   
  255.         t.setName("pool-" + this.realSize);   
  256.         workers.add(worker);   
  257.         return t;   
  258.     }   
  259.    
  260.     // 线程工作执行   
  261.     private class Worker implements Runnable {   
  262.            
  263.         //已准备   
  264.         public final int  ready = 1;   
  265.            
  266.         //在工作   
  267.         public final int  working = 2;   
  268.            
  269.         //在等待   
  270.         public final int  waiting = 3;   
  271.            
  272.         //已退出   
  273.         public final int  exited = 4;   
  274.            
  275.         //当前线程工作执行者的状态,默认是 ready   
  276.         public int status = ready;   
  277.    
  278.         private final ReentrantLock runLock = new ReentrantLock();   
  279.    
  280.         private Runnable task;   
  281.    
  282.         Thread thread = null;   
  283.        
  284.         Worker( Runnable task) {   
  285.             this.task = task;   
  286.             thisthis.status = this.ready;    
  287.         }    
  288.            
  289.         @Override   
  290.         public void run() {   
  291.             Runnable runTask = this.task;   
  292.             for (;;) {   
  293.                 if (runTask != null) {   
  294.                 try {   
  295.                        this.runTask(runTask);   
  296.                      } catch (RuntimeException e) {   
  297.                          ;   
  298.                      }   
  299.                      runTask = null;   
  300.                 }   
  301.                 try {   
  302.                      runTask = getTask();   
  303.                     } catch (InterruptedException ie) {   
  304.                          thisthis.status = this.exited;   
  305.                          break;   
  306.                    }   
  307.             }   
  308.         }   
  309.    
  310.         void shutdown(){   
  311.              if ( thread != Thread.currentThread()) {   
  312.                     thread.interrupt();   
  313.              }   
  314.         }   
  315.            
  316.         private void runTask(Runnable task) {   
  317.             try {   
  318.                  final ReentrantLock runLock = this.runLock;   
  319.                  runLock.lock();   
  320.                  thisthis.status = this.working;    
  321.                  task.run();   
  322.                } catch (Exception e) {   
  323.                  throw new RuntimeException(e);   
  324.                } finally {   
  325.                  runLock.unlock();   
  326.                }   
  327.         }   
  328.    
  329.         private Runnable getTask() throws InterruptedException {   
  330.             for (;;) {   
  331.                 Runnable task = null;   
  332.                 //工作队列非空,直接调用poll方法获取.   
  333.                 if (!workQueue.isEmpty()) {   
  334.                     task = workQueue.poll();   
  335.                 } else {   
  336.                     try {   
  337.                         //如果设置了idelTime 的?,调用poll方法获取元素,超出idelTime时间,抛?InterruptedException   
  338.                         if( idelTime != 0L ) {   
  339.                             task = workQueue.poll(idelTime, TimeUnit.MILLISECONDS);   
  340.                         } else {    
  341.                         //Worker线程负责获取方法,从工作队列头获取对象并删除队列中要获取的对象,如果队列为空,一直等?   
  342.                             task = workQueue.take();   
  343.                         }    
  344.                     } catch (InterruptedException e) {   
  345.                             throw e;   
  346.                     } catch(Exception e) {   
  347.                             ;   
  348.                     }   
  349.                }   
  350.                if (task != null) {   
  351.                     return task;   
  352.                }   
  353.                thisthis.status = this.waiting;   
  354.           }   
  355.        }   
  356.            
  357.     }   
  358. }   
  359.  
  360. ackage com.googlecode.soap.util;   
  361.    
  362. import java.lang.reflect.Field;   
  363.    
  364. public final class XmlUnitl {   
  365.    
  366.     public static final String SPACE_CHAR = "";   
  367.    
  368.     public static final String LEFT_SEQ = "<";   
  369.    
  370.     public static final String RIGHT_SEQ = ">";   
  371.    
  372.     public static String toXml(Object object) {   
  373.         if (object == null) {   
  374.             return SPACE_CHAR;   
  375.         }   
  376.         if (object.getClass().getName().equals(String.class.getName())) {   
  377.             return object.toString();   
  378.         } else if (object.getClass().getName().equals(Integer.class.getName())) {   
  379.             return object.toString();   
  380.         } else if (object.getClass().getName().equals(Float.class.getName())) {   
  381.             return object.toString();   
  382.         } else if (object.getClass().getName().equals(Double.class.getName())) {   
  383.             return object.toString();   
  384.         } else if (object.getClass().getName().equals(Long.class.getName())) {   
  385.             return object.toString();   
  386.         } else if (object.getClass().getName().equals(Long.class.getName())) {   
  387.             return object.toString();   
  388.         }   
  389.         Field fields[] = object.getClass().getDeclaredFields();   
  390.         if (fields == null || fields.length == 0) {   
  391.             return SPACE_CHAR;   
  392.         }   
  393.         StringBuffer buffer = new StringBuffer();   
  394.         for (Field field : fields) {   
  395.             String name = field.getName();   
  396.             field.setAccessible(true);   
  397.             try {   
  398.                 Object value = field.get(object);   
  399.                 if (value != null) {   
  400.                     buffer.append(LEFT_SEQ + name + RIGHT_SEQ + value   
  401.                             + LEFT_SEQ + "/" + name + RIGHT_SEQ);   
  402.                 }   
  403.    
  404.             } catch (Exception e) {   
  405.                 ;   
  406.             }   
  407.         }   
  408.         return buffer.toString();   
  409.     }   
  410.    
  411. }   
  412.  
  413. package com.googlecode.soap.test;   
  414.    
  415. import java.io.BufferedReader;   
  416. import java.io.InputStreamReader;   
  417.    
  418. import com.googlecode.soap.client.MethodInvocation;   
  419. import com.googlecode.soap.client.SoapRequest;    
  420. import com.googlecode.soap.client.SoapResponse;   
  421. import com.googlecode.soap.client.SoapServiceClient;   
  422.    
  423. public class SoapTest {   
  424.         
  425.         
  426.     public static void main(String[] args) throws Exception {    
  427.         SoapServiceClient client = new SoapServiceClient("http://www.nicaipu.com:8099/axis2/services/SimpleService?wsdl");   
  428.         MethodInvocation method = new MethodInvocation("getPrice",new Object[]{44},null);    
  429.         SoapRequest request = new SoapRequest(method);    
  430.         request.setCode("utf-8");     
  431.         //client.setNamespace("http://webservice.chapter1.book/client");   
  432.         BufferedReader systemIn=new BufferedReader(new InputStreamReader(System.in));   
  433.         boolean flag=true;   
  434.         while(flag){   
  435.             String command=systemIn.readLine();   
  436.             if( command==null || "quit".equalsIgnoreCase(command.trim())){   
  437.                 flag=false;   
  438.                 System.out.println("Client quit!");   
  439.                 continue;    
  440.             } else if( "send".equalsIgnoreCase(command.trim())) {   
  441.                 System.out.println("send command..");   
  442.                 client.sendRequest(request);       
  443.                 SoapResponse response = client.getResponse();   
  444.                 System.out.println(response.getObject());   
  445.             }   
  446.                 
  447.         }   
  448.        
  449.     }   
  450.        
  451. }   

 

4.测试
4.1 先把 SimpleService.class和People.class发布到$AXIS_HOME$\WEB-INF\pojo\下,启动Axis2
4.2 运行 SoapTest,在控制台下输入send,即可测试