SOAP客户端

1.主要是为了加强对SOAP远程方法调用的学习,特意自己写了一个SOAP Client端.
2.要求环境:JDK1.6 以上,Axis2 以上
3.主要代码
[b]3.1 SimpleService类[/b]
import java.util.ArrayList;
import java.util.List;

public class SimpleService {

public String getGreeting(String name) {

long time = System.currentTimeMillis();

try {

Thread.sleep(19000);

} catch (Exception e) {

}
long cost = System.currentTimeMillis() - time;
System.out.println("cost " + cost);
return "你好 " + name;
}

public int getException(){
System.out.println("getException");
if(true){
throw new RuntimeException("Exception");
}
return -1;
}

public int getPrice(int price) {
System.out.println("getPrice");
return price*2;
}

public float getFloatPrice(float price) {
System.out.println("getFloatPrice");
return price*2.0f;
}

public People getPeople() {
return new People("zhangkunlie", "boy");
}


public People[] getPeoples() {
People peoples[] = new People[3];
peoples[0] = new People("zhangkunlie", "boy");
peoples[1] = new People("xiaoniu", "girl");
peoples[2] = new People(null, "girl");
return peoples;
}


public List<People> getPeopleList() {
People peoples[] = new People[3];
peoples[0] = new People("zhangkunlie", "boy");
peoples[1] = new People("xiaoniu", "girl");
peoples[2] = new People(null, "girl");
List<People> list = new ArrayList<People>();
for (int j = 0; j < peoples.length; j++) {
list.add(peoples[j++]);
}

return list;
}



public void sayHi(){
System.out.println("sayHi");
}



}

[b]3.2 MethodInvocation类[/b]
package com.googlecode.soap.client;

public class MethodInvocation {

private String methodName;


private Object[] arugments;

private Class returnType;


public MethodInvocation(String methodName,Object[] arugments,Class returnType){
this.methodName = methodName;
this.arugments = arugments;
this.returnType =returnType;
}



public String getMethodName() {
return methodName;
}

public void setMethodName(String methodName) {
this.methodName = methodName;
}

public Object[] getArugments() {
return arugments;
}

public void setArugments(Object[] arugments) {
this.arugments = arugments;
}

public Class getReturnType() {
return returnType;
}

public void setReturnType(Class returnType) {
this.returnType = returnType;
}


}

[b]3.3 SoapEnvelope类[/b]
[code]package com.googlecode.soap.client;

import com.googlecode.soap.util.XmlUnitl;

class SoapEnvelope {

public static final String xmlns_soapenv = "http://schemas.xmlsoap.org/soap/envelope/";

public static final String default_namespace_uri = "http://ws.apache.org/axis2";

public String namespaceUri;


public SoapRequest requestContext;


public SoapRequest getRequestContext() {
return requestContext;
}


public void setRequestContext(SoapRequest requestContext) {
this.requestContext = requestContext;
}


public SoapEnvelope(String namespaceUri){
this.namespaceUri = namespaceUri;
}


public SoapEnvelope(){
this.namespaceUri = this.default_namespace_uri;
}



public String getNamespaceUri() {
if( namespaceUri == null ) {
this.namespaceUri = default_namespace_uri;
}
return namespaceUri;
}

public void setNamespaceUri(String mh) {
this.namespaceUri = mh;
}

String getBegin(){
return "<soapenv:Envelope xmlns:soapenv=\""+xmlns_soapenv+"\" xmlns:mh=\"" + this.getNamespaceUri()+ "\"><soapenv:Body>";
}

String getEnd(){
return "</soapenv:Body></soapenv:Envelope>\r\n";
}

String getBody(){
MethodInvocation invocation = this.requestContext.getInvocation();
StringBuffer buffer = new StringBuffer("<mh:"+invocation.getMethodName()+">");
for (int i = 0; invocation.getArugments() != null
&& i < invocation.getArugments().length; i++) {
buffer.append("<arg"+i+">"+XmlUnitl.toXml(invocation.getArugments()[i])+"</arg"+i+">");
}
buffer.append("</mh:"+invocation.getMethodName()+">");
return buffer.toString();
}

public String getEnvelopeContent(){
return this.getBegin() + this.getBody()+ this.getEnd();
}


}
[/code]
[b]3.4 SoapRequest类[/b]
[code]package com.googlecode.soap.client;

