提交 f1258a6a 编写于 作者: J Juergen Hoeller

Removed JAX-RPC support

上级 9c52ae95
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.remoting.jaxrpc;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.util.ClassUtils;
/**
* {@link FactoryBean} for a specific port of a JAX-RPC service.
* Exposes a proxy for the port, to be used for bean references.
* Inherits configuration properties from {@link JaxRpcPortClientInterceptor}.
*
* <p>This factory is typically used with an RMI service interface. Alternatively,
* this factory can also proxy a JAX-RPC service with a matching non-RMI business
* interface, i.e. an interface that mirrors the RMI service methods but does not
* declare RemoteExceptions. In the latter case, RemoteExceptions thrown by the
* JAX-RPC stub will automatically get converted to Spring's unchecked
* RemoteAccessException.
*
* <p>If exposing the JAX-RPC port interface (i.e. an RMI interface) directly,
* setting "serviceInterface" is sufficient. If exposing a non-RMI business
* interface, the business interface needs to be set as "serviceInterface",
* and the JAX-RPC port interface as "portInterface".
*
* @author Juergen Hoeller
* @since 15.12.2003
* @see #setServiceInterface
* @see #setPortInterface
* @see LocalJaxRpcServiceFactoryBean
* @deprecated in favor of JAX-WS support in {@code org.springframework.remoting.jaxws}
*/
@Deprecated
public class JaxRpcPortProxyFactoryBean extends JaxRpcPortClientInterceptor
implements FactoryBean<Object>, BeanClassLoaderAware {
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
private Object serviceProxy;
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@Override
public void afterPropertiesSet() {
if (getServiceInterface() == null) {
// Use JAX-RPC port interface (a traditional RMI interface)
// as service interface if none explicitly specified.
if (getPortInterface() != null) {
setServiceInterface(getPortInterface());
}
else {
throw new IllegalArgumentException("Property 'serviceInterface' is required");
}
}
super.afterPropertiesSet();
this.serviceProxy = new ProxyFactory(getServiceInterface(), this).getProxy(this.beanClassLoader);
}
public Object getObject() {
return this.serviceProxy;
}
public Class<?> getObjectType() {
return getServiceInterface();
}
public boolean isSingleton() {
return true;
}
}
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.remoting.jaxrpc;
import javax.xml.rpc.Service;
/**
* Callback interface for post-processing a JAX-RPC Service.
*
* <p>Implementations can be registered with {@link LocalJaxRpcServiceFactory}
* or one of its subclasses: {@link LocalJaxRpcServiceFactoryBean},
* {@link JaxRpcPortClientInterceptor}, or {@link JaxRpcPortProxyFactoryBean}.
*
* @author Juergen Hoeller
* @since 1.1.4
* @see LocalJaxRpcServiceFactory#setServicePostProcessors
* @see LocalJaxRpcServiceFactoryBean#setServicePostProcessors
* @see JaxRpcPortClientInterceptor#setServicePostProcessors
* @see JaxRpcPortProxyFactoryBean#setServicePostProcessors
* @see javax.xml.rpc.Service#getTypeMappingRegistry
* @deprecated in favor of JAX-WS support in {@code org.springframework.remoting.jaxws}
*/
@Deprecated
public interface JaxRpcServicePostProcessor {
/**
* Post-process the given JAX-RPC {@link Service}.
* @param service the current JAX-RPC {@code Service}
* (can be cast to an implementation-specific class if necessary)
*/
void postProcessJaxRpcService(Service service);
}
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.remoting.jaxrpc;
import javax.xml.namespace.QName;
import javax.xml.rpc.soap.SOAPFaultException;
import org.springframework.remoting.soap.SoapFaultException;
/**
* Spring SoapFaultException adapter for the JAX-RPC
* {@link javax.xml.rpc.soap.SOAPFaultException} class.
*
* @author Juergen Hoeller
* @since 2.5
* @deprecated in favor of JAX-WS support in {@code org.springframework.remoting.jaxws}
*/
@Deprecated
@SuppressWarnings("serial")
public class JaxRpcSoapFaultException extends SoapFaultException {
/**
* Constructor for JaxRpcSoapFaultException.
* @param original the original JAX-RPC SOAPFaultException to wrap
*/
public JaxRpcSoapFaultException(SOAPFaultException original) {
super(original.getMessage(), original);
}
/**
* Return the wrapped JAX-RPC SOAPFaultException.
*/
public final SOAPFaultException getOriginalException() {
return (SOAPFaultException) getCause();
}
@Override
public String getFaultCode() {
return getOriginalException().getFaultCode().toString();
}
@Override
public QName getFaultCodeAsQName() {
return getOriginalException().getFaultCode();
}
@Override
public String getFaultString() {
return getOriginalException().getFaultString();
}
@Override
public String getFaultActor() {
return getOriginalException().getFaultActor();
}
}
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.remoting.jaxrpc;
import java.net.URL;
import java.util.Properties;
import javax.xml.namespace.QName;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.ServiceFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
/**
* Factory for locally defined JAX-RPC {@link javax.xml.rpc.Service} references.
* Uses a JAX-RPC {@link javax.xml.rpc.ServiceFactory} underneath.
*
* <p>Serves as base class for {@link LocalJaxRpcServiceFactoryBean} as well as
* {@link JaxRpcPortClientInterceptor} and {@link JaxRpcPortProxyFactoryBean}.
*
* @author Juergen Hoeller
* @since 15.12.2003
* @see javax.xml.rpc.ServiceFactory
* @see javax.xml.rpc.Service
* @see LocalJaxRpcServiceFactoryBean
* @see JaxRpcPortClientInterceptor
* @see JaxRpcPortProxyFactoryBean
* @deprecated in favor of JAX-WS support in {@code org.springframework.remoting.jaxws}
*/
@Deprecated
public class LocalJaxRpcServiceFactory {
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
private ServiceFactory serviceFactory;
private Class serviceFactoryClass;
private URL wsdlDocumentUrl;
private String namespaceUri;
private String serviceName;
private Class jaxRpcServiceInterface;
private Properties jaxRpcServiceProperties;
private JaxRpcServicePostProcessor[] servicePostProcessors;
/**
* Set the ServiceFactory instance to use.
* <p>This is an alternative to the common "serviceFactoryClass" property,
* allowing for a pre-initialized ServiceFactory instance to be specified.
* @see #setServiceFactoryClass
*/
public void setServiceFactory(ServiceFactory serviceFactory) {
this.serviceFactory = serviceFactory;
}
/**
* Return the specified ServiceFactory instance, if any.
*/
public ServiceFactory getServiceFactory() {
return this.serviceFactory;
}
/**
* Set the ServiceFactory class to use, for example
* "org.apache.axis.client.ServiceFactory".
* <p>Does not need to be set if the JAX-RPC implementation has registered
* itself with the JAX-RPC system property "SERVICEFACTORY_PROPERTY".
* @see javax.xml.rpc.ServiceFactory
*/
public void setServiceFactoryClass(Class serviceFactoryClass) {
if (serviceFactoryClass != null && !ServiceFactory.class.isAssignableFrom(serviceFactoryClass)) {
throw new IllegalArgumentException("'serviceFactoryClass' must implement [javax.xml.rpc.ServiceFactory]");
}
this.serviceFactoryClass = serviceFactoryClass;
}
/**
* Return the ServiceFactory class to use, or {@code null} if default.
*/
public Class getServiceFactoryClass() {
return this.serviceFactoryClass;
}
/**
* Set the URL of the WSDL document that describes the service.
*/
public void setWsdlDocumentUrl(URL wsdlDocumentUrl) {
this.wsdlDocumentUrl = wsdlDocumentUrl;
}
/**
* Return the URL of the WSDL document that describes the service.
*/
public URL getWsdlDocumentUrl() {
return this.wsdlDocumentUrl;
}
/**
* Set the namespace URI of the service.
* Corresponds to the WSDL "targetNamespace".
*/
public void setNamespaceUri(String namespaceUri) {
this.namespaceUri = (namespaceUri != null ? namespaceUri.trim() : null);
}
/**
* Return the namespace URI of the service.
*/
public String getNamespaceUri() {
return this.namespaceUri;
}
/**
* Set the name of the service to look up.
* Corresponds to the "wsdl:service" name.
* @see javax.xml.rpc.ServiceFactory#createService(javax.xml.namespace.QName)
* @see javax.xml.rpc.ServiceFactory#createService(java.net.URL, javax.xml.namespace.QName)
* @see javax.xml.rpc.ServiceFactory#loadService(java.net.URL, javax.xml.namespace.QName, java.util.Properties)
*/
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
/**
* Return the name of the service.
*/
public String getServiceName() {
return this.serviceName;
}
/**
* Set the JAX-RPC service interface to use for looking up the service.
* If specified, this will override a "serviceName" setting.
* <p>The specified interface will usually be a generated JAX-RPC service
* interface that directly corresponds to the WSDL service declaration.
* Note that this is not a port interface or the application-level service
* interface to be exposed by a port proxy!
* <p>Only supported by JAX-RPC 1.1 providers.
* @see #setServiceName
* @see javax.xml.rpc.ServiceFactory#loadService(Class)
* @see javax.xml.rpc.ServiceFactory#loadService(java.net.URL, Class, java.util.Properties)
*/
public void setJaxRpcServiceInterface(Class jaxRpcServiceInterface) {
this.jaxRpcServiceInterface = jaxRpcServiceInterface;
}
/**
* Return the JAX-RPC service interface to use for looking up the service.
*/
public Class getJaxRpcServiceInterface() {
return this.jaxRpcServiceInterface;
}
/**
* Set JAX-RPC service properties to be passed to the ServiceFactory, if any.
* <p>Only supported by JAX-RPC 1.1 providers.
* @see javax.xml.rpc.ServiceFactory#loadService(java.net.URL, javax.xml.namespace.QName, java.util.Properties)
* @see javax.xml.rpc.ServiceFactory#loadService(java.net.URL, Class, java.util.Properties)
*/
public void setJaxRpcServiceProperties(Properties jaxRpcServiceProperties) {
this.jaxRpcServiceProperties = jaxRpcServiceProperties;
}
/**
* Return JAX-RPC service properties to be passed to the ServiceFactory, if any.
*/
public Properties getJaxRpcServiceProperties() {
return this.jaxRpcServiceProperties;
}
/**
* Set the JaxRpcServicePostProcessors to be applied to JAX-RPC Service
* instances created by this factory.
* <p>Such post-processors can, for example, register custom type mappings.
* They are reusable across all pre-built subclasses of this factory:
* LocalJaxRpcServiceFactoryBean, JaxRpcPortClientInterceptor,
* JaxRpcPortProxyFactoryBean.
* @see LocalJaxRpcServiceFactoryBean
* @see JaxRpcPortClientInterceptor
* @see JaxRpcPortProxyFactoryBean
*/
public void setServicePostProcessors(JaxRpcServicePostProcessor[] servicePostProcessors) {
this.servicePostProcessors = servicePostProcessors;
}
/**
* Return the JaxRpcServicePostProcessors to be applied to JAX-RPC Service
* instances created by this factory.
*/
public JaxRpcServicePostProcessor[] getServicePostProcessors() {
return this.servicePostProcessors;
}
/**
* Create a JAX-RPC Service according to the parameters of this factory.
* @see #setServiceName
* @see #setWsdlDocumentUrl
* @see #postProcessJaxRpcService
*/
public Service createJaxRpcService() throws ServiceException {
ServiceFactory serviceFactory = getServiceFactory();
if (serviceFactory == null) {
serviceFactory = createServiceFactory();
}
// Create service based on this factory's settings.
Service service = createService(serviceFactory);
// Allow for custom post-processing in subclasses.
postProcessJaxRpcService(service);
return service;
}
/**
* Return a QName for the given name, relative to the namespace URI
* of this factory, if given.
* @see #setNamespaceUri
*/
protected QName getQName(String name) {
return (getNamespaceUri() != null ? new QName(getNamespaceUri(), name) : new QName(name));
}
/**
* Create a JAX-RPC ServiceFactory, either of the specified class
* or the default.
* @throws ServiceException if thrown by JAX-RPC methods
* @see #setServiceFactoryClass
* @see javax.xml.rpc.ServiceFactory#newInstance()
*/
protected ServiceFactory createServiceFactory() throws ServiceException {
if (getServiceFactoryClass() != null) {
return (ServiceFactory) BeanUtils.instantiateClass(getServiceFactoryClass());
}
else {
return ServiceFactory.newInstance();
}
}
/**
* Actually create the JAX-RPC Service instance,
* based on this factory's settings.
* @param serviceFactory the JAX-RPC ServiceFactory to use
* @return the newly created JAX-RPC Service
* @throws ServiceException if thrown by JAX-RPC methods
* @see javax.xml.rpc.ServiceFactory#createService
* @see javax.xml.rpc.ServiceFactory#loadService
*/
protected Service createService(ServiceFactory serviceFactory) throws ServiceException {
if (getServiceName() == null && getJaxRpcServiceInterface() == null) {
throw new IllegalArgumentException("Either 'serviceName' or 'jaxRpcServiceInterface' is required");
}
if (getJaxRpcServiceInterface() != null) {
// Create service via generated JAX-RPC service interface.
// Only supported on JAX-RPC 1.1
if (getWsdlDocumentUrl() != null || getJaxRpcServiceProperties() != null) {
return serviceFactory.loadService(
getWsdlDocumentUrl(), getJaxRpcServiceInterface(), getJaxRpcServiceProperties());
}
return serviceFactory.loadService(getJaxRpcServiceInterface());
}
// Create service via specified JAX-RPC service name.
QName serviceQName = getQName(getServiceName());
if (getJaxRpcServiceProperties() != null) {
// Only supported on JAX-RPC 1.1
return serviceFactory.loadService(getWsdlDocumentUrl(), serviceQName, getJaxRpcServiceProperties());
}
if (getWsdlDocumentUrl() != null) {
return serviceFactory.createService(getWsdlDocumentUrl(), serviceQName);
}
return serviceFactory.createService(serviceQName);
}
/**
* Post-process the given JAX-RPC Service. Called by {@link #createJaxRpcService}.
* Useful, for example, to register custom type mappings.
* <p>The default implementation delegates to all registered
* {@link JaxRpcServicePostProcessor JaxRpcServicePostProcessors}.
* It is usually preferable to implement custom type mappings etc there rather
* than in a subclass of this factory, to allow for reuse of the post-processors.
* @param service the current JAX-RPC Service
* (can be cast to an implementation-specific class if necessary)
* @see #setServicePostProcessors
* @see javax.xml.rpc.Service#getTypeMappingRegistry()
*/
protected void postProcessJaxRpcService(Service service) {
JaxRpcServicePostProcessor[] postProcessors = getServicePostProcessors();
if (postProcessors != null) {
for (int i = 0; i < postProcessors.length; i++) {
postProcessors[i].postProcessJaxRpcService(service);
}
}
}
}
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.remoting.jaxrpc;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
/**
* {@link org.springframework.beans.factory.FactoryBean} for locally
* defined JAX-RPC Service references.
* Uses {@link LocalJaxRpcServiceFactory}'s facilities underneath.
*
* <p>Alternatively, JAX-RPC Service references can be looked up
* in the JNDI environment of the J2EE container.
*
* @author Juergen Hoeller
* @since 15.12.2003
* @see javax.xml.rpc.Service
* @see org.springframework.jndi.JndiObjectFactoryBean
* @see JaxRpcPortProxyFactoryBean
* @deprecated in favor of JAX-WS support in {@code org.springframework.remoting.jaxws}
*/
@Deprecated
public class LocalJaxRpcServiceFactoryBean extends LocalJaxRpcServiceFactory
implements FactoryBean<Service>, InitializingBean {
private Service service;
public void afterPropertiesSet() throws ServiceException {
this.service = createJaxRpcService();
}
public Service getObject() throws Exception {
return this.service;
}
public Class<? extends Service> getObjectType() {
return (this.service != null ? this.service.getClass() : Service.class);
}
public boolean isSingleton() {
return true;
}
}
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.remoting.jaxrpc;
import java.io.File;
import javax.servlet.ServletContext;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.server.ServiceLifecycle;
import javax.xml.rpc.server.ServletEndpointContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.util.WebUtils;
/**
* Convenience base class for JAX-RPC servlet endpoint implementations.
* Provides a reference to the current Spring application context,
* e.g. for bean lookup or resource loading.
*
* <p>The Web Service servlet needs to run in the same web application
* as the Spring context to allow for access to Spring's facilities.
* In case of Axis, copy the AxisServlet definition into your web.xml,
* and set up the endpoint in "server-config.wsdd" (or use the deploy tool).
*
* <p>This class does not extend
* {@link org.springframework.web.context.support.WebApplicationObjectSupport}
* to not expose any public setters. For some reason, Axis tries to
* resolve public setters in a special way...
*
* <p>JAX-RPC service endpoints are usually required to implement an
* RMI port interface. However, many JAX-RPC implementations accept plain
* service endpoint classes too, avoiding the need to maintain an RMI port
* interface in addition to an existing non-RMI business interface.
* Therefore, implementing the business interface will usually be sufficient.
*
* @author Juergen Hoeller
* @since 16.12.2003
* @see #init
* @see #getWebApplicationContext
* @deprecated in favor of JAX-WS support in {@code org.springframework.remoting.jaxws}
*/
@Deprecated
public abstract class ServletEndpointSupport implements ServiceLifecycle {
protected final Log logger = LogFactory.getLog(getClass());
private ServletEndpointContext servletEndpointContext;
private WebApplicationContext webApplicationContext;
private MessageSourceAccessor messageSourceAccessor;
/**
* Initialize this JAX-RPC servlet endpoint.
* Calls onInit after successful context initialization.
* @param context ServletEndpointContext
* @throws ServiceException if the context is not a ServletEndpointContext
* @see #onInit
*/
public final void init(Object context) throws ServiceException {
if (!(context instanceof ServletEndpointContext)) {
throw new ServiceException("ServletEndpointSupport needs ServletEndpointContext, not [" + context + "]");
}
this.servletEndpointContext = (ServletEndpointContext) context;
ServletContext servletContext = this.servletEndpointContext.getServletContext();
this.webApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
this.messageSourceAccessor = new MessageSourceAccessor(this.webApplicationContext);
onInit();
}
/**
* Return the current JAX-RPC ServletEndpointContext.
*/
protected final ServletEndpointContext getServletEndpointContext() {
return this.servletEndpointContext;
}
/**
* Return the current Spring ApplicationContext.
*/
protected final ApplicationContext getApplicationContext() {
return this.webApplicationContext;
}
/**
* Return the current Spring WebApplicationContext.
*/
protected final WebApplicationContext getWebApplicationContext() {
return this.webApplicationContext;
}
/**
* Return a MessageSourceAccessor for the application context
* used by this object, for easy message access.
*/
protected final MessageSourceAccessor getMessageSourceAccessor() {
return this.messageSourceAccessor;
}
/**
* Return the current ServletContext.
*/
protected final ServletContext getServletContext() {
return this.webApplicationContext.getServletContext();
}
/**
* Return the temporary directory for the current web application,
* as provided by the servlet container.
* @return the File representing the temporary directory
*/
protected final File getTempDir() {
return WebUtils.getTempDir(getServletContext());
}
/**
* Callback for custom initialization after the context has been set up.
* @throws ServiceException if initialization failed
*/
protected void onInit() throws ServiceException {
}
/**
* This implementation of destroy is empty.
* Can be overridden in subclasses.
*/
public void destroy() {
}
}
/**
*
* Remoting classes for Web Services via JAX-RPC.
* This package provides proxy factories for accessing JAX-RPC
* services and ports, and a support class for implementing
* JAX-RPC Servlet endpoints.
*
*/
package org.springframework.remoting.jaxrpc;
......@@ -51,11 +51,6 @@
<classname>BurlapServiceExporter</classname>.</para>
</listitem>
<listitem>
<para><emphasis>JAX-RPC</emphasis>. Spring provides remoting support
for web services via JAX-RPC (J2EE 1.4's web service API).</para>
</listitem>
<listitem>
<para><emphasis>JAX-WS</emphasis>. Spring provides remoting support
for web services via JAX-WS (the successor of JAX-RPC, as introduced
......@@ -501,14 +496,6 @@ public class AccountServiceImpl implements AccountService {
APIs:</para>
<itemizedlist>
<listitem>
<para>Exposing web services using JAX-RPC</para>
</listitem>
<listitem>
<para>Accessing web services using JAX-RPC</para>
</listitem>
<listitem>
<para>Exposing web services using JAX-WS</para>
</listitem>
......@@ -518,285 +505,13 @@ public class AccountServiceImpl implements AccountService {
</listitem>
</itemizedlist>
<note>
<para>Why two standard Java web services APIs?</para>
<para>JAX-RPC 1.1 is the standard web service API in J2EE 1.4. As its
name indicates, it focuses on on RPC bindings, which became less and
less popular in the past couple of years. As a consequence, it has been
superseded by JAX-WS 2.0 in Java EE 5, being more flexible in terms of
bindings but also being heavily annotation-based. JAX-WS 2.1 is also
included in Java 6 (or more specifically, in Sun's JDK 1.6.0_04 and
above; previous Sun JDK 1.6.0 releases included JAX-WS 2.0), integrated
with the JDK's built-in HTTP server.</para>
<para>Spring can work with both standard Java web services APIs. On Java
EE 5 / Java 6, the obvious choice is JAX-WS. On J2EE 1.4 environments
that run on Java 5, you might have the option to plug in a JAX-WS
provider; check your Java EE server's documentation.</para>
</note>
<para>In addition to stock support for JAX-RPC and JAX-WS in Spring Core,
<para>In addition to stock support for JAX-WS in Spring Core,
the Spring portfolio also features <link
xl:href="http://www.springframework.org/spring-ws">Spring Web
Services</link>, a solution for contract-first, document-driven web
services - highly recommended for building modern, future-proof web
services.</para>
<section xml:id="remoting-web-services-jaxrpc-export">
<title>Exposing servlet-based web services using JAX-RPC</title>
<para>Spring provides a convenience base class for JAX-RPC servlet
endpoint implementations -
<classname>ServletEndpointSupport</classname>. To expose our
<interfacename>AccountService</interfacename> we extend Spring's
<classname>ServletEndpointSupport</classname> class and implement our
business logic here, usually delegating the call to the business
layer.</para>
<programlisting language="java"><lineannotation>/**
* JAX-RPC compliant RemoteAccountService implementation that simply delegates
* to the AccountService implementation in the root web application context.
*
* This wrapper class is necessary because JAX-RPC requires working with dedicated
* endpoint classes. If an existing service needs to be exported, a wrapper that
* extends ServletEndpointSupport for simple application context access is
* the simplest JAX-RPC compliant way.
*
* This is the class registered with the server-side JAX-RPC implementation.
* In the case of Axis, this happens in "server-config.wsdd" respectively via
* deployment calls. The web service engine manages the lifecycle of instances
* of this class: A Spring application context can just be accessed here.
*/</lineannotation>import org.springframework.remoting.jaxrpc.ServletEndpointSupport;
public class AccountServiceEndpoint extends ServletEndpointSupport implements RemoteAccountService {
private AccountService biz;
protected void onInit() {
this.biz = (AccountService) getWebApplicationContext().getBean("accountService");
}
public void insertAccount(Account acc) throws RemoteException {
biz.insertAccount(acc);
}
public Account[] getAccounts(String name) throws RemoteException {
return biz.getAccounts(name);
}
}</programlisting>
<para>Our <classname>AccountServletEndpoint</classname> needs to run in
the same web application as the Spring context to allow for access to
Spring's facilities. In case of Axis, copy the
<classname>AxisServlet</classname> definition into your
<filename>'web.xml'</filename>, and set up the endpoint in
<filename>'server-config.wsdd'</filename> (or use the deploy tool). See
the sample application JPetStore where the
<interfacename>OrderService</interfacename> is exposed as a web service
using Axis.</para>
</section>
<section xml:id="remoting-web-services-jaxrpc-access">
<title>Accessing web services using JAX-RPC</title>
<para>Spring provides two factory beans to create JAX-RPC web service
proxies, namely <classname>LocalJaxRpcServiceFactoryBean</classname> and
<classname>JaxRpcPortProxyFactoryBean</classname>. The former can only
return a JAX-RPC service class for us to work with. The latter is the
full-fledged version that can return a proxy that implements our
business service interface. In this example we use the latter to create
a proxy for the <interfacename>AccountService</interfacename> endpoint
we exposed in the previous section. You will see that Spring has great
support for web services requiring little coding efforts - most of the
setup is done in the Spring configuration file as usual:</para>
<programlisting language="xml">&lt;bean id="accountWebService" class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean"&gt;
&lt;property name="serviceInterface" value="example.RemoteAccountService"/&gt;
&lt;property name="wsdlDocumentUrl" value="http://localhost:8080/account/services/accountService?WSDL"/&gt;
&lt;property name="namespaceUri" value="http://localhost:8080/account/services/accountService"/&gt;
&lt;property name="serviceName" value="AccountService"/&gt;
&lt;property name="portName" value="AccountPort"/&gt;
&lt;/bean&gt;</programlisting>
<para>Where <literal>serviceInterface</literal> is our remote business
interface the clients will use. <literal>wsdlDocumentUrl</literal> is
the URL for the WSDL file. Spring needs this at startup time to create
the JAX-RPC Service. <literal>namespaceUri</literal> corresponds to the
targetNamespace in the .wsdl file. <literal>serviceName</literal>
corresponds to the service name in the .wsdl file.
<literal>portName</literal> corresponds to the port name in the .wsdl
file.</para>
<para>Accessing the web service is now very easy as we have a bean
factory for it that will expose it as
<literal>RemoteAccountService</literal> interface. We can wire this up
in Spring:</para>
<programlisting language="xml">&lt;bean id="client" class="example.AccountClientImpl"&gt;
...
&lt;property name="service" ref="accountWebService"/&gt;
&lt;/bean&gt;</programlisting>
<para>From the client code we can access the web service just as if it
was a normal class, except that it throws
<exceptionname>RemoteException</exceptionname>.</para>
<programlisting language="java">public class AccountClientImpl {
private RemoteAccountService service;
public void setService(RemoteAccountService service) {
this.service = service;
}
public void foo() {
try {
service.insertAccount(...);
}
catch (RemoteException ex) {
<lineannotation>// ouch</lineannotation>
}
}
}
</programlisting>
<para>We can get rid of the checked
<exceptionname>RemoteException</exceptionname> since Spring supports
automatic conversion to its corresponding unchecked
<exceptionname>RemoteException</exceptionname>. This requires that we
provide a non-RMI interface also. Our configuration is now:</para>
<programlisting language="xml">&lt;bean id="accountWebService" class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean"&gt;
&lt;property name="serviceInterface" value="example.AccountService"/&gt;
&lt;property name="portInterface" value="example.RemoteAccountService"/&gt;
...
&lt;/bean&gt;</programlisting>
<para>Where <literal>serviceInterface</literal> is changed to our non
RMI interface. Our RMI interface is now defined using the property
<literal>portInterface</literal>. Our client code can now avoid handling
<exceptionname>java.rmi.RemoteException</exceptionname>:</para>
<programlisting language="java">public class AccountClientImpl {
private AccountService service;
public void setService(AccountService service) {
this.service = service;
}
public void foo() {
service.insertAccount(...);
}
}</programlisting>
<para>Note that you can also drop the "portInterface" part and specify a
plain business interface as "serviceInterface". In this case,
<classname>JaxRpcPortProxyFactoryBean</classname> will automatically
switch to the JAX-RPC "Dynamic Invocation Interface", performing dynamic
invocations without a fixed port stub. The advantage is that you don't
even need to have an RMI-compliant Java port interface around (e.g. in
case of a non-Java target web service); all you need is a matching
business interface. Check out
<classname>JaxRpcPortProxyFactoryBean</classname>'s javadoc for details
on the runtime implications.</para>
</section>
<section xml:id="remoting-web-services-jaxrpc-mapping-registration">
<title>Registering JAX-RPC Bean Mappings</title>
<para>To transfer complex objects over the wire such as
<classname>Account</classname> we must register bean mappings on the
client side.</para>
<note>
<para>On the server side using Axis registering bean mappings is
usually done in the <filename>'server-config.wsdd'</filename>
file.</para>
</note>
<para>We will use Axis to register bean mappings on the client side. To
do this we need to register the bean mappings programmatically:</para>
<programlisting language="java">public class AxisPortProxyFactoryBean extends JaxRpcPortProxyFactoryBean {
protected void postProcessJaxRpcService(Service service) {
TypeMappingRegistry registry = service.getTypeMappingRegistry();
TypeMapping mapping = registry.createTypeMapping();
registerBeanMapping(mapping, Account.class, "Account");
registry.register("http://schemas.xmlsoap.org/soap/encoding/", mapping);
}
protected void registerBeanMapping(TypeMapping mapping, Class type, String name) {
QName qName = new QName("http://localhost:8080/account/services/accountService", name);
mapping.register(type, qName,
new BeanSerializerFactory(type, qName),
new BeanDeserializerFactory(type, qName));
}
}</programlisting>
</section>
<section xml:id="remoting-web-services-jaxrpc-handler-registration">
<title>Registering your own JAX-RPC Handler</title>
<para>In this section we will register our own
<interfacename>javax.rpc.xml.handler.Handler</interfacename> to the web
service proxy where we can do custom code before the SOAP message is
sent over the wire. The <interfacename>Handler</interfacename> is a
callback interface. There is a convenience base class provided in
<filename class="libraryfile">jaxrpc.jar</filename>, namely
<classname>javax.rpc.xml.handler.GenericHandler</classname> that we will
extend:</para>
<programlisting language="java">public class AccountHandler extends GenericHandler {
public QName[] getHeaders() {
return null;
}
public boolean handleRequest(MessageContext context) {
SOAPMessageContext smc = (SOAPMessageContext) context;
SOAPMessage msg = smc.getMessage();
try {
SOAPEnvelope envelope = msg.getSOAPPart().getEnvelope();
SOAPHeader header = envelope.getHeader();
...
}
catch (SOAPException ex) {
throw new JAXRPCException(ex);
}
return true;
}
}</programlisting>
<para>What we need to do now is to register our AccountHandler to
JAX-RPC Service so it would invoke
<methodname>handleRequest(..)</methodname> before the message is sent
over the wire. Spring has at this time of writing no declarative support
for registering handlers, so we must use the programmatic approach.
However Spring has made it very easy for us to do this as we can
override the <methodname>postProcessJaxRpcService(..)</methodname>
method that is designed for this:</para>
<programlisting language="java">public class AccountHandlerJaxRpcPortProxyFactoryBean extends JaxRpcPortProxyFactoryBean {
protected void postProcessJaxRpcService(Service service) {
QName port = new QName(this.getNamespaceUri(), this.getPortName());
List list = service.getHandlerRegistry().getHandlerChain(port);
list.add(new HandlerInfo(AccountHandler.class, null, null));
logger.info("Registered JAX-RPC AccountHandler on port " + port);
}
}</programlisting>
<para>The last thing we must remember to do is to change the Spring
configuration to use our factory bean:</para>
<programlisting language="xml">&lt;bean id="accountWebService" class="example.AccountHandlerJaxRpcPortProxyFactoryBean"&gt;
...
&lt;/bean&gt;</programlisting>
</section>
<section xml:id="remoting-web-services-jaxws-export-servlet">
<title>Exposing servlet-based web services using JAX-WS</title>
......@@ -937,9 +652,8 @@ public class AccountServiceEndpoint {
<section xml:id="remoting-web-services-jaxws-access">
<title>Accessing web services using JAX-WS</title>
<para>Analogous to the JAX-RPC support, Spring provides two factory
beans to create JAX-WS web service proxies, namely
<classname>LocalJaxWsServiceFactoryBean</classname> and
<para>Spring provides two factory beans to create JAX-WS web service
proxies, namely <classname>LocalJaxWsServiceFactoryBean</classname> and
<classname>JaxWsPortProxyFactoryBean</classname>. The former can only
return a JAX-WS service class for us to work with. The latter is the
full-fledged version that can return a proxy that implements our
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册