Axis源码分析-客户端调用(一)

1.手工编码调用服务,如:

String endPoint = "……";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endPoint));
call.setOperation("sendSMPPMsg");
System.out.println(call.invoke(new Object[]{"aaa","bbb","ccc","ddd","001","ccms"}));

以上代码完成一次接口调用,源码解读
第一步:Service service = new Service();
完成新建服务对象,构造函数为:

public Service() {
//获取客户端引擎
engine = getAxisClient();
}

//通过EngineConfiguration构造客户端引擎
protected AxisClient getAxisClient() {
return new AxisClient(getEngineConfiguration());
}

//获取客户端配置信息
//EngineConfigurationFactoryFinder.newFactory返回的工厂是:
//org.apache.axis.configuration.EngineConfigurationFactoryDefault
//该工厂中getClientEngineConfig()返回的是FileProvider对象
protected EngineConfiguration getEngineConfiguration() {
if (this.config == null) {
this.config = EngineConfigurationFactoryFinder.newFactory().getClientEngineConfig();
}
return config;
}

EngineConfigurationFactoryDefault:

//EngineConfigurationFactoryDefault中方法
public EngineConfiguration getClientEngineConfig() {
return new FileProvider(clientConfigFile);
}


第二步:Call call = (Call) service.createCall();

public javax.xml.rpc.Call createCall() throws ServiceException {
_call = new org.apache.axis.client.Call(this);
return _call;
}

新建Call对象时,首先进行初始化

static {
initialize();
}

public Call(Service service) {
this.service = service ;
//service.getEngine()返回AxisClient实例
AxisEngine engine = service.getEngine();
//构造MessageContext
msgContext = new MessageContext( engine );
myProperties.setParent(engine.getOptions());
maintainSession = service.getMaintainSession();
}

//初始化协议对应的Transport(java/local/http/https)
public static synchronized void initialize() {
addTransportPackage("org.apache.axis.transport");

setTransportForProtocol("java",
org.apache.axis.transport.java.JavaTransport.class);
setTransportForProtocol("local",
org.apache.axis.transport.local.LocalTransport.class);
setTransportForProtocol("http", HTTPTransport.class);
setTransportForProtocol("https", HTTPTransport.class);
}


第三步:call.setTargetEndpointAddress(new java.net.URL(endPoint));

public void setTargetEndpointAddress(java.net.URL address) {
try {
if ( address == null ) {
setTransport(null);
return ;
}
String protocol = address.getProtocol();
if ( this.transport != null ) {
String oldAddr = this.transport.getUrl();
if ( oldAddr != null && !oldAddr.equals("") ) {
URL tmpURL = new URL( oldAddr );
String oldProto = tmpURL.getProtocol();
if ( protocol.equals(oldProto) ) {
this.transport.setUrl( address.toString() );
return ;
}
}
}

// Do we already have a transport for this address?
Transport transport = service.getTransportForURL(address);
if (transport != null) {
setTransport(transport);
}
else {
//org.apache.axis.transport.http.HTTPTransport
transport = getTransportForProtocol(protocol);
if (transport == null)
throw new AxisFault("Call.setTargetEndpointAddress",
Messages.getMessage("noTransport01",
protocol), null, null);
transport.setUrl(address.toString());
setTransport(transport);
service.registerTransportForURL(address, transport);
}
}
catch( Exception exp ) {
log.error(Messages.getMessage("exception00"), exp);
}
}


第四步:call.setOperation("sendSMPPMsg");

public void setOperation(String opName) {
if ( service == null ) {
throw new JAXRPCException( Messages.getMessage("noService04") );
}

this.setOperationName( opName );
this.setEncodingStyle( null );
this.setReturnType( null );
this.removeAllParameters();

javax.wsdl.Service wsdlService = service.getWSDLService();
if(wsdlService == null) {
return;
}
…… ……
}

public void setOperationName(String opName) {
operationName = new QName(opName);
}


第五步:call.invoke(new Object[]{});

public Object invoke(Object[] params) throws java.rmi.RemoteException {
Object res=this.invoke(operationName.getNamespaceURI(),
operationName.getLocalPart(), params);
……
}