public class SoapRequest {

SoapServiceClient context;

private MethodInvocation invocation;

private String code;

public final static String defualt_code ="utf-8";

public SoapServiceClient getContext() {
return context;
}

public SoapRequest(MethodInvocation invocation) {
this.invocation = invocation;
}

public MethodInvocation getInvocation() {
return this.invocation;
}

public String getCode() {
return code==null ? defualt_code:code;
}

public void setCode(String code) {
this.code = code;
}

public String toString(){

SoapEnvelope envelope = (context.getNamespace() == null) ? new SoapEnvelope(): new SoapEnvelope(context.getNamespace());
envelope.setRequestContext(this);
String content = envelope.getEnvelopeContent();
return "POST " + context.url.getPath() + " HTTP/1.1\r\n"
+ "Host: "+ context.url.getHost() + ":" + context.url.getPort() + "\r\n"
+ "Content-Type: text/xml; charset="+this.getCode()+"\r\n"
+ "Connection: close\r\n"
+ "Content-Length: "+ (content.length() + (2 * 2)) + "\r\n"
+ "SOAPAction: \042\042\r\n" + "\r\n" + content;
}

}
[/code]
[b]3.5 SoapResponse类[/b]
[code]package com.googlecode.soap.client;

public class SoapResponse {

public enum Status {

OK(1, "OK"), ServerError(2, "ServerError"), TIMEOUT(3, "TIMEOUT");

public String detail;

int status;

Status(int status, String detail) {
this.status = status;
this.detail = detail;
}
};

private Status status;

private String text;

private String serverVersion;

private Object object;

Class returnType;

SoapResponse(String text,Class returnType){
this(text, Status.OK, returnType);
}

SoapResponse(String text,Status status,Class returnType){
this.text = text;
this.status = status;
this.returnType =returnType;
this.object = this.text;
this.parse();
}

public Object getObject(){
return object;
}

public Status getStatus(){
return this.status;
}


private void parse() {
if (this.status != Status.OK) {
return;
}
String texts[] = this.text.split("\r\n");
if (texts.length < 7) {
return;
}
String text0 = texts[0];
if( text0.contains("OK") ) {
this.status = Status.OK;
String soapText = texts[texts.length - 1];
if (soapText == null || soapText.length() == 0) {
return;
}
if( returnType == String.class ) {
int begin =soapText.indexOf("<return>")+"<return>".length();
int end = soapText.indexOf("</return>");
if( end <=0){ return; }
String returnstring = soapText.substring(begin,end);
this.object = returnstring;
}

} else if ( text0.contains("Accepted") ){
;
} else {
String soapText = texts[texts.length - 1];
if ( soapText == null || soapText.length() == 0) {
return;
}
int begin =soapText.indexOf("<faultstring>")+"<faultstring>".length();
int end = soapText.indexOf("</faultstring>");
if( end <=0){ return; }
String faultstring = soapText.substring(begin,end);
this.status = Status.ServerError;
this.object = this.status.detail = faultstring ;
}
this.serverVersion = texts[1].split(":")[1];
}


public String getServerVersion() {
return serverVersion;
}

public void setServerVersion(String serverVersion) {
this.serverVersion = serverVersion;
}





}
[/code]
[b]3.6 SoapServiceClient类[/b]
[code]package com.googlecode.soap.client;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.URL;

import com.googlecode.soap.client.SoapResponse.Status;
import com.googlecode.soap.util.ExecuteThreadPool;

