一.SpringAxisConstans
package com.skysuite.axis.spring;
import org.apache.axis.deployment.wsdd.WSDDConstants;
import javax.xml.namespace.QName;
public class SpringAxisConstans {
public static final String PROVIDER_SPRINGRPC = "SPRINGRPC";
public static final String PROVIDER_SPRINGMSG = "SPRINGMSG";
public static final QName QNAME_JAVARPC_SPRINGPROVIDER = new QName(WSDDConstants.URI_WSDD_JAVA, PROVIDER_SPRINGRPC);
public static final QName QNAME_JAVAMSG_SPRINGPROVIDER = new QName(WSDDConstants.URI_WSDD_JAVA, PROVIDER_SPRINGMSG);
}
2.AxisServlet
package com.skysuite.axis.spring;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.apache.axis.transport.http.AxisServlet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.StringUtils;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.context.support.XmlWebApplicationContext;
public class SpringAxisServlet extends AxisServlet {
private static final Log LOG = LogFactory.getLog(SpringAxisServlet.class);
/**
* Suffix for WebApplicationContext namespaces. If a SpringAxisServlet is
* given the name "axis" in a context, the namespace used by this instance will
* resolve to "axis-servlet".
*/
public static final String DEFAULT_NAMESPACE_SUFFIX = "-servlet";
/**
* Default context class for SpringAxisServlet.
*
* @see org.springframework.web.context.support.XmlWebApplicationContext
*/
public static final Class DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class;
/** Name of the ServletContext attribute for the WebApplicationContext */
public static final String SERVLET_CONTEXT_ATTRIBUTE = SpringAxisServlet.class.getName()
+ ".CONTEXT";
/** Custom WebApplicationContext class */
private Class contextClass = DEFAULT_CONTEXT_CLASS;
/** Namespace for this servlet */
private String namespace;
/** Explicit context config location */
private String contextConfigLocation;
/** WebApplicationContext for the SpringAxisServlet */
private WebApplicationContext webApplicationContext;
/**
* Initialise the WebApplicationContext of the SpringAxisServlet.
*
* @see org.apache.axis.transport.http.AxisServlet#init()
*/
public void init() throws ServletException {
super.init();
long startTime = System.currentTimeMillis();
if (LOG.isDebugEnabled()) {
LOG.debug("Servlet '" + getServletName() + "' init");
}
setContextClassName(getServletConfig().getInitParameter("contextClassName"));
setContextConfigLocation(getServletConfig().getInitParameter("contextConfigLocation"));
setNamespace(getServletConfig().getInitParameter("namespace"));
try {
this.webApplicationContext = initWebApplicationContext();
} catch (BeansException ex) {
LOG.error("Context initialization failed", ex);
throw ex;
}
if (LOG.isDebugEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
LOG.debug("Servlet '"
+ this.getServletName()
+ "' init completed in "
+ elapsedTime
+ " ms");
}
}
/**
* Close the WebApplicationContext of the SpringAxisServlet.
*
* @see org.apache.axis.transport.http.AxisServletBase#destroy()
*/
public void destroy() {
super.destroy();
log("Closing WebApplicationContext of servlet '" + getServletName() + "'");
if (this.webApplicationContext instanceof ConfigurableApplicationContext) {
((ConfigurableApplicationContext) this.webApplicationContext).close();
}
}
/**
* Set a custom context class by name. This class must be of type WebApplicationContext,
* when using the default SpringAxisServlet implementation, the context class
* must also implement ConfigurableWebApplicationContext.
*
* @see #createWebApplicationContext
*/
public void setContextClassName(String contextClassName) throws IllegalArgumentException {
if (contextClassName != null) {
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
this.contextClass = Class.forName(contextClassName, true, loader);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
}
/**
* Set a custom context class. This class must be of type WebApplicationContext,
* when using the default SpringAxisServlet implementation, the context class
* must also implement ConfigurableWebApplicationContext.
*
* @see #createWebApplicationContext
*/
public void setContextClass(Class contextClass) {
this.contextClass = contextClass;
}
/**
* Return the custom context class.
*/
public Class getContextClass() {
return contextClass;
}
/**
* Set a custom namespace for the SpringAxisServlet,
* to be used for building a default context config location.
*/
public void setNamespace(String namespace) {
this.namespace = namespace;
}
/**
* Return the namespace for the SpringAxisServlet, falling back to default scheme if
* no custom namespace was set: e.g. "axis-servlet" for a servlet named "axis".
*/
public String getNamespace() {
if (namespace != null) {
return namespace;
}
return getServletName() + DEFAULT_NAMESPACE_SUFFIX;
}
/**
* Set the context config location explicitly, instead of relying on the default
* location built from the namespace. This location string can consist of
* multiple locations separated by any number of commas and spaces.
*/
public void setContextConfigLocation(String contextConfigLocation) {
this.contextConfigLocation = contextConfigLocation;
}
/**
* Return the explicit context config location, if any.
*/
public String getContextConfigLocation() {
return contextConfigLocation;
}
/**
* Initialize and publish the WebApplicationContext for the SpringAxisServlet.
* Delegates to createWebApplicationContext for actual creation.
* Can be overridden in subclasses.
*
* @throws org.springframework.beans.BeansException
* if the context couldn't be initialized
*
* @see #createWebApplicationContext
*/
protected WebApplicationContext initWebApplicationContext() throws BeansException {
log("Initializing WebApplicationContext for servlet '" + this.getServletName() + "'");
ServletContext ctx = getServletContext();
WebApplicationContext parent = WebApplicationContextUtils.getWebApplicationContext(ctx);
//WebApplicationContext wac = createWebApplicationContext(parent);
WebApplicationContext wac = parent;
if (LOG.isDebugEnabled()) {
LOG.debug("Using context class '"
+ wac.getClass().getName()
+ "' for servlet '"
+ getServletName()
+ "'");
}
// publish the context as a servlet context attribute
ctx.setAttribute(SERVLET_CONTEXT_ATTRIBUTE, wac);
if (LOG.isDebugEnabled()) {
LOG.debug("Published WebApplicationContext of servlet '"
+ getServletName()
+ "' as ServletContext attribute with name ["
+ SERVLET_CONTEXT_ATTRIBUTE
+ "]");
}
return wac;
}
/**
* Instantiate the WebApplicationContext for the SpringAxisServlet, either a default
* XmlWebApplicationContext or a custom context class if set. This implementation
* expects custom contexts to implement ConfigurableWebApplicationContext.
* Can be overridden in subclasses.
*
* @throws org.springframework.beans.BeansException
* if the context couldn't be initialized
*
* @see #setContextClass
*
* @see org.springframework.web.context.support.XmlWebApplicationContext
*/
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent)
throws BeansException {
if (LOG.isDebugEnabled()) {
LOG.debug("Servlet with name '"
+ getServletName()
+ "' will try to create custom WebApplicationContext context of class '"
+ getContextClass().getName()
+ "'"
+ " using parent context ["
+ parent
+ "]");
}
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(getContextClass())) {
throw new ApplicationContextException(
"Fatal initialization error in servlet with name '"
+ getServletName()
+ "': custom WebApplicationContext class ["
+ getContextClass().getName()
+ "] is not of type ConfigurableWebApplicationContext");
}
ConfigurableWebApplicationContext wac = createContextInstance();
wac.setParent(parent);
wac.setServletContext(getServletContext());
wac.setNamespace(getNamespace());
if (this.contextConfigLocation != null) {
wac.setConfigLocations(StringUtils.tokenizeToStringArray(
this.contextConfigLocation,
ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS,
true,
true));
}
wac.refresh();
return wac;
}
private ConfigurableWebApplicationContext createContextInstance() {
return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(getContextClass());
}
/**
* Return the SpringAxisServlet's WebApplicationContext.
*/
public final WebApplicationContext getWebApplicationContext() {
return webApplicationContext;
}
}
三.SpringAxisSetup
package com.skysuite.axis.spring;
import org.apache.axis.deployment.wsdd.WSDDProvider;
public class SpringAxisSetup {
public SpringAxisSetup() {
init();
}
public void init() {
WSDDProvider.registerProvider(
SpringAxisConstans.QNAME_JAVARPC_SPRINGPROVIDER,
new WSDDSpringRPCProvider());
WSDDProvider.registerProvider(
SpringAxisConstans.QNAME_JAVAMSG_SPRINGPROVIDER,
new WSDDSpringMsgProvider());
}
}
四.SpringBeanMsgProvider
package com.skysuite.axis.spring;
import org.apache.axis.AxisFault;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.soap.SOAPService;
import org.apache.axis.providers.java.MsgProvider;
/**
* Axis provider for message-style services that uses Spring Framework
* to retrieve service classes and resolve their dependencies.
* Simply delegates to {@link com.workingmouse.webservice.axis.SpringBeanProvider}.
* <p>
* To use this class:<br>
* 1. Configure {@link com.workingmouse.webservice.axis.SpringAxisServlet} as your axis servlet in web.xml.
* <pre>
* <servlet>
* <servlet-name>axis</servlet-name>
* <display-name>Apache-Axis Servlet</display-name>
* <servlet-class>com.workingmouse.webservice.axis.SpringAxisServlet</servlet-class>
* </servlet>
* </pre>
* 2. Configure your server-config.wsdd service to use this class as the service handler.
* <pre>
* <service name="formRequest.jws" provider="Handler" style="message">
* <parameter name="handlerClass" value="com.workingmouse.webservice.axis.SpringBeanMsgProvider"/>
* <parameter name="wsdlTargetNamespace" value="http://www.ioof.com.au/schemas"/>
* <parameter name="springBean" value="formRequestWS"/>
* </service>
* </pre>
* 3. Configure a Spring-managed bean in axis-servlet.xml that will act as the web service end point.
* <pre>
* <bean id="formRequestWS" class="com.workingmouse.webservice.forms.FormRequestWebService">
* <property name="documentServices"><ref bean="documentServices"/></property>
* </bean>
* </pre>
*
*/
public class SpringBeanMsgProvider extends MsgProvider {
private final SpringBeanProvider provider = new SpringBeanProvider();
/**
* @see org.apache.axis.providers.java.JavaProvider#makeNewServiceObject(org.apache.axis.MessageContext, java.lang.String)
*/
protected Object makeNewServiceObject(MessageContext msgContext, String clsName)
throws Exception {
return provider.getBean(msgContext, clsName);
}
/**
* @see org.apache.axis.providers.java.JavaProvider#getServiceClass(java.lang.String, org.apache.axis.handlers.soap.SOAPService, org.apache.axis.MessageContext)
*/
protected Class getServiceClass(String clsName, SOAPService service, MessageContext msgContext)
throws AxisFault {
return provider.getBeanClass(clsName);
}
/**
* @see org.apache.axis.providers.java.JavaProvider#getServiceClassNameOptionName()
*/
protected String getServiceClassNameOptionName() {
return SpringBeanProvider.BEAN_OPTION_NAME;
}
}
五.SpringBeanProvider
package com.skysuite.axis.spring;
import javax.servlet.ServletContext;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.server.ServletEndpointContext;
import org.apache.axis.Constants;
import org.apache.axis.MessageContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
/**
*
*/
public class SpringBeanProvider {
private Log log = LogFactory.getLog(getClass());
/**
* The server-config.wsdd service parameter used to provide the name of the
* Spring-managed bean to use as the web service end-point.
*/
public static final String BEAN_OPTION_NAME = "springBean";
public static final String BEAN_CLASS_OPTION_NAME = "springBeanClass";
private WebApplicationContext webAppCtx;
/**
* Return a bean bound with the given beanName from the WebApplicationContext.
*/
public Object getBean(MessageContext msgContext, String beanName) throws Exception {
initWebAppContext(msgContext);
if (webAppCtx != null) {
return webAppCtx.getBean(beanName);
}
else {
return null;
}
}
/**
* Return the class of a bean bound with the given beanName in the WebApplicationContext.
*/
public Class getBeanClass(String className) {
Class result = null;
try {
result = Class.forName(className);
}
catch (ClassNotFoundException e) {
log.debug("class "+className+" not found");
}
return result;
}
private void initWebAppContext(MessageContext msgContext) throws ServiceException {
log.info("initializing app context for spring-axis integration");
if (webAppCtx == null) {
if (msgContext != null) {
Object context = msgContext.getProperty(Constants.MC_SERVLET_ENDPOINT_CONTEXT);
if (context instanceof ServletEndpointContext) {
ServletEndpointContext servletEndpointContext = (ServletEndpointContext) context;
ServletContext servletCtx = servletEndpointContext.getServletContext();
webAppCtx = WebApplicationContextUtils.getWebApplicationContext(servletCtx);
if (webAppCtx == null) {
log.info("failed to retrieve webapp context for spring-axis integration");
throw new ServiceException(
"Cannot find WebApplicationContext from org.springframework.web.context.ContextLoaderListener");
}
} else {
log.info("failed to retrieve webapp context for spring-axis integration because this is an incorrect servlet context!");
throw new ServiceException("Invalid context - expected ["
+ ServletEndpointContext.class.getName()
+ "], actual ["
+ context
+ "]");
}
}
else {
log.info("null msg context!");
}
}
}
}
六.SpringBeanRPCProvider
package com.skysuite.axis.spring;
import org.apache.axis.AxisFault;
import org.apache.axis.Handler;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.soap.SOAPService;
import org.apache.axis.providers.java.RPCProvider;
/**
* <p>
* To use this class:<br>
* 1. Configure web.xml to use the axis servlet
* 2. Configure web.xml to use the spring @see org.springframework.web.context.ContextLoaderListener.
* 3. Configure your server-config.wsdd service to use this class as the service handler.
*
* Here is an example:
* <pre>
* <service name="hdWebService.jws" provider="Handler" style="rpc">
* <parameter name="handlerClass" value="com.workingmouse.webservice.axis.SpringBeanRPCProvider"/>
* <parameter name="wsdlTargetNamespace" value="http://healthdec.com"/>
* <parameter name="springBean" value="hdWebService"/>
* <parameter name="springBeanClass" value="com.healthdec.hdSOAPServer.WebService"/>
* <parameter name="allowedMethods" value="findAllInstances"/>
* <beanMapping qname="myNS:Instance" xmlns:myNS="urn:BeanService" languageSpecificType="java:com.healthdec.domain.dm.Instance"/>
* <beanMapping qname="myNS:CRFType" xmlns:myNS="urn:BeanService" languageSpecificType="java:com.healthdec.domain.dm.CRFType"/>
* <beanMapping qname="myNS:CRFQuestionType" xmlns:myNS="urn:BeanService" languageSpecificType="java:com.healthdec.domain.dm.CRFQuestionType"/>
* </service>
* </pre>
*
* 4. Configure a Spring-managed bean in your applicationContext xml file that will act as the web service end point.
* <pre>
* <bean id="productWS" class="com.skysuite.webservice.ProductWebServices">
* </bean>
* </pre>
*
*/
public class SpringBeanRPCProvider extends RPCProvider {
private final SpringBeanProvider provider = new SpringBeanProvider();
private String serviceClassName;
private String springBeanName;
/* (non-Javadoc)
* @see org.apache.axis.providers.BasicProvider#initServiceDesc(org.apache.axis.handlers.soap.SOAPService, org.apache.axis.MessageContext)
*
* Get the name and class of the Spring bean that will implement the Webservice methods.
*
*/
public void initServiceDesc(SOAPService service, MessageContext arg1)
throws AxisFault {
setServiceClassName((String)service.getOption(SpringBeanProvider.BEAN_CLASS_OPTION_NAME));
setSpringBeanName((String)service.getOption(SpringBeanProvider.BEAN_OPTION_NAME));
super.initServiceDesc(service, arg1);
}
/**
* @see org.apache.axis.providers.java.JavaProvider#makeNewServiceObject(org.apache.axis.MessageContext, java.lang.String)
*/
protected Object makeNewServiceObject(MessageContext msgContext, String clsName)
throws Exception {
if (msgContext != null) {
return provider.getBean(msgContext, getSpringBeanName());
}
else {
return null;
}
}
/**
* @see org.apache.axis.providers.java.JavaProvider#getServiceClass(java.lang.String, org.apache.axis.handlers.soap.SOAPService, org.apache.axis.MessageContext)
*/
protected Class getServiceClass(String clsName, SOAPService service, MessageContext msgContext) {
return provider.getBeanClass(clsName);
}
/**
* @see org.apache.axis.providers.java.JavaProvider#getServiceClassNameOptionName()
*/
protected String getServiceClassNameOptionName() {
return SpringBeanProvider.BEAN_OPTION_NAME;
}
public void setServiceClassName(String serviceClassName) {
this.serviceClassName = serviceClassName;
}
/**
* @see org.apache.axis.providers.java.JavaProvider#getServiceClassName(org.apache.axis.Handler)
*/
protected String getServiceClassName(Handler arg0) {
return getServiceClassName();
}
/**
* @return Returns the serviceClassName.
*/
public String getServiceClassName() {
return serviceClassName;
}
/**
* @param serviceClassName The serviceClassName to set.
*/
/**
* @return Returns the springBeanName.
*/
public String getSpringBeanName() {
return springBeanName;
}
/**
* @param springBeanName The springBeanName to set.
*/
public void setSpringBeanName(String springBeanName) {
this.springBeanName = springBeanName;
}
}
七.WSDDSpringMsgProvider
package com.skysuite.axis.spring;
import org.apache.axis.EngineConfiguration;
import org.apache.axis.Handler;
import org.apache.axis.deployment.wsdd.WSDDProvider;
import org.apache.axis.deployment.wsdd.WSDDService;
public class WSDDSpringMsgProvider extends WSDDProvider{
@Override
public Handler newProviderInstance(WSDDService arg0, EngineConfiguration arg1) throws Exception {
return new SpringBeanMsgProvider();
}
@Override
public String getName() {
return SpringAxisConstans.PROVIDER_SPRINGMSG;
}
}
八. WSDDSpringRPCProvider
package com.skysuite.axis.spring;
import org.apache.axis.EngineConfiguration;
import org.apache.axis.Handler;
import org.apache.axis.deployment.wsdd.WSDDProvider;
import org.apache.axis.deployment.wsdd.WSDDService;
public class WSDDSpringRPCProvider extends WSDDProvider{
@Override
public Handler newProviderInstance(WSDDService arg0, EngineConfiguration arg1) throws Exception {
return new SpringBeanRPCProvider();
}
@Override
public String getName() {
return SpringAxisConstans.PROVIDER_SPRINGRPC;
}
}