You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2012/05/29 18:30:53 UTC
svn commit: r1343822 - in /cxf/trunk:
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/
rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/
systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/
systests/jaxrs/src/test/reso...
Author: sergeyb
Date: Tue May 29 16:30:52 2012
New Revision: 1343822
URL: http://svn.apache.org/viewvc?rev=1343822&view=rev
Log:
[CXF-4349] Making it possible to produce xsi:type for JAXB root classes
Added:
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/SuperBook.java (with props)
Modified:
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java
cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java
cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java?rev=1343822&r1=1343821&r2=1343822&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/AbstractClient.java Tue May 29 16:30:52 2012
@@ -382,23 +382,20 @@ public abstract class AbstractClient imp
state.setResponseBuilder(currentResponseBuilder);
return rb;
}
- protected <T> void writeBody(T o, Message outMessage, Type type, Annotation[] anns,
- MultivaluedMap<String, Object> headers, OutputStream os) {
- @SuppressWarnings("unchecked")
- Class<T> cls = (Class<T>)o.getClass();
- writeBody(o, outMessage, cls, type, anns, headers, os);
- }
- protected <T> void writeBody(T o, Message outMessage, Class<T> cls, Type type, Annotation[] anns,
+
+ protected <T> void writeBody(T o, Message outMessage, Class<?> cls, Type type, Annotation[] anns,
MultivaluedMap<String, Object> headers, OutputStream os) {
if (o == null) {
return;
}
+ @SuppressWarnings("unchecked")
+ Class<T> theClass = (Class<T>)cls;
MediaType contentType = MediaType.valueOf(headers.getFirst("Content-Type").toString());
MessageBodyWriter<T> mbw = ProviderFactory.getInstance(outMessage)
- .createMessageBodyWriter(cls, type, anns, contentType, outMessage);
+ .createMessageBodyWriter(theClass, type, anns, contentType, outMessage);
if (mbw != null) {
try {
mbw.writeTo(o, cls, type, anns, contentType, headers, os);
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java?rev=1343822&r1=1343821&r2=1343822&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java Tue May 29 16:30:52 2012
@@ -633,10 +633,11 @@ public class ClientProxyImpl extends Abs
try {
if (bodyIndex != -1) {
writeBody(body, outMessage,
+ method.getParameterTypes()[bodyIndex],
method.getGenericParameterTypes()[bodyIndex],
anns, headers, os);
} else {
- writeBody(body, outMessage, body.getClass(),
+ writeBody(body, outMessage, body.getClass(), body.getClass(),
anns, headers, os);
}
} catch (Exception ex) {
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java?rev=1343822&r1=1343821&r2=1343822&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java Tue May 29 16:30:52 2012
@@ -64,6 +64,7 @@ import org.apache.cxf.phase.Phase;
*
*/
public class WebClient extends AbstractClient {
+ private static final String REQUEST_CLASS = "request.class";
private static final String REQUEST_TYPE = "request.type";
private static final String RESPONSE_CLASS = "response.class";
private static final String RESPONSE_TYPE = "response.type";
@@ -345,6 +346,20 @@ public class WebClient extends AbstractC
}
/**
+ * Does HTTP invocation and returns types response object
+ * @param httpMethod HTTP method
+ * @param body request body, can be null
+ * @param requestClass request body class
+ * @param responseClass expected type of response object
+ * @return typed object, can be null. Response status code and headers
+ * can be obtained too, see Client.getResponse()
+ */
+ public <T> T invoke(String httpMethod, Object body, Class<?> requestClass, Class<T> responseClass) {
+ Response r = doInvoke(httpMethod, body, requestClass, null, responseClass, responseClass);
+ return responseClass.cast(responseClass == Response.class ? r : r.getEntity());
+ }
+
+ /**
* Does HTTP POST invocation and returns typed response object
* @param body request body, can be null
* @param responseClass expected type of response object
@@ -694,8 +709,21 @@ public class WebClient extends AbstractC
return (WebClient)super.reset();
}
- protected Response doInvoke(String httpMethod, Object body, Type inGenericType,
- Class<?> responseClass, Type outGenericType) {
+ protected Response doInvoke(String httpMethod,
+ Object body,
+ Type inGenericType,
+ Class<?> responseClass,
+ Type outGenericType) {
+ return doInvoke(httpMethod, body, body == null ? null : body.getClass(), inGenericType,
+ responseClass, outGenericType);
+ }
+
+ protected Response doInvoke(String httpMethod,
+ Object body,
+ Class<?> requestClass,
+ Type inGenericType,
+ Class<?> responseClass,
+ Type outGenericType) {
MultivaluedMap<String, String> headers = getHeaders();
boolean contentTypeNotSet = headers.getFirst(HttpHeaders.CONTENT_TYPE) == null;
@@ -712,7 +740,7 @@ public class WebClient extends AbstractC
headers.putSingle(HttpHeaders.ACCEPT, MediaType.APPLICATION_XML_TYPE.toString());
}
resetResponse();
- Response r = doChainedInvocation(httpMethod, headers, body, inGenericType,
+ Response r = doChainedInvocation(httpMethod, headers, body, requestClass, inGenericType,
responseClass, outGenericType, null, null);
if (r.getStatus() >= 400 && responseClass != Response.class) {
throw new ServerWebApplicationException(r);
@@ -729,16 +757,18 @@ public class WebClient extends AbstractC
Map<String, Object> reqContext = CastUtils.cast((Map<?, ?>)invContext.get(REQUEST_CONTEXT));
String httpMethod = (String)reqContext.get(Message.HTTP_REQUEST_METHOD);
+ Class<?> requestClass = (Class<?>)reqContext.get(REQUEST_CLASS);
Type inType = (Type)reqContext.get(REQUEST_TYPE);
Class<?> respClass = (Class<?>)reqContext.get(RESPONSE_CLASS);
Type outType = (Type)reqContext.get(RESPONSE_TYPE);
- return doChainedInvocation(httpMethod, headers, body, inType,
+ return doChainedInvocation(httpMethod, headers, body, requestClass, inType,
respClass, outType, exchange, invContext);
}
//CHECKSTYLE:OFF
protected Response doChainedInvocation(String httpMethod,
MultivaluedMap<String, String> headers,
Object body,
+ Class<?> requestClass,
Type inGenericType,
Class<?> responseClass,
Type outGenericType,
@@ -751,6 +781,7 @@ public class WebClient extends AbstractC
Map<String, Object> reqContext = getRequestContext(m);
reqContext.put(Message.HTTP_REQUEST_METHOD, httpMethod);
+ reqContext.put(REQUEST_CLASS, requestClass);
reqContext.put(REQUEST_TYPE, inGenericType);
reqContext.put(RESPONSE_CLASS, responseClass);
reqContext.put(RESPONSE_TYPE, outGenericType);
@@ -843,12 +874,16 @@ public class WebClient extends AbstractC
Object body = objs.get(0);
Map<String, Object> requestContext = WebClient.this.getRequestContext(outMessage);
- Type type = null;
+ Class<?> requestClass = null;
+ Type requestType = null;
if (requestContext != null) {
- type = (Type)requestContext.get(REQUEST_TYPE);
+ requestClass = (Class<?>)requestContext.get(REQUEST_CLASS);
+ requestType = (Type)requestContext.get(REQUEST_TYPE);
}
try {
- writeBody(body, outMessage, type == null ? body.getClass() : type,
+ writeBody(body, outMessage,
+ requestClass == null ? body.getClass() : requestClass,
+ requestType == null ? body.getClass() : requestType,
new Annotation[]{}, headers, os);
if (os != null) {
os.flush();
Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java?rev=1343822&r1=1343821&r2=1343822&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java (original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/interceptor/JAXRSOutInterceptor.java Tue May 29 16:30:52 2012
@@ -207,8 +207,8 @@ public class JAXRSOutInterceptor extends
? ori.getMethodToInvoke() : ori.getAnnotatedMethod();
}
- Class<?> targetType = getRawResponseClass(responseObj);
- Type genericType = getGenericResponseType(ori == null ? null : invoked, responseObj, targetType);
+ Class<?> targetType = getRawResponseClass(invoked, responseObj);
+ Type genericType = getGenericResponseType(invoked, responseObj, targetType);
if (genericType instanceof TypeVariable) {
genericType = InjectionUtils.getSuperType(ori.getClassResourceInfo().getServiceClass(),
(TypeVariable<?>)genericType);
@@ -432,11 +432,14 @@ public class JAXRSOutInterceptor extends
}
- private Class<?> getRawResponseClass(Object targetObject) {
+ private Class<?> getRawResponseClass(Method invoked, Object targetObject) {
if (GenericEntity.class.isAssignableFrom(targetObject.getClass())) {
return ((GenericEntity<?>)targetObject).getRawType();
} else {
- return ClassHelper.getRealClassFromClass(targetObject.getClass());
+ Class<?> targetClass = targetObject.getClass();
+ Class<?> responseClass = invoked == null
+ || !invoked.getReturnType().isAssignableFrom(targetClass) ? targetClass : invoked.getReturnType();
+ return ClassHelper.getRealClassFromClass(responseClass);
}
}
Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java?rev=1343822&r1=1343821&r2=1343822&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java Tue May 29 16:30:52 2012
@@ -81,6 +81,21 @@ public class BookStoreSpring {
}
@GET
+ @Path("/books/xsitype")
+ @Produces("application/xml")
+ public Book getBookXsiType() {
+ return new SuperBook("SuperBook", 999L);
+ }
+
+ @POST
+ @Path("/books/xsitype")
+ @Produces("application/xml")
+ @Consumes("application/xml")
+ public Book postGetBookXsiType(Book book) {
+ return book;
+ }
+
+ @GET
@Path("/books/{id}")
@Produces({"application/json", "application/vnd.example-com.foo+json" })
public Book getBookById(@PathParam("id") Long id) {
Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java?rev=1343822&r1=1343821&r2=1343822&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java (original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java Tue May 29 16:30:52 2012
@@ -312,6 +312,45 @@ public class JAXRSClientServerSpringBook
}
@Test
+ public void testGetBookXsiType() throws Exception {
+ String address = "http://localhost:" + PORT + "/the/thebooksxsi/bookstore/books/xsitype";
+ WebClient wc = WebClient.create(address);
+ wc.accept("application/xml");
+ Book book = wc.get(Book.class);
+ assertEquals("SuperBook", book.getName());
+
+ }
+
+ @Test
+ public void testPostBookXsiType() throws Exception {
+ String address = "http://localhost:" + PORT + "/the/thebooksxsi/bookstore/books/xsitype";
+ JAXBElementProvider<Book> provider = new JAXBElementProvider<Book>();
+ provider.setExtraClass(new Class[]{SuperBook.class});
+ provider.setJaxbElementClassNames(Collections.singletonList(Book.class.getName()));
+ WebClient wc = WebClient.create(address, Collections.singletonList(provider));
+ wc.accept("application/xml");
+ wc.type("application/xml");
+ SuperBook book = new SuperBook("SuperBook2", 999L);
+ Book book2 = wc.invoke("POST", book, Book.class, Book.class);
+ assertEquals("SuperBook2", book2.getName());
+
+ }
+
+ @Test
+ public void testPostBookXsiTypeProxy() throws Exception {
+ String address = "http://localhost:" + PORT + "/the/thebooksxsi/bookstore";
+ JAXBElementProvider<Book> provider = new JAXBElementProvider<Book>();
+ provider.setExtraClass(new Class[]{SuperBook.class});
+ provider.setJaxbElementClassNames(Collections.singletonList(Book.class.getName()));
+ BookStoreSpring bookStore = JAXRSClientFactory.create(address, BookStoreSpring.class,
+ Collections.singletonList(provider));
+ SuperBook book = new SuperBook("SuperBook2", 999L);
+ Book book2 = bookStore.postGetBookXsiType(book);
+ assertEquals("SuperBook2", book2.getName());
+
+ }
+
+ @Test
public void testGetBookWithEncodedQueryValue() throws Exception {
String endpointAddress =
"http://localhost:" + PORT + "/the/bookstore/booksquery?id=12%2B3";
Added: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/SuperBook.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/SuperBook.java?rev=1343822&view=auto
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/SuperBook.java (added)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/SuperBook.java Tue May 29 16:30:52 2012
@@ -0,0 +1,35 @@
+/**
+ * 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.systest.jaxrs;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+@XmlRootElement(name = "SuperBook")
+public class SuperBook extends Book {
+
+ public SuperBook() {
+
+ }
+
+ public SuperBook(String name, long id) {
+ super(name, id);
+ }
+}
Propchange: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/SuperBook.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/SuperBook.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml?rev=1343822&r1=1343821&r2=1343822&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml (original)
+++ cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml Tue May 29 16:30:52 2012
@@ -88,6 +88,19 @@ http://cxf.apache.org/schemas/core.xsd">
</jaxrs:features>
</jaxrs:server>
+ <jaxrs:server id="booksxsi"
+ address="/thebooksxsi/bookstore">
+ <jaxrs:serviceBeans>
+ <ref bean="serviceBean" />
+ </jaxrs:serviceBeans>
+ <jaxrs:providers>
+ <ref bean="jaxbProviderXsi"/>
+ </jaxrs:providers>
+ <jaxrs:features>
+ <cxf:logging/>
+ </jaxrs:features>
+ </jaxrs:server>
+
<jaxrs:server id="bookservice4"
address="/thebooks4/bookstore">
<jaxrs:serviceBeans>
@@ -239,6 +252,18 @@ http://cxf.apache.org/schemas/core.xsd">
<property name="schemaHandler" ref="schemaHolder"/>
</bean>
+ <util:list id="jaxbClasses">
+ <value>org.apache.cxf.systest.jaxrs.Book</value>
+ </util:list>
+ <bean id="jaxbProviderXsi" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
+ <property name="jaxbElementClassNames" ref="jaxbClasses"/>
+ <property name="extraClass">
+ <list>
+ <value>org.apache.cxf.systest.jaxrs.SuperBook</value>
+ </list>
+ </property>
+ </bean>
+
<bean id="schemaHolder" class="org.apache.cxf.jaxrs.utils.schemas.SchemaHandler">
<property name="schemas" ref="theSchemas"/>
</bean>