Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6C5714905 for ; Tue, 21 Jun 2011 22:24:56 +0000 (UTC) Received: (qmail 9734 invoked by uid 500); 21 Jun 2011 22:24:56 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 9685 invoked by uid 500); 21 Jun 2011 22:24:56 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 9678 invoked by uid 99); 21 Jun 2011 22:24:56 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Jun 2011 22:24:56 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Jun 2011 22:24:54 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 8DD3F2388A29; Tue, 21 Jun 2011 22:24:33 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1138220 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/ Date: Tue, 21 Jun 2011 22:24:33 -0000 To: commits@cxf.apache.org From: sergeyb@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110621222433.8DD3F2388A29@eris.apache.org> Author: sergeyb Date: Tue Jun 21 22:24:33 2011 New Revision: 1138220 URL: http://svn.apache.org/viewvc?rev=1138220&view=rev Log: [CXF-3610] Enhancing WebClient to support posting explicit collections Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java 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=1138220&r1=1138219&r2=1138220&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 Jun 21 22:24:33 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> 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 invoke(String httpMethod, Object body, Class 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 post(Object body, Class responseClass) { + return invoke("POST", body, responseClass); } /** @@ -340,29 +345,53 @@ public class WebClient extends AbstractC */ public Collection invokeAndGetCollection(String httpMethod, Object body, Class memberClass) { - Response r = doInvoke(httpMethod, body, Collection.class, - new ParameterizedCollectionType(memberClass)); - - if (r.getStatus() >= 400) { - throw new ServerWebApplicationException(r); - } - + Response r = doInvoke(httpMethod, body, null, + Collection.class, new ParameterizedCollectionType(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 Response postCollection(Object collection, Class memberClass) { + return doInvoke("POST", collection, new ParameterizedCollectionType(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 post(Object body, Class responseClass) { - return invoke("POST", body, responseClass); + public T2 postCollection(Object collection, Class memberClass, + Class responseClass) { + Response r = doInvoke("POST", collection, new ParameterizedCollectionType(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 Collection postAndGetCollection(Object collection, + Class memberClass, + Class responseClass) { + Response r = doInvoke("POST", collection, new ParameterizedCollectionType(memberClass), + Collection.class, new ParameterizedCollectionType(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 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 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 headers, Object body, + Type inGenericType, Class responseClass, - Type genericType, + Type outGenericType, Exchange exchange, Map invContext) { - + //CHECKSTYLE:ON URI uri = getCurrentURI(); Message m = createMessage(body, httpMethod, headers, uri, exchange, invContext); Map 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 headers = (MultivaluedMap)outMessage.get(Message.PROTOCOL_HEADERS); Object body = objs.get(0); + + Map 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/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java?rev=1138220&r1=1138219&r2=1138220&view=diff ============================================================================== --- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java (original) +++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStore.java Tue Jun 21 22:24:33 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 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/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java?rev=1138220&r1=1138219&r2=1138220&view=diff ============================================================================== --- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java (original) +++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java Tue Jun 21 22:24:33 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 books = new ArrayList(); + 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 books = new ArrayList(); + books.add(b1); + books.add(b2); + List books2 = new ArrayList(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);