public Object invoke(String namespace, String method, Object[] args)
throws AxisFault {
if (log.isDebugEnabled()) {
log.debug("Enter: Call::invoke(ns, meth, args)");
}

if (getReturnType() != null && args != null && args.length != 0 && operation.getNumParams() == 0) {
throw new AxisFault(Messages.getMessage("mustSpecifyParms"));
}
//构造参数消息体XML格式
RPCElement body = new RPCElement(namespace, method, getParamList(args));

Object ret = invoke( body );

if (log.isDebugEnabled()) {
log.debug("Exit: Call::invoke(ns, meth, args)");
}

return ret;
}


public Object invoke( RPCElement body ) throws AxisFault {
if (log.isDebugEnabled()) {
log.debug("Enter: Call::invoke(RPCElement)");
}

SOAPEnvelope reqEnv =
new SOAPEnvelope(msgContext.getSOAPConstants(),
msgContext.getSchemaVersion());
SOAPEnvelope resEnv = null ;
Message reqMsg = new Message( reqEnv );
Message resMsg = null ;
Vector resArgs = null ;
Object result = null ;

// Clear the output params
outParams = new HashMap();
outParamsList = new ArrayList();

// Set both the envelope and the RPCElement encoding styles
try {
body.setEncodingStyle(getEncodingStyle());
//设置请求消息
setRequestMessage(reqMsg);
//添加请求消息
reqEnv.addBodyElement(body);
reqEnv.setMessageType(Message.REQUEST);
System.out.println(reqMsg.getSOAPPartAsString());
//调用前不妨打印下请求消息体
//调用invoke
invoke();
} catch (Exception e) {
entLog.debug(Messages.getMessage("toAxisFault00"), e);
throw AxisFault.makeFault(e);
}
//获取响应消息
resMsg = msgContext.getResponseMessage();

if (resMsg == null) {
if (msgContext.isPropertyTrue(FAULT_ON_NO_RESPONSE, false)) {
throw new AxisFault(Messages.getMessage("nullResponse00"));
} else {
return null;
}
}

resEnv = resMsg.getSOAPEnvelope();
SOAPBodyElement bodyEl = resEnv.getFirstBody();
if (bodyEl == null) {
return null;
}

if (bodyEl instanceof RPCElement) {
try {
resArgs = ((RPCElement) bodyEl).getParams();
} catch (Exception e) {
log.error(Messages.getMessage("exception00"), e);
throw AxisFault.makeFault(e);
}

if (resArgs != null && resArgs.size() > 0) {
boolean findReturnParam = false;
QName returnParamQName = null;
if (operation != null) {
returnParamQName = operation.getReturnQName();
}

if (!XMLType.AXIS_VOID.equals(getReturnType())) {
if (returnParamQName == null) {
RPCParam param = (RPCParam)resArgs.get(0);
result = param.getObjectValue();
outParamStart = 1;
} else {
findReturnParam = true;
}
}

for (int i = outParamStart; i < resArgs.size(); i++) {
RPCParam param = (RPCParam) resArgs.get(i);

Class javaType = getJavaTypeForQName(param.getQName());
Object value = param.getObjectValue();

if (javaType != null && value != null &&
!javaType.isAssignableFrom(value.getClass())) {
value = JavaUtils.convert(value, javaType);
}

if (findReturnParam &&
returnParamQName.equals(param.getQName())) {
result = value;
findReturnParam = false;
} else {
outParams.put(param.getQName(), value);
outParamsList.add(value);
}
}

if (findReturnParam) {
Iterator it = outParams.keySet().iterator();
while (findReturnParam && it.hasNext()) {
QName qname = (QName) it.next();
ParameterDesc paramDesc =
operation.getOutputParamByQName(qname);
if (paramDesc == null) {
findReturnParam = false;
result = outParams.remove(qname);
}
}
}
if (findReturnParam) {
String returnParamName = returnParamQName.toString();
throw new AxisFault(Messages.getMessage("noReturnParam",
returnParamName));
}
}
} else {
try {
result = bodyEl.getValueAsType(getReturnType());
} catch (Exception e) {
result = bodyEl;
}

}

if (operation != null && operation.getReturnClass() != null) {
result = JavaUtils.convert(result, operation.getReturnClass());
}
return( result );
}

