gnodet-bot commented on code in PR #28923:
URL: https://github.com/apache/camel/pull/28923#discussion_r4445549311
##########
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:
đĄ **Documentation gap â multi-parameter MCL still fails.** The condition in
`populateCxfRsResponseFromExchange` is `mcl.size() <= 1`: a
`MessageContentsList` of two or more parameters (i.e. a resource method with
multiple parameters where the route doesn't set a reply) still returns the raw
MCL, which fails with "No message body writer". This remaining failure case is
not documented here.
Suggested addition after the second sentence:
```suggestion
When the resource method returns a collection, the `MessageContentsList` is
still written as that collection.
A `MessageContentsList` of several parameters (a resource method with more
than one parameter) still causes an HTTP 500 error when the route does not set
a reply body; in that case, set the body explicitly.
```
##########
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:
âšī¸ `doPopulateCxfRsResponseFromExchange` is `protected`, which intentionally
exposes it as an extension point for `SimpleCxfRsBinding` (and any other custom
binding that needs to bypass the new MCL unwrapping). The Javadoc accurately
describes the contract. Just confirming this visibility is deliberate â it is
an API surface expansion compared to the private/package-private alternative.
--
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]