Repository: cxf Updated Branches: refs/heads/master 71376c2e3 -> 75093fe6a
[CXF-7157] Support for the client side bean validation for JAX-RS and JAX-WS (further minor updates might be needed for JAX-WS) Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/75093fe6 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/75093fe6 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/75093fe6 Branch: refs/heads/master Commit: 75093fe6a833af5c96b136005dc9d993123adc9e Parents: 71376c2 Author: Sergey Beryozkin <[email protected]> Authored: Mon Nov 28 15:00:12 2016 +0000 Committer: Sergey Beryozkin <[email protected]> Committed: Mon Nov 28 15:00:12 2016 +0000 ---------------------------------------------------------------------- .../AbstractBeanValidationInterceptor.java | 63 ++++++++++++++++++++ .../AbstractValidationInterceptor.java | 20 ++++--- .../cxf/validation/BeanValidationFeature.java | 5 +- .../validation/BeanValidationInInterceptor.java | 39 +----------- .../validation/ClientBeanValidationFeature.java | 50 ++++++++++++++++ .../ClientBeanValidationOutInterceptor.java | 30 ++++++++++ .../cxf/jaxrs/client/ClientProxyImpl.java | 21 ++++--- .../jaxrs/client/JAXRSClientFactoryBean.java | 1 + .../JAXRSClientBeanValidationFeature.java | 40 +++++++++++++ ...JAXRSClientBeanValidationOutInterceptor.java | 40 +++++++++++++ .../JAXRSClientServerValidationSpringTest.java | 24 ++++++++ 11 files changed, 279 insertions(+), 54 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/75093fe6/core/src/main/java/org/apache/cxf/validation/AbstractBeanValidationInterceptor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/validation/AbstractBeanValidationInterceptor.java b/core/src/main/java/org/apache/cxf/validation/AbstractBeanValidationInterceptor.java new file mode 100644 index 0000000..a7b25e0 --- /dev/null +++ b/core/src/main/java/org/apache/cxf/validation/AbstractBeanValidationInterceptor.java @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.validation; + +import java.lang.reflect.Method; +import java.util.List; + +import javax.validation.ValidationException; + +import org.apache.cxf.message.Message; + +public abstract class AbstractBeanValidationInterceptor extends AbstractValidationInterceptor { + protected AbstractBeanValidationInterceptor(String phase) { + super(phase); + } + + protected Object getServiceObject(Message message) { + return checkNotNull(super.getServiceObject(message), "SERVICE_OBJECT_NULL"); + } + + protected Method getServiceMethod(Message message) { + return (Method)checkNotNull(super.getServiceMethod(message), "SERVICE_METHOD_NULL"); + } + + private Object checkNotNull(Object object, String name) { + if (object == null) { + String message = new org.apache.cxf.common.i18n.Message(name, BUNDLE).toString(); + LOG.severe(message); + throw new ValidationException(message.toString()); + } + return object; + } + + @Override + protected void handleValidation(final Message message, final Object resourceInstance, + final Method method, final List<Object> arguments) { + if (arguments.size() > 0) { + BeanValidationProvider provider = getProvider(message); + provider.validateParameters(resourceInstance, method, unwrapArgs(arguments).toArray()); + message.getExchange().put(BeanValidationProvider.class, provider); + } + } + + protected List<Object> unwrapArgs(List<Object> arguments) { + return arguments; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/75093fe6/core/src/main/java/org/apache/cxf/validation/AbstractValidationInterceptor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/validation/AbstractValidationInterceptor.java b/core/src/main/java/org/apache/cxf/validation/AbstractValidationInterceptor.java index 266d2c9..821d7d1 100644 --- a/core/src/main/java/org/apache/cxf/validation/AbstractValidationInterceptor.java +++ b/core/src/main/java/org/apache/cxf/validation/AbstractValidationInterceptor.java @@ -96,15 +96,21 @@ public abstract class AbstractValidationInterceptor extends AbstractPhaseInterce protected Method getServiceMethod(Message message) { Message inMessage = message.getExchange().getInMessage(); - Method method = (Method)inMessage.get("org.apache.cxf.resource.method"); - if (method == null) { - BindingOperationInfo bop = inMessage.getExchange().getBindingOperationInfo(); - if (bop != null) { - MethodDispatcher md = (MethodDispatcher) - inMessage.getExchange().getService().get(MethodDispatcher.class.getName()); - method = md.getMethod(bop); + Method method = null; + if (inMessage != null) { + method = (Method)inMessage.get("org.apache.cxf.resource.method"); + if (method == null) { + BindingOperationInfo bop = inMessage.getExchange().getBindingOperationInfo(); + if (bop != null) { + MethodDispatcher md = (MethodDispatcher) + inMessage.getExchange().getService().get(MethodDispatcher.class.getName()); + method = md.getMethod(bop); + } } } + if (method == null) { + method = message.getExchange().get(Method.class); + } return method; } http://git-wip-us.apache.org/repos/asf/cxf/blob/75093fe6/core/src/main/java/org/apache/cxf/validation/BeanValidationFeature.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/validation/BeanValidationFeature.java b/core/src/main/java/org/apache/cxf/validation/BeanValidationFeature.java index e5516fc..f4f1ef1 100644 --- a/core/src/main/java/org/apache/cxf/validation/BeanValidationFeature.java +++ b/core/src/main/java/org/apache/cxf/validation/BeanValidationFeature.java @@ -19,10 +19,13 @@ package org.apache.cxf.validation; import org.apache.cxf.Bus; +import org.apache.cxf.annotations.Provider; +import org.apache.cxf.annotations.Provider.Scope; +import org.apache.cxf.annotations.Provider.Type; import org.apache.cxf.feature.AbstractFeature; import org.apache.cxf.interceptor.InterceptorProvider; - +@Provider(value = Type.Feature, scope = Scope.Server) public class BeanValidationFeature extends AbstractFeature { private BeanValidationProvider validationProvider; http://git-wip-us.apache.org/repos/asf/cxf/blob/75093fe6/core/src/main/java/org/apache/cxf/validation/BeanValidationInInterceptor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/validation/BeanValidationInInterceptor.java b/core/src/main/java/org/apache/cxf/validation/BeanValidationInInterceptor.java index 15d1b67..2e87f96 100644 --- a/core/src/main/java/org/apache/cxf/validation/BeanValidationInInterceptor.java +++ b/core/src/main/java/org/apache/cxf/validation/BeanValidationInInterceptor.java @@ -18,50 +18,13 @@ */ package org.apache.cxf.validation; -import java.lang.reflect.Method; -import java.util.List; - -import javax.validation.ValidationException; - -import org.apache.cxf.message.Message; import org.apache.cxf.phase.Phase; -public class BeanValidationInInterceptor extends AbstractValidationInterceptor { +public class BeanValidationInInterceptor extends AbstractBeanValidationInterceptor { public BeanValidationInInterceptor() { super(Phase.PRE_INVOKE); } public BeanValidationInInterceptor(String phase) { super(phase); } - - protected Object getServiceObject(Message message) { - return checkNotNull(super.getServiceObject(message), "SERVICE_OBJECT_NULL"); - } - - protected Method getServiceMethod(Message message) { - return (Method)checkNotNull(super.getServiceMethod(message), "SERVICE_METHOD_NULL"); - } - - private Object checkNotNull(Object object, String name) { - if (object == null) { - String message = new org.apache.cxf.common.i18n.Message(name, BUNDLE).toString(); - LOG.severe(message); - throw new ValidationException(message.toString()); - } - return object; - } - - @Override - protected void handleValidation(final Message message, final Object resourceInstance, - final Method method, final List<Object> arguments) { - if (arguments.size() > 0) { - BeanValidationProvider provider = getProvider(message); - provider.validateParameters(resourceInstance, method, unwrapArgs(arguments).toArray()); - message.getExchange().put(BeanValidationProvider.class, provider); - } - } - - protected List<Object> unwrapArgs(List<Object> arguments) { - return arguments; - } } http://git-wip-us.apache.org/repos/asf/cxf/blob/75093fe6/core/src/main/java/org/apache/cxf/validation/ClientBeanValidationFeature.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/validation/ClientBeanValidationFeature.java b/core/src/main/java/org/apache/cxf/validation/ClientBeanValidationFeature.java new file mode 100644 index 0000000..67caff2 --- /dev/null +++ b/core/src/main/java/org/apache/cxf/validation/ClientBeanValidationFeature.java @@ -0,0 +1,50 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.validation; + +import org.apache.cxf.Bus; +import org.apache.cxf.annotations.Provider; +import org.apache.cxf.annotations.Provider.Scope; +import org.apache.cxf.annotations.Provider.Type; +import org.apache.cxf.feature.AbstractFeature; +import org.apache.cxf.interceptor.InterceptorProvider; + +@Provider(value = Type.Feature, scope = Scope.Client) +public class ClientBeanValidationFeature extends AbstractFeature { + + private BeanValidationProvider validationProvider; + + @Override + protected void initializeProvider(InterceptorProvider interceptorProvider, Bus bus) { + ClientBeanValidationOutInterceptor out = new ClientBeanValidationOutInterceptor(); + addInterceptor(interceptorProvider, out); + } + + protected void addInterceptor(InterceptorProvider interceptorProvider, ClientBeanValidationOutInterceptor out) { + if (validationProvider != null) { + out.setProvider(validationProvider); + } + interceptorProvider.getOutInterceptors().add(out); + + } + + public void setProvider(BeanValidationProvider provider) { + this.validationProvider = provider; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/75093fe6/core/src/main/java/org/apache/cxf/validation/ClientBeanValidationOutInterceptor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/validation/ClientBeanValidationOutInterceptor.java b/core/src/main/java/org/apache/cxf/validation/ClientBeanValidationOutInterceptor.java new file mode 100644 index 0000000..c8e0401 --- /dev/null +++ b/core/src/main/java/org/apache/cxf/validation/ClientBeanValidationOutInterceptor.java @@ -0,0 +1,30 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.validation; + +import org.apache.cxf.phase.Phase; + +public class ClientBeanValidationOutInterceptor extends AbstractBeanValidationInterceptor { + public ClientBeanValidationOutInterceptor() { + super(Phase.PRE_LOGICAL); + } + public ClientBeanValidationOutInterceptor(String phase) { + super(phase); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/75093fe6/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java ---------------------------------------------------------------------- diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java index af3c015..221cbd4 100644 --- a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java +++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java @@ -96,8 +96,7 @@ public class ClientProxyImpl extends AbstractClient implements private static final ResourceBundle BUNDLE = BundleUtils.getBundle(ClientProxyImpl.class); private static final String SLASH = "/"; private static final String BUFFER_PROXY_RESPONSE = "buffer.proxy.response"; - private static final String METHOD_PARAM_BODY_INDEX = "method.parameter.body.index"; - private static final String METHOD_PARAMS = "method.parameters"; + private static final String PROXY_METHOD_PARAM_BODY_INDEX = "proxy.method.parameter.body.index"; private ClassResourceInfo cri; private ClassLoader proxyLoader; @@ -105,6 +104,7 @@ public class ClientProxyImpl extends AbstractClient implements private boolean isRoot; private Map<String, Object> valuesMap = Collections.emptyMap(); private BodyWriter bodyWriter = new BodyWriter(); + private Client proxy; public ClientProxyImpl(URI baseURI, ClassLoader loader, ClassResourceInfo cri, @@ -128,7 +128,9 @@ public class ClientProxyImpl extends AbstractClient implements initValuesMap(varValues); cfg.getInInterceptors().add(new ClientAsyncResponseInterceptor()); } - + void setProxyClient(Client client) { + this.proxy = client; + } private void initValuesMap(Object... varValues) { if (isRoot) { List<String> vars = cri.getURITemplate().getVariables(); @@ -732,15 +734,18 @@ public class ClientProxyImpl extends AbstractClient implements outMessage.put(Annotation.class.getName(), getMethodAnnotations(ori.getAnnotatedMethod(), bodyIndex)); - outMessage.put(METHOD_PARAMS, methodParams); + outMessage.getExchange().put(Message.SERVICE_OBJECT, proxy); + if (methodParams != null) { + outMessage.put(List.class, Arrays.asList(methodParams)); + } if (body != null) { - outMessage.put(METHOD_PARAM_BODY_INDEX, bodyIndex); + outMessage.put(PROXY_METHOD_PARAM_BODY_INDEX, bodyIndex); } outMessage.getInterceptorChain().add(bodyWriter); Map<String, Object> reqContext = getRequestContext(outMessage); reqContext.put(OperationResourceInfo.class.getName(), ori); - reqContext.put(METHOD_PARAM_BODY_INDEX, bodyIndex); + reqContext.put(PROXY_METHOD_PARAM_BODY_INDEX, bodyIndex); // execute chain InvocationCallback<Object> asyncCallback = checkAsyncCallback(ori, reqContext); @@ -828,7 +833,7 @@ public class ClientProxyImpl extends AbstractClient implements Map<String, Object> invContext) throws Throwable { Map<String, Object> reqContext = CastUtils.cast((Map<?, ?>)invContext.get(REQUEST_CONTEXT)); - int bodyIndex = body != null ? (Integer)reqContext.get(METHOD_PARAM_BODY_INDEX) : -1; + int bodyIndex = body != null ? (Integer)reqContext.get(PROXY_METHOD_PARAM_BODY_INDEX) : -1; OperationResourceInfo ori = (OperationResourceInfo)reqContext.get(OperationResourceInfo.class.getName()); return doChainedInvocation(newRequestURI, headers, ori, null, @@ -906,7 +911,7 @@ public class ClientProxyImpl extends AbstractClient implements } Method method = ori.getMethodToInvoke(); - int bodyIndex = (Integer)outMessage.get(METHOD_PARAM_BODY_INDEX); + int bodyIndex = (Integer)outMessage.get(PROXY_METHOD_PARAM_BODY_INDEX); Annotation[] anns = customAnns != null ? customAnns : getMethodAnnotations(ori.getAnnotatedMethod(), bodyIndex); http://git-wip-us.apache.org/repos/asf/cxf/blob/75093fe6/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java ---------------------------------------------------------------------- diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java index 936c43d..79d8b04 100644 --- a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java +++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JAXRSClientFactoryBean.java @@ -323,6 +323,7 @@ public class JAXRSClientFactoryBean extends AbstractJAXRSFactoryBean { ClassLoader theLoader = proxyLoader == null ? cri.getServiceClass().getClassLoader() : proxyLoader; Class<?>[] ifaces = new Class[]{Client.class, InvocationHandlerAware.class, cri.getServiceClass()}; Client actualClient = (Client)ProxyHelper.getProxy(theLoader, ifaces, proxyImpl); + proxyImpl.setProxyClient(actualClient); notifyLifecycleManager(actualClient); this.getServiceFactory().sendEvent(FactoryBeanListener.Event.CLIENT_CREATED, actualClient, ep); return actualClient; http://git-wip-us.apache.org/repos/asf/cxf/blob/75093fe6/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/validation/JAXRSClientBeanValidationFeature.java ---------------------------------------------------------------------- diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/validation/JAXRSClientBeanValidationFeature.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/validation/JAXRSClientBeanValidationFeature.java new file mode 100644 index 0000000..9e45eab --- /dev/null +++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/validation/JAXRSClientBeanValidationFeature.java @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.jaxrs.client.validation; + +import org.apache.cxf.Bus; +import org.apache.cxf.annotations.Provider; +import org.apache.cxf.annotations.Provider.Scope; +import org.apache.cxf.annotations.Provider.Type; +import org.apache.cxf.interceptor.InterceptorProvider; +import org.apache.cxf.validation.ClientBeanValidationFeature; + +@Provider(value = Type.Feature, scope = Scope.Client) +public class JAXRSClientBeanValidationFeature extends ClientBeanValidationFeature { + private boolean wrapInProcessingException; + @Override + protected void initializeProvider(InterceptorProvider interceptorProvider, Bus bus) { + JAXRSClientBeanValidationOutInterceptor out = new JAXRSClientBeanValidationOutInterceptor(); + out.setWrapInProcessingException(wrapInProcessingException); + super.addInterceptor(interceptorProvider, out); + } + public void setWrapInProcessingException(boolean wrapInProcessingException) { + this.wrapInProcessingException = wrapInProcessingException; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/75093fe6/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/validation/JAXRSClientBeanValidationOutInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/validation/JAXRSClientBeanValidationOutInterceptor.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/validation/JAXRSClientBeanValidationOutInterceptor.java new file mode 100644 index 0000000..c2c155b --- /dev/null +++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/validation/JAXRSClientBeanValidationOutInterceptor.java @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cxf.jaxrs.client.validation; + +import java.lang.reflect.Method; +import java.util.List; + +import org.apache.cxf.message.Message; +import org.apache.cxf.validation.ClientBeanValidationOutInterceptor; + +public class JAXRSClientBeanValidationOutInterceptor extends ClientBeanValidationOutInterceptor { + private boolean wrapInProcessingException; + + @Override + protected void handleValidation(Message message, Object resourceInstance, + Method method, List<Object> arguments) { + message.getExchange().put("wrap.in.processing.exception", wrapInProcessingException); + super.handleValidation(message, resourceInstance, method, arguments); + } + + public void setWrapInProcessingException(boolean wrapInProcessingException) { + this.wrapInProcessingException = wrapInProcessingException; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/75093fe6/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/spring/JAXRSClientServerValidationSpringTest.java ---------------------------------------------------------------------- diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/spring/JAXRSClientServerValidationSpringTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/spring/JAXRSClientServerValidationSpringTest.java index b067b39..73cb899 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/spring/JAXRSClientServerValidationSpringTest.java +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/validation/spring/JAXRSClientServerValidationSpringTest.java @@ -18,6 +18,9 @@ */ package org.apache.cxf.systest.jaxrs.validation.spring; +import java.util.Arrays; + +import javax.validation.ConstraintViolationException; import javax.ws.rs.BadRequestException; import javax.ws.rs.core.Form; import javax.ws.rs.core.Response; @@ -28,6 +31,8 @@ import javax.xml.ws.soap.SOAPBinding; import javax.xml.ws.soap.SOAPFaultException; import org.apache.cxf.jaxrs.client.JAXRSClientFactory; +import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean; +import org.apache.cxf.jaxrs.client.validation.JAXRSClientBeanValidationFeature; import org.apache.cxf.jaxrs.model.AbstractResourceInfo; import org.apache.cxf.systest.jaxrs.AbstractSpringServer; import org.apache.cxf.systest.jaxrs.validation.AbstractJAXRSValidationTest; @@ -95,6 +100,25 @@ public class JAXRSClientServerValidationSpringTest extends AbstractJAXRSValidati } } + + @Test + public void testHelloRestValidationFailsIfNameIsNullClient() throws Exception { + JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean(); + bean.setAddress("http://localhost:" + PORT + "/bwrest"); + bean.setServiceClass(BookWorld.class); + bean.setFeatures(Arrays.asList(new JAXRSClientBeanValidationFeature())); + BookWorld service = bean.create(BookWorld.class); + BookWithValidation bw = service.echoBook(new BookWithValidation("RS", "123")); + assertEquals("123", bw.getId()); + + try { + service.echoBook(new BookWithValidation(null, "123")); + fail("Validation failure expected"); + } catch (ConstraintViolationException ex) { + // complete + } + + } @Test public void testHelloSoapValidationFailsIfNameIsNull() throws Exception { final QName serviceName = new QName("http://bookworld.com", "BookWorld");