请求消息体

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<sendSMPPMsg xmlns="">
<arg0 xsi:type="xsd:string">aaa</arg0>
<arg1 xsi:type="xsd:string">bbb</arg1>
<arg2 xsi:type="xsd:string">ccc</arg2>
<arg3 xsi:type="xsd:string">ddd</arg3>
<arg4 xsi:type="xsd:string">001</arg4>
<arg5 xsi:type="xsd:string">ccms</arg5>
</sendSMPPMsg>
</soapenv:Body>
</soapenv:Envelope>


public void invoke() throws AxisFault {
if (log.isDebugEnabled()) {
log.debug("Enter: Call::invoke()");
}
isNeverInvoked = false;
Message reqMsg = null ;
SOAPEnvelope reqEnv = null ;
//以下为设置MessageContext
msgContext.reset();
msgContext.setResponseMessage(null);
msgContext.setProperty( MessageContext.CALL, this );
msgContext.setProperty( WSDL_SERVICE, service );
msgContext.setProperty( WSDL_PORT_NAME, getPortName() );
if ( isMsg ) {
msgContext.setProperty( MessageContext.IS_MSG, "true" );
}

if (username != null) {
msgContext.setUsername(username);
}
if (password != null) {
msgContext.setPassword(password);
}
msgContext.setMaintainSession(maintainSession);

if (operation != null) {
msgContext.setOperation(operation);
operation.setStyle(getOperationStyle());
operation.setUse(getOperationUse());
}

if (useSOAPAction) {
msgContext.setUseSOAPAction(true);
}
if (SOAPActionURI != null) {
msgContext.setSOAPActionURI(SOAPActionURI);
} else {
msgContext.setSOAPActionURI(null);
}
if (timeout != null) {
msgContext.setTimeout(timeout.intValue());
}
msgContext.setHighFidelity(!useStreaming);
if (myService != null) {
msgContext.setService(myService);
} else {
if (portName != null) {
msgContext.setTargetService(portName.getLocalPart());
} else {
reqMsg = msgContext.getRequestMessage();
boolean isStream = ((SOAPPart)reqMsg.getSOAPPart()).isBodyStream();

if (reqMsg != null && !isStream) {
reqEnv = reqMsg.getSOAPEnvelope();

SOAPBodyElement body = reqEnv.getFirstBody();

if (body != null) {
if ( body.getNamespaceURI() == null ) {
throw new AxisFault("Call.invoke",
Messages.getMessage("cantInvoke00", body.getName()),
null, null);
} else {
msgContext.setTargetService(body.getNamespaceURI());
}
}
}
}
}
if (log.isDebugEnabled()) {
log.debug(Messages.getMessage("targetService",
msgContext.getTargetService()));
}

Message requestMessage = msgContext.getRequestMessage();
if (requestMessage != null) {
try {
msgContext.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, requestMessage.getProperty(SOAPMessage.CHARACTER_SET_ENCODING));
} catch (SOAPException e) {
}

if(myHeaders != null) {
reqEnv = requestMessage.getSOAPEnvelope();

// If we have headers to insert, do so now.
for (int i = 0 ; myHeaders != null && i < myHeaders.size() ; i++ ) {
reqEnv.addHeader((SOAPHeaderElement)myHeaders.get(i));
}
}
}

// set up transport if there is one
if (transport != null) {
transport.setupMessageContext(msgContext, this, service.getEngine());
}
else {
msgContext.setTransportName( transportName );
}

SOAPService svc = msgContext.getService();
if (svc != null) {
svc.setPropertyParent(myProperties);
} else {
msgContext.setPropertyParent(myProperties);
}

if(!invokeOneWay) {
//使用当前线程调用
invokeEngine(msgContext);
} else {
//异步调用,开启新的线程调用
invokeEngineOneWay(msgContext);
}
}


