1.主要是为了加强对SOAP远程方法调用的学习,特意自己写了一个SOAP Client端.
2.要求环境:JDK1.6 以上,Axis2 以上
3.主要代码
[b]3.1 SimpleService类[/b]
[b]3.2 MethodInvocation类[/b]
[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,即可测试
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,即可测试