实现原理类同于 http://blog.youkuaiyun.com/daryl715/archive/2007/09/20/1793826.aspx,一点区别在于本文着重讨论远程服务返回复杂类型的情况,其实也就是对返回类型在webservice做一些配置,客户端进行一些修改等
服务端:
POJO及远程接口
package
ch16.ComplexAxis;

public
interface
MessageService
...
{
public MessageBean getMessageBean();
}


package
ch16.ComplexAxis;
import
java.rmi.Remote;
import
java.rmi.RemoteException;

public
interface
RemoteMessageService
extends
Remote
...
{
public MessageBean getMessageBean () throws RemoteException;
}
服务接口实现
package
ch16.ComplexAxis;

public
class
SimpleMessageServie
implements
MessageService
...
{

public MessageBean getMessageBean() ...{
return new MessageBean("helloworld","gaoxiang");
}
}
JavaBean:
package
ch16.ComplexAxis;
import
java.io.Serializable;

public
class
MessageBean
implements
Serializable
...
{
private String message;
private String senderName;
public MessageBean()...{
}
public MessageBean(String message, String senderName) ...{
this.message = message;
this.senderName = senderName;
}
public String getMessage() ...{
return message;
}
public void setMessage(String message) ...{
this.message = message;
}
public String getSenderName() ...{
return senderName;
}
public void setSenderName(String senderName) ...{
this.senderName = senderName;
}
public String toString()...{
return this.message+" by "+this.senderName;
}
}
WEB服务实现
package
ch16.ComplexAxis;
import
java.rmi.RemoteException;
import
javax.xml.rpc.ServiceException;
import
org.springframework.remoting.jaxrpc.ServletEndpointSupport;
public
class
JaxRpcMessageService
extends
ServletEndpointSupport
implements