private void invokeEngine(MessageContext msgContext) throws AxisFault {
//将当前invoke委托至客户端引擎AxisClient执行
service.getEngine().invoke( msgContext );
if (transport != null) {
transport.processReturnedMessageContext(msgContext);
}
Message resMsg = msgContext.getResponseMessage();

if (resMsg == null) {
if (msgContext.isPropertyTrue(FAULT_ON_NO_RESPONSE, false)) {
throw new AxisFault(Messages.getMessage("nullResponse00"));
} else {
return;
}
}

/** This must happen before deserialization...
*/
resMsg.setMessageType(Message.RESPONSE);

SOAPEnvelope resEnv = resMsg.getSOAPEnvelope();

SOAPBodyElement respBody = resEnv.getFirstBody();
if (respBody instanceof SOAPFault) {
//we got a fault
if(operation == null ||
operation.getReturnClass() == null ||
operation.getReturnClass() !=
javax.xml.soap.SOAPMessage.class) {
//unless we don't care about the return value or we want
//a raw message back
//get the fault from the body and throw it
throw ((SOAPFault)respBody).getFault();
}
}
}

AxisClient:

public void invoke(MessageContext msgContext) throws AxisFault {
String hName = null;
Handler h = null;
HandlerChain handlerImpl = null;
MessageContext previousContext = getCurrentMessageContext();
try {
setCurrentMessageContext(msgContext);
hName = msgContext.getStrProp(MessageContext.ENGINE_HANDLER);
if (hName != null) {
h = getHandler(hName);
if (h != null)
h.invoke(msgContext);
else
throw new AxisFault("Client.error",
Messages.getMessage("noHandler00",
hName),
null, null);
} else {
SOAPService service = null;
msgContext.setPastPivot(false);
service = msgContext.getService();
if (service != null) {
h = service.getRequestHandler();
if (h != null)
h.invoke(msgContext);
}
if ((h = getGlobalRequest()) != null)
h.invoke(msgContext);
handlerImpl = getJAXRPChandlerChain(msgContext);
if (handlerImpl != null) {
try {
if (!handlerImpl.handleRequest(msgContext)) {
msgContext.setPastPivot(true);
}
} catch (RuntimeException re) {
handlerImpl.destroy();
throw re;
}
}

if (!msgContext.getPastPivot()) {
//hName为http
hName = msgContext.getTransportName();
//getTransport方法为AxisEngine实现
if (hName != null && (h = getTransport(hName)) != null) {
try {
h.invoke(msgContext);
} catch (AxisFault e) {
throw e;
}
} else {
throw new AxisFault(Messages.getMessage("noTransport00",
hName));
}
}

msgContext.setPastPivot(true);
if (!msgContext.isPropertyTrue(Call.ONE_WAY)) {
if ((handlerImpl != null) &&
!msgContext.isPropertyTrue(Call.ONE_WAY)) {
try {
handlerImpl.handleResponse(msgContext);
} catch (RuntimeException ex) {
handlerImpl.destroy(); // WS4EE 1.1 6.2.2.1 Handler Life Cycle. "RuntimeException" --> destroy handler
throw ex;
}
}

/* Process the Global Response Chain */
/***********************************/
if ((h = getGlobalResponse()) != null) {
h.invoke(msgContext);
}

/* Process the Service-Specific Response Chain */
/***********************************************/
if (service != null) {
h = service.getResponseHandler();
if (h != null) {
h.invoke(msgContext);
}
}

// Do SOAP Semantics checks here - this needs to be a call
// to a pluggable object/handler/something
if (msgContext.isPropertyTrue(Call.CHECK_MUST_UNDERSTAND,
true)) {
checker.invoke(msgContext);
}
}
}
} catch (Exception e) {
// Should we even bother catching it ?
if (e instanceof AxisFault) {
throw (AxisFault) e;
} else {
log.debug(Messages.getMessage("exception00"), e);
throw AxisFault.makeFault(e);
}
} finally {
if (handlerImpl != null) {
handlerImpl.destroy();
}
// restore previous state
setCurrentMessageContext(previousContext);
}
if (log.isDebugEnabled()) {
log.debug("Exit: AxisClient::invoke");
}
}