public class SoapServiceClient {

private String address;

private String namespace;


public static long MAX_TIME_OUT = 10000; // 10秒

private SoapResponse response;

static ExecuteThreadPool executor = new ExecuteThreadPool(5);

public final Object lock = new Object();

URL url = null;

Socket socket = null;

private void init(SoapRequest request){
this.response = null;
request.context = this;
}

public SoapServiceClient(String address) throws Exception, IOException {
this.address = address;
if (!this.address.endsWith("?wsdl")) {
this.address = this.address + "?wsdl";
}
this.url = new URL(this.address);
socket = new Socket(url.getHost(), url.getPort());
}

public String getNamespace() {
return namespace;
}

public void setNamespace(String namespace) {
this.namespace = namespace;
}

public void sendRequest(final SoapRequest request) {

this.init(request);
// 多线程环境下发送
executor.execute(new Runnable() {

public void run() {

OutputStream os = null;
InputStream input = null;
PrintStream ps = null;
ByteArrayOutputStream bos = null;
try {
String send = request.toString();
if( socket.isClosed()) {
socket = new Socket(url.getHost(), url.getPort());
}
socket.setSoTimeout((int)MAX_TIME_OUT);
os = socket.getOutputStream();
ps = new PrintStream(os, true, request.getCode());
ps.println(send);
input = socket.getInputStream();
int available = input.available();
if (available <= 0) {
long current= System.currentTimeMillis();
for(;;){
input = socket.getInputStream();
available = input.available();
if(available > 0 ) {
break;
}
if(System.currentTimeMillis()-current >= MAX_TIME_OUT ) {
synchronized(lock) {
response = new SoapResponse("TimeOut Exception", Status.TIMEOUT,null);

return ;
}
}
}
}
bos = new ByteArrayOutputStream();
byte[] buffer = new byte[256];
int totalRead = 0;
while (true) {
int nRead = input.read(buffer);
totalRead += nRead;
bos.write(buffer, 0, nRead);
if (totalRead >= available) {
break;
}
}
String responseString = bos.toString(request.getCode());
System.out.println("response=\r\n" + responseString);
synchronized(lock) {
response = new SoapResponse(responseString,request.getInvocation().getReturnType());

}
} catch (Exception e) {
e.printStackTrace();
synchronized(lock) {
response = new SoapResponse("RequestError", Status.ServerError,null);

}
} finally {
try {
if (ps != null) {
ps.close();
}
if (os != null) {
os.close();
}
if (input != null) {
input.close();
}
if (bos != null) {
bos.close();
}
if (socket != null) {
socket.close();
}

} catch (Exception e) {
e.printStackTrace();
} finally {
ps = null; os =null; input = null; bos =null;
}
}
}
});

}

public SoapResponse getResponse() {
if (this.response == null) {
long current = System.currentTimeMillis();
for (;;) {
if (System.currentTimeMillis() - current >= MAX_TIME_OUT) {
synchronized (lock) {
return this.response;
}
}
if (this.response != null) {
synchronized (lock) {
return this.response;
}
}
}
}
synchronized (lock) {
return this.response;
}


}



}
[/code]
[b]3.7 ExecuteThreadPool工具类[/b]
[code]package com.googlecode.soap.util;

import java.util.HashSet;
import java.util.Iterator;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

public class ExecuteThreadPool implements Executor {

private final int maxPoolSize ;

private long idelTime = 0 ;

private int realSize = 0 ;

//线程池是否关�?
private boolean poolClosed = false;

private final HashSet<Worker> workers = new HashSet<Worker>();

private final ReentrantLock mainLock = new ReentrantLock();

//工作队列
private final BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>();;

public ExecuteThreadPool(int maxPoolSize) {
this.maxPoolSize = maxPoolSize;
}

/**
* @param maxPoolSize int 线程池中可用的线程的大小
* @param idelTime 单位毫秒,当线程池所有的线程忙的时�?�?
* �?��等待的时�?超出这个等待时间,抛出异�?
*
* */
public ExecuteThreadPool(int poolSize,long idelTime) {
this.maxPoolSize = poolSize;
this.idelTime = idelTime;
}

@Override
public void execute(Runnable command) {
if (command == null) {
throw new IllegalArgumentException("command argument can't be null");
}
if(this.poolClosed) {
throw new RuntimeException("Current pool was closed.");
}
//线程池还没有满,新建线程直接运行
if (realSize < maxPoolSize) {
this.newThread(command).start();
} else {
//主线程负责workQueue工作队列。准备战斗
this.workQueue.offer(command);
}
}

//强制关闭线程
public void shutdown(){
this.mainLock.lock();
Iterator<Worker> it = workers.iterator();
while(it.hasNext()) {
Worker w = it.next();
w.status = w.exited;
w.shutdown();
}
workers.clear();
workQueue.clear();
this.poolClosed = true;
this.mainLock.unlock();
}

private Thread newThread(Runnable command){
//用Worker来封�?command,因为Worker也继承Runnable.
Worker worker = new Worker(command);
Thread t = new Thread(worker);
worker.thread = t;
this.realSize = this.realSize + 1;
t.setName("pool-" + this.realSize);
workers.add(worker);
return t;
}

// 线程工作执行
private class Worker implements Runnable {

//已准备
public final int ready = 1;

//在工作
public final int working = 2;

//在等待
public final int waiting = 3;

//已退出
public final int exited = 4;

//当前线程工作执行者的状态,默认是 ready
public int status = ready;

private final ReentrantLock runLock = new ReentrantLock();

private Runnable task;

Thread thread = null;

Worker( Runnable task) {
this.task = task;
this.status = this.ready;
}

@Override
public void run() {
Runnable runTask = this.task;
for (;;) {
if (runTask != null) {
try {
this.runTask(runTask);
} catch (RuntimeException e) {
;
}
runTask = null;
}
try {
runTask = getTask();
} catch (InterruptedException ie) {
this.status = this.exited;
break;
}
}
}

void shutdown(){
if ( thread != Thread.currentThread()) {
thread.interrupt();
}
}

private void runTask(Runnable task) {
try {
final ReentrantLock runLock = this.runLock;
runLock.lock();
this.status = this.working;
task.run();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
runLock.unlock();
}
}

private Runnable getTask() throws InterruptedException {
for (;;) {
Runnable task = null;
//工作队列非空,直接调用poll方法获取.
if (!workQueue.isEmpty()) {
task = workQueue.poll();
} else {
try {
//如果设置了idelTime 的�?,调用poll方法获取元素,超出idelTime时间,抛�?InterruptedException
if( idelTime != 0L ) {
task = workQueue.poll(idelTime, TimeUnit.MILLISECONDS);
} else {
//Worker线程负责获取方法,从工作队列头获取对象并删除队列中要获取的对象,如果队列为空,一直等�?
task = workQueue.take();
}
} catch (InterruptedException e) {
throw e;
} catch(Exception e) {
;
}
}
if (task != null) {
return task;
}
this.status = this.waiting;
}
}

}
}
[/code]
[b]3.8 XmlUnitl工具类[/b]
[code]package com.googlecode.soap.util;

