You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2021/05/01 20:38:38 UTC

[cxf] branch master updated: CXF-8518: Fixing jaxrs.spec.provider.standardnotnull clientJaxbProviderTest (#782)

This is an automated email from the ASF dual-hosted git repository.

reta pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/master by this push:
     new 4852a50  CXF-8518: Fixing jaxrs.spec.provider.standardnotnull clientJaxbProviderTest (#782)
4852a50 is described below

commit 4852a50d335817c50882f641197fd189207571eb
Author: Andriy Redko <dr...@gmail.com>
AuthorDate: Sat May 1 16:38:29 2021 -0400

    CXF-8518: Fixing jaxrs.spec.provider.standardnotnull clientJaxbProviderTest (#782)
---
 .../main/java/org/apache/cxf/helpers/IOUtils.java  | 40 +++++++++++++++++++---
 .../cxf/jaxrs/provider/JAXBElementProvider.java    | 24 +++++++++----
 .../cxf/systest/jaxrs/provider/CXFResource.java    |  6 ++++
 .../systest/jaxrs/provider/JAXBProviderTest.java   | 20 +++++++++++
 4 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/core/src/main/java/org/apache/cxf/helpers/IOUtils.java b/core/src/main/java/org/apache/cxf/helpers/IOUtils.java
index efa8ded..74af28d 100644
--- a/core/src/main/java/org/apache/cxf/helpers/IOUtils.java
+++ b/core/src/main/java/org/apache/cxf/helpers/IOUtils.java
@@ -43,16 +43,48 @@ public final class IOUtils {
     private IOUtils() {
 
     }
+    
+    /**
+     * Checks if input stream is empty. If the standard InputStream means do not provide
+     * such details, the stream might be wrapped into PushbackInputStream and is going
+     * to be returned instead of original one.
+     * @param is input stream to check
+     * @return "null" if original input stream is empty, otherwise original stream or 
+     * original stream wrapped into PushbackInputStream.
+     * @throws IOException
+     */
+    public static InputStream nullOrNotEmptyStream(InputStream is) throws IOException {
+        if (isEmpty(is)) {
+            return null;
+        } else if (!(is instanceof PushbackInputStream)) {
+            final byte[] bytes = new byte[1];
+            
+            final PushbackInputStream pbStream = new PushbackInputStream(is);
+            boolean isEmpty = isEof(pbStream.read(bytes));
+            
+            if (!isEmpty) {
+                pbStream.unread(bytes);
+                return pbStream;
+            }
+            
+            return null;
+        }
+        
+        return is;
+    }
 
     public static boolean isEmpty(InputStream is) throws IOException {
         if (is == null) {
             return true;
         }
-        // if available is 0 it does not mean it is empty
-        if (is.available() > 0) {
-            return false;
+        try {
+            // if available is 0 it does not mean it is empty
+            if (is.available() > 0) {
+                return false;
+            }
+        } catch (IOException ioe) {
+            //Do nothing
         }
-        
         final byte[] bytes = new byte[1];
         if (is.markSupported()) {
             is.mark(1);
diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
index 6ca7e2b..ab27e02 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java
@@ -59,6 +59,7 @@ import javax.xml.transform.Source;
 import org.w3c.dom.Document;
 
 import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.jaxrs.ext.MessageContext;
 import org.apache.cxf.jaxrs.ext.Nullable;
 import org.apache.cxf.jaxrs.ext.xml.XMLInstruction;
@@ -165,20 +166,29 @@ public class JAXBElementProvider<T> extends AbstractJAXBProvider<T>  {
 
             unmarshaller = createUnmarshaller(theType, genericType, isCollection);
             addAttachmentUnmarshaller(unmarshaller);
-            Object response;
+            Object response = null;
             if (JAXBElement.class.isAssignableFrom(type)
                 || !isCollection && (unmarshalAsJaxbElement
                 || jaxbElementClassMap != null && jaxbElementClassMap.containsKey(theType.getName()))) {
-                reader = getStreamReader(is, type, mt);
-                reader = TransformUtils.createNewReaderIfNeeded(reader, is);
-                if (JAXBElement.class.isAssignableFrom(type) && type == theType) {
-                    response = unmarshaller.unmarshal(reader);
-                } else {
-                    response = unmarshaller.unmarshal(reader, theType);
+                try (InputStream in = IOUtils.nullOrNotEmptyStream(is)) {
+                    // The return value might be "null" in case of empty stream, in this
+                    // case the unmarshaller fails with javax.xml.bind.UnmarshalException instead
+                    // of returning empty response.
+                    if (in != null) {
+                        reader = getStreamReader(in, type, mt);
+                        reader = TransformUtils.createNewReaderIfNeeded(reader, in);
+                        
+                        if (JAXBElement.class.isAssignableFrom(type) && type == theType) {
+                            response = unmarshaller.unmarshal(reader);
+                        } else {
+                            response = unmarshaller.unmarshal(reader, theType);
+                        }
+                    }
                 }
             } else {
                 response = doUnmarshal(unmarshaller, type, is, anns, mt);
             }
+            
             if (response instanceof JAXBElement && !JAXBElement.class.isAssignableFrom(type)) {
                 response = ((JAXBElement<?>)response).getValue();
             }
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/CXFResource.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/CXFResource.java
index 5f3a7d0..724d8d7 100644
--- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/CXFResource.java
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/CXFResource.java
@@ -30,4 +30,10 @@ public class CXFResource {
     public JAXBElement<String> jaxb(JAXBElement<String> jaxb) {
         return jaxb;
     }
+    
+    @Path("null")
+    @POST
+    public JAXBElement<String> jaxbnull(JAXBElement<String> jaxb) {
+        return null;
+    }
 }
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/JAXBProviderTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/JAXBProviderTest.java
index bd4b9f8..d0d568f 100644
--- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/JAXBProviderTest.java
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/provider/JAXBProviderTest.java
@@ -21,6 +21,7 @@ package org.apache.cxf.systest.jaxrs.provider;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.ws.rs.core.GenericType;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.xml.bind.JAXBElement;
@@ -37,6 +38,8 @@ import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
 public class JAXBProviderTest extends AbstractClientServerTestBase {
@@ -79,4 +82,21 @@ public class JAXBProviderTest extends AbstractClientServerTestBase {
         assertTrue(result.contains("<jaxbelement xmlns=\"org.apache.cxf\">test</jaxbelement>"));
         Assert.assertFalse(result.contains("WriteInCXFJaxbProvider"));
     }
+    
+    @Test
+    public void testNoContentIsReturned() throws Exception {
+        WebClient client = WebClient.create("http://localhost:" + PORT + "/resource/null");
+        WebClient.getConfig(client).getHttpConduit().getClient().setReceiveTimeout(3000000);
+
+        List<String> values = new ArrayList<>();
+        values.add(MediaType.APPLICATION_XML);
+        client.getHeaders().put("content-type", values);
+        JAXBElement<String> test = new JAXBElement<>(new QName("org.apache.cxf", "jaxbelement"),
+                                                           String.class, "test");
+        Response response = client.post(test);
+        GenericType<JAXBElement<String>> type = new GenericType<JAXBElement<String>>() {
+        };
+        JAXBElement<String> result = response.readEntity(type);
+        assertThat(result, nullValue());
+    }
 }