Claus Ibsen created CAMEL-25769:
-----------------------------------

             Summary: camel-core - REST binding: a GET with Content-Type 
text/plain is answered 500 when bindingMode is json
                 Key: CAMEL-25769
                 URL: https://issues.apache.org/jira/browse/CAMEL-25769
             Project: Camel
          Issue Type: Bug
          Components: camel-core
            Reporter: Claus Ibsen
             Fix For: 4.24.0


With bindingMode json, a request whose Content-Type is not JSON gets no JSON 
answer. A GET of a REST DSL operation that answers a Map, sent with 
Content-Type text/plain:

{noformat}
curl -H 'Content-Type: text/plain;charset=UTF-8' 
http://localhost:8080/orders/ORD-1002
500 Internal Server Error

WARN  VertxPlatformHttpConsumer : Failed handling platform-http endpoint 
/orders/{id}. Caused by: [org.apache.camel.NoTypeConversionAvailableException - 
No type converter available to convert from type: java.util.LinkedHashMap to 
the required type: java.io.InputStream]
{noformat}

The same GET without a Content-Type, or with application/json, gets the order 
as JSON.

Cause, in RestBindingAdvice.doMarshal: the request's Content-Type header is 
still on the message when the answer is made. ensureHeaderContentType keeps an 
existing Content-Type, so application/json is not set, and the answer is 
marshalled only when its Content-Type contains json. The Map is left as it is, 
and the HTTP consumer cannot write it. Vert.x only reports the failure; the 
decision is in the binding.

The Content-Type of a request describes its body, and a GET has none. The 
format of the answer comes from the Accept header and what the operation 
produces: Spring MVC and JAX-RS answer JSON for such a GET whatever its 
Content-Type, when the operation declares no consumes. Most clients send no 
Content-Type on a GET (browsers, curl, the Java HttpClient), but some do: the 
Citrus HTTP client sends text/plain by default, which is how this was found, in 
the contracts/rest-code-first example (apache/camel-jbang-examples#118). Camel 
answers with a server error for a header that does not concern the answer.

Proposal:
* The request's Content-Type does not decide the answer. The binding remembers 
it when the request comes in; when the message still has that value at the end, 
the route did not choose a type, so the binding sets the Content-Type of its 
mode (application/json) and marshals.
* A Content-Type that the route sets itself still wins, so a route can answer 
text/csv and skip the binding, as today.
* A body that is already text stays as it is, so a route that answers a String 
to a text/plain request gets the same answer as today. Only the case that fails 
today changes: an object body (Map, List, POJO).
* Tests for each of the three cases.

_Claude Code on behalf of davsclaus_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to