Author: sergeyb
Date: Tue Jun 21 22:27:11 2011
New Revision: 1138221
URL: http://svn.apache.org/viewvc?rev=1138221&view=rev
Log:
Merged revisions 1138220 via svnmerge from
https://svn.apache.org/repos/asf/cxf/trunk
........
r1138220 | sergeyb | 2011-06-21 23:24:33 +0100 (Tue, 21 Jun 2011) | 1 line
[CXF-3610] Enhancing WebClient to support posting explicit collections
........
Modified:
cxf/branches/2.4.x-fixes/ (props changed)
cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
Propchange: cxf/branches/2.4.x-fixes/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Jun 21 22:27:11 2011
@@ -1 +1 @@
-/cxf/trunk:1137793,1137960
+/cxf/trunk:1137793,1137960,1138220
Propchange: cxf/branches/2.4.x-fixes/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Jun 21 22:27:11 2011
@@ -1 +1 @@
-/cxf/trunk:1-1134023,1134142,1134248,1134281,1134523,1134526,1135106,1135457,1135484,1135899,1136380,1136417,1136837,1136860,1136933,1136942-1136953,1136960,1137509,1137658-1137678,1137793,1137960
+/cxf/trunk:1-1134023,1134142,1134248,1134281,1134523,1134526,1135106,1135457,1135484,1135899,1136380,1136417,1136837,1136860,1136933,1136942-1136953,1136960,1137509,1137658-1137678,1137793,1137960,1138220
Modified:
cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java?rev=1138221&r1=1138220&r2=1138221&view=diff
==============================================================================
---
cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
(original)
+++
cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java
Tue Jun 21 22:27:11 2011
@@ -63,7 +63,7 @@ import org.apache.cxf.phase.Phase;
*
*/
public class WebClient extends AbstractClient {
-
+ private static final String REQUEST_TYPE = "request.type";
private static final String RESPONSE_CLASS = "response.class";
private static final String RESPONSE_TYPE = "response.type";
@@ -239,7 +239,7 @@ public class WebClient extends AbstractC
* error message if client or server error occured
*/
public Response invoke(String httpMethod, Object body) {
- return doInvoke(httpMethod, body, Response.class, Response.class);
+ return doInvoke(httpMethod, body, null, Response.class,
Response.class);
}
/**
@@ -299,7 +299,7 @@ public class WebClient extends AbstractC
*/
public Response form(Map<String, List<Object>> values) {
type(MediaType.APPLICATION_FORM_URLENCODED_TYPE);
- return doInvoke("POST", values, InputStream.class, InputStream.class);
+ return doInvoke("POST", values, null, InputStream.class,
InputStream.class);
}
/**
@@ -309,7 +309,7 @@ public class WebClient extends AbstractC
*/
public Response form(Form form) {
type(MediaType.APPLICATION_FORM_URLENCODED_TYPE);
- return doInvoke("POST", form.getData(), InputStream.class,
InputStream.class);
+ return doInvoke("POST", form.getData(), null, InputStream.class,
InputStream.class);
}
/**
@@ -321,14 +321,19 @@ public class WebClient extends AbstractC
* can be obtained too, see Client.getResponse()
*/
public <T> T invoke(String httpMethod, Object body, Class<T>
responseClass) {
-
- Response r = doInvoke(httpMethod, body, responseClass, responseClass);
-
- if (r.getStatus() >= 400 && responseClass != null) {
- throw new ServerWebApplicationException(r);
- }
-
- return responseClass.cast(r.getEntity());
+ Response r = doInvoke(httpMethod, body, 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
+ * @return typed object, can be null. Response status code and headers
+ * can be obtained too, see Client.getResponse()
+ */
+ public <T> T post(Object body, Class<T> responseClass) {
+ return invoke("POST", body, responseClass);
}
/**
@@ -340,29 +345,53 @@ public class WebClient extends AbstractC
*/
public <T> Collection<? extends T> invokeAndGetCollection(String
httpMethod, Object body,
Class<T> memberClass) {
- Response r = doInvoke(httpMethod, body, Collection.class,
- new ParameterizedCollectionType<T>(memberClass));
-
- if (r.getStatus() >= 400) {
- throw new ServerWebApplicationException(r);
- }
-
+ Response r = doInvoke(httpMethod, body, null,
+ Collection.class, new
ParameterizedCollectionType<T>(memberClass));
return CastUtils.cast((Collection)r.getEntity(), memberClass);
}
/**
- * Does HTTP POST invocation and returns typed response object
- * @param body request body, can be null
+ * Posts a collection of typed objects
+ * @param collection request body
+ * @param memberClass type of collection member class
+ * @return JAX-RS Response
+ */
+ public <T> Response postCollection(Object collection, Class<T>
memberClass) {
+ return doInvoke("POST", collection, new
ParameterizedCollectionType<T>(memberClass),
+ Response.class, Response.class);
+ }
+
+ /**
+ * Posts a collection of typed objects
+ * @param collection request body
+ * @param memberClass type of collection member 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()
+ * @return JAX-RS Response
*/
- public <T> T post(Object body, Class<T> responseClass) {
- return invoke("POST", body, responseClass);
+ public <T1, T2> T2 postCollection(Object collection, Class<T1>
memberClass,
+ Class<T2> responseClass) {
+ Response r = doInvoke("POST", collection, new
ParameterizedCollectionType<T1>(memberClass),
+ responseClass, responseClass);
+ return responseClass.cast(responseClass == Response.class ? r :
r.getEntity());
}
/**
- * Does HTTP POST invocation and returns a collection of typed objects
+ * Posts collection of typed objects and returns a collection of typed
objects
+ * @param collection request body
+ * @param memberClass type of collection member class
+ * @param responseClass expected type of response object
+ * @return JAX-RS Response
+ */
+ public <T1, T2> Collection<? extends T2> postAndGetCollection(Object
collection,
+ Class<T1>
memberClass,
+ Class<T2>
responseClass) {
+ Response r = doInvoke("POST", collection, new
ParameterizedCollectionType<T1>(memberClass),
+ Collection.class, new
ParameterizedCollectionType<T2>(responseClass));
+ return CastUtils.cast((Collection)r.getEntity(), responseClass);
+ }
+
+ /**
+ * Posts request body and returns a collection of typed objects
* @param body request body, can be null
* @param memberClass expected type of collection member class
* @return typed collection
@@ -617,7 +646,8 @@ public class WebClient extends AbstractC
return (WebClient)super.reset();
}
- protected Response doInvoke(String httpMethod, Object body, Class<?>
responseClass, Type genericType) {
+ protected Response doInvoke(String httpMethod, Object body, Type
inGenericType,
+ Class<?> responseClass, Type outGenericType) {
MultivaluedMap<String, String> headers = getHeaders();
if (body != null) {
@@ -631,7 +661,12 @@ public class WebClient extends AbstractC
headers.putSingle(HttpHeaders.ACCEPT,
MediaType.APPLICATION_XML_TYPE.toString());
}
resetResponse();
- return doChainedInvocation(httpMethod, headers, body, responseClass,
genericType, null, null);
+ Response r = doChainedInvocation(httpMethod, headers, body,
inGenericType,
+ responseClass, outGenericType, null,
null);
+ if (r.getStatus() >= 400 && responseClass != Response.class) {
+ throw new ServerWebApplicationException(r);
+ }
+ return r;
}
@Override
@@ -643,26 +678,30 @@ 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);
+ Type inType = (Type)reqContext.get(REQUEST_TYPE);
Class<?> respClass = (Class)reqContext.get(RESPONSE_CLASS);
- Type type = (Type)reqContext.get(RESPONSE_TYPE);
- return doChainedInvocation(httpMethod, headers, body, respClass, type,
exchange, invContext);
+ Type outType = (Type)reqContext.get(RESPONSE_TYPE);
+ return doChainedInvocation(httpMethod, headers, body, inType,
+ respClass, outType, exchange, invContext);
}
-
+ //CHECKSTYLE:OFF
protected Response doChainedInvocation(String httpMethod,
MultivaluedMap<String, String>
headers,
Object body,
+ Type inGenericType,
Class<?> responseClass,
- Type genericType,
+ Type outGenericType,
Exchange exchange,
Map<String, Object> invContext) {
-
+ //CHECKSTYLE:ON
URI uri = getCurrentURI();
Message m = createMessage(body, httpMethod, headers, uri, exchange,
invContext);
Map<String, Object> reqContext = getRequestContext(m);
reqContext.put(Message.HTTP_REQUEST_METHOD, httpMethod);
+ reqContext.put(REQUEST_TYPE, inGenericType);
reqContext.put(RESPONSE_CLASS, responseClass);
- reqContext.put(RESPONSE_TYPE, genericType);
+ reqContext.put(RESPONSE_TYPE, outGenericType);
if (body != null) {
m.getInterceptorChain().add(new BodyWriter());
@@ -691,7 +730,7 @@ public class WebClient extends AbstractC
Response response = null;
Object entity = null;
try {
- response = handleResponse(m, responseClass, genericType);
+ response = handleResponse(m, responseClass, outGenericType);
entity = response.getEntity();
return response;
} catch (RuntimeException ex) {
@@ -741,9 +780,15 @@ public class WebClient extends AbstractC
MultivaluedMap<String, String> headers =
(MultivaluedMap)outMessage.get(Message.PROTOCOL_HEADERS);
Object body = objs.get(0);
+
+ Map<String, Object> requestContext =
WebClient.this.getRequestContext(outMessage);
+ Type type = null;
+ if (requestContext != null) {
+ type = (Type)requestContext.get(REQUEST_TYPE);
+ }
try {
- writeBody(body, outMessage, body.getClass(), body.getClass(),
new Annotation[]{},
- headers, os);
+ writeBody(body, outMessage, body.getClass(), type == null ?
body.getClass() : type,
+ new Annotation[]{}, headers, os);
if (os != null) {
os.flush();
}
Modified:
cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java?rev=1138221&r1=1138220&r2=1138221&view=diff
==============================================================================
---
cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
(original)
+++
cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java
Tue Jun 21 22:27:11 2011
@@ -277,6 +277,17 @@ public class BookStore {
}
@POST
+ @Path("/collections3")
+ @Produces({"application/xml", "application/json" })
+ @Consumes({"application/xml", "application/json" })
+ public Book postCollectionGetBook(List<Book> bs) throws Exception {
+ if (bs == null || bs.size() != 2) {
+ throw new RuntimeException();
+ }
+ return bs.get(0);
+ }
+
+ @POST
@Path("/collections2")
@Produces({"application/xml", "application/json" })
@Consumes({"application/xml", "application/json" })
Modified:
cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
URL:
http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=1138221&r1=1138220&r2=1138221&view=diff
==============================================================================
---
cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
(original)
+++
cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
Tue Jun 21 22:27:11 2011
@@ -168,6 +168,49 @@ public class JAXRSClientServerBookTest e
}
@Test
+ public void testPostCollectionGetBooksWebClient() throws Exception {
+
+ String endpointAddress =
+ "http://localhost:" + PORT + "/bookstore/collections3";
+ WebClient wc = WebClient.create(endpointAddress);
+ wc.accept("application/xml").type("application/xml");
+ Book b1 = new Book("CXF in Action", 123L);
+ Book b2 = new Book("CXF Rocks", 124L);
+ List<Book> books = new ArrayList<Book>();
+ books.add(b1);
+ books.add(b2);
+ Book book = wc.postCollection(books, Book.class, Book.class);
+ assertEquals(200, wc.getResponse().getStatus());
+ assertNotSame(b1, book);
+ assertEquals(b1.getName(), book.getName());
+ }
+
+ @Test
+ public void testPostCollectionOfBooksWebClient() throws Exception {
+
+ String endpointAddress =
+ "http://localhost:" + PORT + "/bookstore/collections";
+ WebClient wc = WebClient.create(endpointAddress);
+ wc.accept("application/xml").type("application/xml");
+ Book b1 = new Book("CXF in Action", 123L);
+ Book b2 = new Book("CXF Rocks", 124L);
+ List<Book> books = new ArrayList<Book>();
+ books.add(b1);
+ books.add(b2);
+ List<Book> books2 = new ArrayList<Book>(wc.postAndGetCollection(books,
Book.class, Book.class));
+ assertNotNull(books2);
+ assertNotSame(books, books2);
+ assertEquals(2, books2.size());
+ Book b11 = books.get(0);
+ assertEquals(123L, b11.getId());
+ assertEquals("CXF in Action", b11.getName());
+ Book b22 = books.get(1);
+ assertEquals(124L, b22.getId());
+ assertEquals("CXF Rocks", b22.getName());
+ assertEquals(200, wc.getResponse().getStatus());
+ }
+
+ @Test
public void testGetBookResponseAndETag() throws Exception {
String endpointAddress =
@@ -303,6 +346,18 @@ public class JAXRSClientServerBookTest e
}
@Test
+ public void testServerWebApplicationExceptionResponse() throws Exception {
+ WebClient wc = WebClient.create("http://localhost:" + PORT +
"/bookstore/webappexception");
+ wc.accept("application/xml");
+ try {
+ Response r = wc.get(Response.class);
+ assertEquals(500, r.getStatus());
+ } catch (ServerWebApplicationException ex) {
+ fail("Unexpected exception");
+ }
+ }
+
+ @Test
public void testServerWebApplicationExceptionXML() throws Exception {
ResponseReader reader = new ResponseReader();
reader.setEntityClass(Book.class);