提交 4955a730 编写于 作者: J Juergen Hoeller

added support for JAX-WS 2.1 WebServiceFeatures to...

added support for JAX-WS 2.1 WebServiceFeatures to JaxWsPortClientInterceptor/PortProxyFactoryBean (SPR-5712)
上级 11bb7264
......@@ -25,17 +25,22 @@ import javax.xml.ws.BindingProvider;
import javax.xml.ws.ProtocolException;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.soap.SOAPFaultException;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.remoting.RemoteAccessException;
import org.springframework.remoting.RemoteConnectFailureException;
import org.springframework.remoting.RemoteLookupFailureException;
import org.springframework.remoting.RemoteProxyFailureException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* {@link org.aopalliance.intercept.MethodInterceptor} for accessing a
......@@ -54,7 +59,7 @@ import org.springframework.remoting.RemoteProxyFailureException;
* @see org.springframework.jndi.JndiObjectFactoryBean
*/
public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
implements MethodInterceptor, InitializingBean {
implements MethodInterceptor, BeanClassLoaderAware, InitializingBean {
private Service jaxWsService;
......@@ -74,10 +79,14 @@ public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
private Map<String, Object> customProperties;
private Object[] webServiceFeatures;
private Class<?> serviceInterface;
private boolean lookupServiceOnStartup = true;
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
private QName portQName;
private Object portStub;
......@@ -244,6 +253,15 @@ public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
getCustomProperties().put(name, value);
}
/**
* Allows for providing JAX-WS 2.1 WebServiceFeature specifications:
* in the form of actual {@link javax.xml.ws.WebServiceFeature} objects,
* WebServiceFeature Class references, or WebServiceFeature class names.
*/
public void setWebServiceFeatures(Object[] webServiceFeatures) {
this.webServiceFeatures = webServiceFeatures;
}
/**
* Set the interface of the service that this factory should create a proxy for.
*/
......@@ -271,6 +289,23 @@ public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
this.lookupServiceOnStartup = lookupServiceOnStartup;
}
/**
* Set the bean ClassLoader to use for this interceptor:
* for resolving WebServiceFeature class names as specified through
* {@link #setWebServiceFeatures}, and also for building a client
* proxy in the {@link JaxWsPortProxyFactoryBean} subclass.
*/
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
/**
* Return the bean ClassLoader to use for this interceptor.
*/
protected ClassLoader getBeanClassLoader() {
return this.beanClassLoader;
}
public void afterPropertiesSet() {
if (this.lookupServiceOnStartup) {
......@@ -278,6 +313,9 @@ public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
}
}
/**
* Initialize the JAX-WS port for this interceptor.
*/
public void prepare() {
if (getServiceInterface() == null) {
throw new IllegalArgumentException("Property 'serviceInterface' is required");
......@@ -287,8 +325,7 @@ public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
serviceToUse = createJaxWsService();
}
this.portQName = getQName(getPortName() != null ? getPortName() : getServiceInterface().getName());
Object stub = (getPortName() != null ?
serviceToUse.getPort(this.portQName, getServiceInterface()) : serviceToUse.getPort(getServiceInterface()));
Object stub = getPortStub(serviceToUse, (getPortName() != null ? this.portQName : null));
preparePortStub(stub);
this.portStub = stub;
}
......@@ -312,6 +349,23 @@ public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
return this.portQName;
}
/**
* Obtain the port stub from the given JAX-WS Service.
* @param service the Service object to obtain the port from
* @param portQName the name of the desired port, if specified
* @return the corresponding port object as returned from
* <code>Service.getPort(...)</code>
*/
protected Object getPortStub(Service service, QName portQName) {
if (this.webServiceFeatures != null) {
return new FeaturePortProvider().getPortStub(service, portQName, this.webServiceFeatures);
}
else {
return (portQName != null ? service.getPort(portQName, getServiceInterface()) :
service.getPort(getServiceInterface()));
}
}
/**
* Prepare the given JAX-WS port stub, applying properties to it.
* Called by {@link #prepare}.
......@@ -424,4 +478,44 @@ public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
}
}
/**
* Inner class in order to avoid a hard-coded JAX-WS 2.1 dependency.
* JAX-WS 2.0, as used in Java EE 5, didn't have WebServiceFeatures yet...
*/
private class FeaturePortProvider {
public Object getPortStub(Service service, QName portQName, Object[] features) {
WebServiceFeature[] wsFeatures = new WebServiceFeature[features.length];
for (int i = 0; i < features.length; i++) {
wsFeatures[i] = convertWebServiceFeature(features[i]);
}
return (portQName != null ? service.getPort(portQName, getServiceInterface(), wsFeatures) :
service.getPort(getServiceInterface(), wsFeatures));
}
private WebServiceFeature convertWebServiceFeature(Object feature) {
Assert.notNull(feature, "WebServiceFeature specification object must not be null");
if (feature instanceof WebServiceFeature) {
return (WebServiceFeature) feature;
}
else if (feature instanceof Class) {
return (WebServiceFeature) BeanUtils.instantiate((Class<?>) feature);
}
else if (feature instanceof String) {
try {
Class<?> featureClass = getBeanClassLoader().loadClass((String) feature);
return (WebServiceFeature) BeanUtils.instantiate(featureClass);
}
catch (ClassNotFoundException ex) {
throw new IllegalArgumentException("Could not load WebServiceFeature class [" + feature + "]");
}
}
else {
throw new IllegalArgumentException("Unknown WebServiceFeature specification type: " + feature.getClass());
}
}
}
}
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2010 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.
......@@ -19,9 +19,7 @@ package org.springframework.remoting.jaxws;
import javax.xml.ws.BindingProvider;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.util.ClassUtils;
/**
* {@link org.springframework.beans.factory.FactoryBean} for a specific port of a
......@@ -34,17 +32,11 @@ import org.springframework.util.ClassUtils;
* @see LocalJaxWsServiceFactoryBean
*/
public class JaxWsPortProxyFactoryBean extends JaxWsPortClientInterceptor
implements FactoryBean<Object>, BeanClassLoaderAware {
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
implements FactoryBean<Object> {
private Object serviceProxy;
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
......@@ -54,7 +46,7 @@ public class JaxWsPortProxyFactoryBean extends JaxWsPortClientInterceptor
pf.addInterface(getServiceInterface());
pf.addInterface(BindingProvider.class);
pf.addAdvice(this);
this.serviceProxy = pf.getProxy(this.beanClassLoader);
this.serviceProxy = pf.getProxy(getBeanClassLoader());
}
......
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2010 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.
......@@ -18,14 +18,15 @@ package org.springframework.remoting.jaxws;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceRef;
import javax.xml.ws.soap.AddressingFeature;
import junit.framework.TestCase;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.support.GenericBeanDefinition;
......@@ -37,9 +38,29 @@ import org.springframework.context.support.GenericApplicationContext;
* @author Juergen Hoeller
* @since 2.5
*/
public class JaxWsSupportTests extends TestCase {
public class JaxWsSupportTests {
@Test
public void testJaxWsPortAccess() throws Exception {
doTestJaxWsPortAccess((Object[]) null);
}
@Test
public void testJaxWsPortAccessWithFeatureObject() throws Exception {
doTestJaxWsPortAccess(new AddressingFeature());
}
@Test
public void testJaxWsPortAccessWithFeatureClass() throws Exception {
doTestJaxWsPortAccess(AddressingFeature.class);
}
@Test
public void testJaxWsPortAccessWithFeatureString() throws Exception {
doTestJaxWsPortAccess("javax.xml.ws.soap.AddressingFeature");
}
private void doTestJaxWsPortAccess(Object... features) throws Exception {
GenericApplicationContext ac = new GenericApplicationContext();
GenericBeanDefinition serviceDef = new GenericBeanDefinition();
......@@ -60,6 +81,9 @@ public class JaxWsSupportTests extends TestCase {
clientDef.getPropertyValues().add("serviceName", "OrderService");
clientDef.getPropertyValues().add("serviceInterface", OrderService.class);
clientDef.getPropertyValues().add("lookupServiceOnStartup", Boolean.FALSE);
if (features != null) {
clientDef.getPropertyValues().add("webServiceFeatures", features);
}
ac.registerBeanDefinition("client", clientDef);
GenericBeanDefinition serviceFactoryDef = new GenericBeanDefinition();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册