import java.lang.reflect.Field;

public final class XmlUnitl {

public static final String SPACE_CHAR = "";

public static final String LEFT_SEQ = "<";

public static final String RIGHT_SEQ = ">";

public static String toXml(Object object) {
if (object == null) {
return SPACE_CHAR;
}
if (object.getClass().getName().equals(String.class.getName())) {
return object.toString();
} else if (object.getClass().getName().equals(Integer.class.getName())) {
return object.toString();
} else if (object.getClass().getName().equals(Float.class.getName())) {
return object.toString();
} else if (object.getClass().getName().equals(Double.class.getName())) {
return object.toString();
} else if (object.getClass().getName().equals(Long.class.getName())) {
return object.toString();
} else if (object.getClass().getName().equals(Long.class.getName())) {
return object.toString();
}
Field fields[] = object.getClass().getDeclaredFields();
if (fields == null || fields.length == 0) {
return SPACE_CHAR;
}
StringBuffer buffer = new StringBuffer();
for (Field field : fields) {
String name = field.getName();
field.setAccessible(true);
try {
Object value = field.get(object);
if (value != null) {
buffer.append(LEFT_SEQ + name + RIGHT_SEQ + value
+ LEFT_SEQ + "/" + name + RIGHT_SEQ);
}

} catch (Exception e) {
;
}
}
return buffer.toString();
}

}
[/code]

[b]3.9 测试类SoapTest [/b]
[code]package com.googlecode.soap.test;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import com.googlecode.soap.client.MethodInvocation;
import com.googlecode.soap.client.SoapRequest;
import com.googlecode.soap.client.SoapResponse;
import com.googlecode.soap.client.SoapServiceClient;

public class SoapTest {


public static void main(String[] args) throws Exception {
SoapServiceClient client = new SoapServiceClient("http://localhost:8099/axis2/services/SimpleService?wsdl");
MethodInvocation method = new MethodInvocation("getPrice",new Object[]{44},null);
SoapRequest request = new SoapRequest(method);
request.setCode("utf-8");
//client.setNamespace("http://webservice.chapter1.book/client");
BufferedReader systemIn=new BufferedReader(new InputStreamReader(System.in));
boolean flag=true;
while(flag){
String command=systemIn.readLine();
if( command==null || "quit".equalsIgnoreCase(command.trim())){
flag=false;
System.out.println("Client quit!");
continue;
} else if( "send".equalsIgnoreCase(command.trim())) {
System.out.println("send command..");
client.sendRequest(request);
SoapResponse response = client.getResponse();
System.out.println(response.getObject());
}

}

}

}
[/code]
[b]4.测试[/b]
4.1 先把 SimpleService.class和People.class发布到$AXIS_HOME$\WEB-INF\pojo\下,启动Axis2
4.2 运行 SoapTest,在控制台下输入send,即可测试
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值