AxisEngine:

public Handler getTransport(String name) throws AxisFault
{
try {
//config为org.apache.axis.configuration.FileProvider
return config.getTransport(new QName(null, name));
} catch (ConfigurationException e) {
throw new AxisFault(e);
}
}

FileProvider:

public Handler getTransport(QName qname) throws ConfigurationException {
return deployment.getTransport(qname);
}

org.apache.axis.deployment.wsdd.WSDDDeployment:

public Handler getTransport(QName name) throws ConfigurationException {
WSDDTransport t = (WSDDTransport) transports.get(name);
if (t != null) {
return t.getInstance(this);
}
return null;
}



public final Handler getInstance(EngineConfiguration registry)
throws ConfigurationException
{
if (scope == SCOPE_SINGLETON) {
synchronized (this) {
if (singletonInstance == null)
singletonInstance = getNewInstance(registry);
}
return singletonInstance;
}
return getNewInstance(registry);
}

private Handler getNewInstance(EngineConfiguration registry)
throws ConfigurationException
{
QName type = getType();
if (type == null ||
WSDDConstants.URI_WSDD_JAVA.equals(type.getNamespaceURI())) {
try
{
//此处产生实例交给子类WSDDTargetedChain实现
Handler ha = makeNewInstance(registry);
return ha;
}
catch(Exception e)
{
e.printStackTrace();
return null;
}

} else {
return registry.getHandler(type);
}
}

WSDDTargetedChain:

public Handler makeNewInstance(EngineConfiguration registry)
throws ConfigurationException
{
Handler reqHandler = null;

WSDDChain req = getRequestFlow();
if (req != null)
reqHandler = req.getInstance(registry);

Handler pivot = null;
if (pivotQName != null) {
if (URI_WSDD_JAVA.equals(pivotQName.getNamespaceURI())) {
try {
//此处的枢纽Handler为client包下的client-config.wsdd配置中的http Transport即:java:org.apache.axis.transport.http.HTTPSender
pivot = (Handler)ClassUtils.forName(pivotQName.getLocalPart()).newInstance();
} catch (InstantiationException e) {
throw new ConfigurationException(e);
} catch (IllegalAccessException e) {
throw new ConfigurationException(e);
} catch (ClassNotFoundException e) {
throw new ConfigurationException(e);
}
} else {
pivot = registry.getHandler(pivotQName);
}
}

Handler respHandler = null;
WSDDChain resp = getResponseFlow();
if (resp != null)
respHandler = resp.getInstance(registry);
//返回SimpleTargetedChain
Handler retVal = new org.apache.axis.SimpleTargetedChain(reqHandler, pivot,respHandler);
retVal.setOptions(getParametersTable());
return retVal;
}

SimpleTargetedChain:

public SimpleTargetedChain(Handler reqHandler, Handler pivHandler,
Handler respHandler) {
init(reqHandler, null, pivHandler, null, respHandler);
}
//初始化Handler链:请求requestHandler、响应responseHandler、枢纽pivotHandler(此处为client-config.wsdd中配置的<transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>)
protected void init(Handler reqHandler, Handler specialReqHandler,
Handler pivHandler, Handler specialRespHandler,
Handler respHandler) {

requestHandler = reqHandler;
if (requestHandler != null)
addHandler(requestHandler);

if (specialReqHandler != null)
addHandler(specialReqHandler);

pivotHandler = pivHandler;
if (pivotHandler != null) {
addHandler(pivotHandler);
addHandler(new PivotIndicator());
}

if (specialRespHandler != null)
addHandler(specialRespHandler);

responseHandler = respHandler;
if (responseHandler != null)
addHandler(responseHandler);
}


回到AxisClient中的

if (hName != null && (h = getTransport(hName)) != null) {
try {
//h为:org.apache.axis.SimpleTargetedChain
h.invoke(msgContext);
} catch (AxisFault e) {
throw e;
}
}

SimpleTargetedChain的invoke是由父类SimpleChain实现

public void invoke(MessageContext msgContext) throws AxisFault {
invoked = true;
doVisiting(msgContext, iVisitor);
}