RemoteMessageService
...
{
private MessageService messageService;
@Override
protected void onInit() throws ServiceException ...{
messageService=(MessageService)getWebApplicationContext().getBean("messageService");
}
public MessageBean getMessageBean() throws RemoteException ...{
return messageService.getMessageBean();
}
}
spring配置文件:
<?
xml version="1.0" encoding="UTF-8"
?>
<
beans
xmlns
="http://www.springframework.org/schema/beans"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>
<
bean
id
="helloWorldService"
class
="ch16.SimpleAxis.SimpleHelloWorld"
>
</
bean
>
<
bean
id
="messageService"
class
="ch16.ComplexAxis.SimpleMessageServie"
>
</
bean
>
</
beans
>
axis部署描述符(增加了对复杂返回类的配置)
<
deployment
xmlns
="http://xml.apache.org/axis/wsdd/"
xmlns:java
="http://xml.apache.org/axis/wsdd/providers/java"
>
<
handler
name
="URLMapper"
type
="java:org.apache.axis.handlers.http.URLMapper"
/>
<
service
name
="MessageService"
provider
="java:RPC"
>
<
parameter
name
="className"
value
="ch16.ComplexAxis.JaxRpcMessageService"
/>
<
parameter
name
="allowedMethods"
value
="*"
/>
<!--
绑定复杂类型对象
-->
<
beanMapping
qname
="ws:MessageBean"
xmlns:ws
="http://localhost"
languageSpecificType
="java:ch16.ComplexAxis.MessageBean"
/>
</
service
>
<
transport
name
="http"
>
<
requestFlow
>
<
handler
type
="URLMapper"
/>
</
requestFlow
>
</
transport
>
</
deployment
>
web.xml
<
context-param
>
<
param-name
>
contextConfigLocation
</
param-name
>
<
param-value
>
/WEB-INF/applicationContext-server.xml
</
param-value
>
</
context-param
>
<
servlet
>
<
servlet-name
>
context
</
servlet-name
>
<
servlet-class
>
org.springframework.web.context.ContextLoaderServlet
</
servlet-class
>
<
load-on-startup
>
1
</
load-on-startup
>
</
servlet
>
<
servlet
>
<
servlet-name
>
axis
</
servlet-name
>
<
servlet-class
>
org.apache.axis.transport.http.AxisServlet
</
servlet-class
>
<
load-on-startup
>
2
</
load-on-startup
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>
axis
</
servlet-name
>
<
url-pattern
>
/services/*
</
url-pattern
>
</
servlet-mapping
>
客户端:
Spring没有为返回复杂类型的情况提供相应的JaxRpcPortProxyFactoryBean提供实现,所以我们必须自定义一个
package
ch16.ComplexAxis;
import
javax.xml.namespace.QName;
import
javax.xml.rpc.Service;
import
javax.xml.rpc.encoding.TypeMapping;
import
javax.xml.rpc.encoding.TypeMappingRegistry;
import
org.apache.axis.encoding.ser.BeanDeserializerFactory;
import
org.apache.axis.encoding.ser.BeanSerializerFactory;
import
org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean;
public
class
MessageServiceJaxRpcProxyFactoryBean
extends

JaxRpcPortProxyFactoryBean
...
{

protected void postProcessJaxRpcService(Service service) ...{
TypeMappingRegistry tmr=service.getTypeMappingRegistry();
TypeMapping tm=tmr.createTypeMapping();
QName qname=new QName("http://localhost","MessageBean");
tm.register(MessageBean.class, qname,
new BeanSerializerFactory(MessageBean.class,qname),
new BeanDeserializerFactory(MessageBean.class,qname));
tmr.register("http://schemas.xmlsoap.org/soap/encoding/", tm);
}
}
其中Qname的属性和axis配置过的对应
客户端spring配置文件
<?
xml version="1.0" encoding="UTF-8"
?>
<
beans
xmlns
="http://www.springframework.org/schema/beans"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
>

<
bean
id
="messageBeanService"
class
="ch16.ComplexAxis.MessageServiceJaxRpcProxyFactoryBean"
>
<
property
name
="serviceFactoryClass"
>
<
value
>
org.apache.axis.client.ServiceFactory
</
value
>
</
property
>
<
property
name
="wsdlDocumentUrl"
>
<
value
>
http://localhost:81/ProSpringStudyWeb/services/MessageService?wsdl
</
value
>
</
property
>
<
property
name
="namespaceUri"
>
<
value
>
http://localhost:81/ProSpringStudyWeb/services/MessageService
</
value
>
</
property
>
<
property
name
="serviceName"
>
<
value
>
JaxRpcMessageServiceService
</
value
>
</
property
>
<
property
name
="portName"
>
<
value
>
MessageService
</
value
>
</
property
>
<
property
name
="portInterface"
>
<
value
>
ch16.ComplexAxis.RemoteMessageService
</
value
>
</
property
>
<
property
name
="serviceInterface"
>
<
value
>
ch16.ComplexAxis.MessageService
</
value
>
</
property
>
</
bean
>
</
beans
>
测试代码:
package
ch16.ComplexAxis;
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;



public
class
Test
...
{

public static void main(String[] args) ...{
ApplicationContext context = new ClassPathXmlApplicationContext("ch16/ComplexAxis/applicationContext-client.xml");
MessageService messageService=(MessageService)context.getBean("messageBeanService");
System.out.println(messageService.getMessageBean());
}
}
运行服务端后,运行客户端测试程序,会出现以下结果
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
helloworld by gaoxiang
证明webservice返回复杂类型测试成功
这篇博客介绍了如何使用Spring结合Axis1.4开发WebService,特别是处理返回复杂类型的场景。文中详细讲解了服务端的POJO、接口实现、JavaBean以及配置文件设置,以及客户端如何自定义JaxRpcPortProxyFactoryBean来处理复杂类型,并提供了测试代码以验证成功运行。
1450

被折叠的 条评论
为什么被折叠?



