davsclaus commented on code in PR #28923:
URL: https://github.com/apache/camel/pull/28923#discussion_r4445660949


##########
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc:
##########
@@ -1797,6 +1797,19 @@ It is now written with all its decimals, so a record 
that is unmarshalled and ma
 `Double` that is the result of a calculation is written with all its digits 
too (`0.1 + 0.2` as `0.30000000000000004`,
 before `0.3`). Set `precision` to get a fixed number of decimals, as before.
 
+=== camel-cxfrs - an unchanged request body as reply, and a List body of the 
HTTP API producer
+
+With the `Default` binding style, a route that does not set a reply body 
replied with the request
+`MessageContentsList`, which failed with HTTP 500 "No message body writer has 
been found for class
+MessageContentsList" (or was written as a one element array by a JSON provider 
that writes any object). Now a
+`MessageContentsList` reply of one element is the response entity, and an 
empty one replies with no content (204).
+When the resource method returns a collection, the `MessageContentsList` is 
still written as that collection.

Review Comment:
   Thanks. Added in 8bd1c40d02e7: the upgrade guide and the component page now 
say that a `MessageContentsList` of several parameters still fails with HTTP 
500 and the route must set the reply body. The `@BodyTypes` description already 
said so.
   
   _Claude Code on behalf of Claus Ibsen (davsclaus)_



##########
components/camel-cxf/camel-cxf-rest/src/main/java/org/apache/camel/component/cxf/jaxrs/DefaultCxfRsBinding.java:
##########
@@ -70,6 +72,28 @@ public Object populateCxfRsResponseFromExchange(
             Exchange camelExchange,
             org.apache.cxf.message.Exchange cxfExchange)
             throws Exception {
+        Object o = doPopulateCxfRsResponseFromExchange(camelExchange, 
cxfExchange);
+        if (o instanceof MessageContentsList mcl && mcl.size() <= 1 && 
!isCollectionReturnType(cxfExchange)) {
+            // the request parameters are still the body (the route did not 
set a reply), and CXF has no
+            // message body writer for a MessageContentsList: reply with its 
single element, or no content
+            return mcl.isEmpty() ? null : mcl.get(0);
+        }
+        return o;
+    }
+
+    private static boolean 
isCollectionReturnType(org.apache.cxf.message.Exchange cxfExchange) {
+        // a resource method that returns a collection writes the 
MessageContentsList as that collection
+        OperationResourceInfo ori = cxfExchange != null ? 
cxfExchange.get(OperationResourceInfo.class) : null;
+        return ori != null && 
Collection.class.isAssignableFrom(ori.getMethodToInvoke().getReturnType());
+    }
+
+    /**
+     * Populates the CXF exchange from the Camel response message and returns 
its body as is.
+     */
+    protected Object doPopulateCxfRsResponseFromExchange(
+            Exchange camelExchange,
+            org.apache.cxf.message.Exchange cxfExchange)

Review Comment:
   Yes, it is deliberate. `SimpleCxfRsBinding` calls 
`doPopulateCxfRsResponseFromExchange` to skip the unwrapping, because its 
`buildResponse` replies without an entity for the request 
`MessageContentsList`. A custom binding can do the same.
   
   _Claude Code on behalf of Claus Ibsen (davsclaus)_



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to