//visitor为InvocationStrategy
private void doVisiting(MessageContext msgContext,
HandlerIterationStrategy visitor) throws AxisFault {
int i = 0 ;
try {
Enumeration enumeration = handlers.elements();
while (enumeration.hasMoreElements()) {
//循环Handler链,对每个handler都进行迭代
Handler h = (Handler)enumeration.nextElement();
visitor.visit(h, msgContext);
i++;
}
} catch( AxisFault f ) {
……
}
}



public class InvocationStrategy implements HandlerIterationStrategy {
public void visit(Handler handler, MessageContext msgContext)
throws AxisFault {
//实际上是调用每个注册的Handler的invoke方法
handler.invoke(msgContext);
}
}

此处为client-config.wsdd中配置的<transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>
即枢纽Handler类:HTTPSender

public void invoke(MessageContext msgContext) throws AxisFault {
SocketHolder socketHolder = new SocketHolder(null);
try {
BooleanHolder useFullURL = new BooleanHolder(false);
StringBuffer otherHeaders = new StringBuffer();
targetURL = new URL(msgContext.getStrProp(MessageContext.TRANS_URL));
String host = targetURL.getHost();
int port = targetURL.getPort();
//writeToSocket完成Http请求头设置、Socket工厂产生Socket对象
//向socket输出流添加http请求头以及请求消息体XML格式
InputStream inp = writeToSocket(socketHolder, msgContext, targetURL,otherHeaders, host, port, msgContext.getTimeout(), useFullURL);
Hashtable headers = new Hashtable();
//向socket输入流添加http响应头
inp = readHeadersFromSocket(socketHolder, msgContext, inp, headers);
//向socket输入流添加响应消息体XML格式
readFromSocket(socketHolder, msgContext, inp, headers);
} catch (Exception e) {
log.debug(e);
try {
if (socketHolder.getSocket() != null ) {
socketHolder.getSocket().close();
}
} catch (IOException ie) {
// we shouldn't get here.
}
throw AxisFault.makeFault(e);
}
}

以下为打印的header信息:

POST /frameweb/SmsSendService.jws?wsdl HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/#axisVersion#
Host: 10.70.85.91:7001
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 600

以下为返回响应信息:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<sendSMPPMsgResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<sendSMPPMsgReturn xsi:type="xsd:string">发送成功</sendSMPPMsgReturn>
</sendSMPPMsgResponse>
</soapenv:Body>
</soapenv:Envelope>


至此,能大概对完成一次Webservice调用有个清晰的了解。
实际上,调用的底层采用socket发送http请求+xml消息(Message)。
我可以直接通过socket调用Webservice服务,代码如下:

Socket socket = null;
OutputStream out = null;
try
{
socket = getSocket("192.168.1.110", 8888, 20000);
out = socket.getOutputStream();
out = new BufferedOutputStream(out, 8 * 1024);
String header = "POST /axis/services/Version?wsdl HTTP/1.0\n" +
"Content-Type: text/xml; charset=utf-8\n" +
"Accept: application/soap+xml, application/dime, multipart/related, text/*\n" +
"User-Agent: Axis/#axisVersion#\n" +
"Host: localhost:8888\n" +
"Cache-Control: no-cache\n" +
"Pragma: no-cache\n" +
"SOAPAction: \"\"\n" +
"Content-Length: 291\n\n";
System.out.println(header);
out.write(header.toString()
.getBytes("iso-8859-1"));
Writer writer = new OutputStreamWriter(out, "UTF-8");
writer = new BufferedWriter(new PrintWriter(writer));

String req = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
"\n <soapenv:Body>\n" +
" <getVersion xmlns=\"\"/>\n" +
" </soapenv:Body>\n" +
"</soapenv:Envelope>";
System.out.println(req);
System.out.println(req.length());
writer.write(new String(req.getBytes("iso-8859-1")));
writer.flush();

out.flush();
BufferedReader reader = new BufferedReader (
new InputStreamReader
(socket.getInputStream()
));
String line;
while((line = reader.readLine()) != null)
{
System.out.println(line);
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
socket.close();
out.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值