private void marshal()

in core/camel-support/src/main/java/org/apache/camel/support/processor/RestBindingAdvice.java [333:467]


    private void marshal(Exchange exchange, Map<String, Object> state) {
        // only marshal if there was no exception
        if (exchange.getException() != null) {
            return;
        }

        if (skipBindingOnErrorCode) {
            Integer code = exchange.getMessage().getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class);
            // if there is a custom http error code then skip binding
            if (code != null && code >= 300) {
                return;
            }
        }

        boolean isXml = false;
        boolean isJson = false;

        // accept takes precedence
        String accept = (String) state.get(STATE_KEY_ACCEPT);
        if (accept != null) {
            isXml = accept.toLowerCase(Locale.ENGLISH).contains("xml");
            isJson = accept.toLowerCase(Locale.ENGLISH).contains("json");
        }
        // fallback to content type if still undecided
        if (!isXml && !isJson) {
            String contentType = ExchangeHelper.getContentType(exchange);
            if (contentType != null) {
                isXml = contentType.toLowerCase(Locale.ENGLISH).contains("xml");
                isJson = contentType.toLowerCase(Locale.ENGLISH).contains("json");
            }
        }
        // if content type could not tell us if it was json or xml, then fallback to if the binding was configured with
        // that information in the consumes
        if (!isXml && !isJson) {
            isXml = produces != null && produces.toLowerCase(Locale.ENGLISH).contains("xml");
            isJson = produces != null && produces.toLowerCase(Locale.ENGLISH).contains("json");
        }

        // only allow xml/json if the binding mode allows that (when off we still want to know if its xml or json)
        if (bindingMode != null) {
            isXml &= bindingMode.equals("off") || bindingMode.equals("auto") || bindingMode.contains("xml");
            isJson &= bindingMode.equals("off") || bindingMode.equals("auto") || bindingMode.contains("json");

            // if we do not yet know if its xml or json, then use the binding mode to know the mode
            if (!isJson && !isXml) {
                isXml = bindingMode.equals("auto") || bindingMode.contains("xml");
                isJson = bindingMode.equals("auto") || bindingMode.contains("json");
            }
        }

        // in case we have not yet been able to determine if xml or json, then use the same as in the unmarshaller
        if (isXml && isJson) {
            isXml = state.get(STATE_KEY_DO_MARSHAL).equals(STATE_XML);
            isJson = !isXml;
        }

        // need to prepare exchange first
        ExchangeHelper.prepareOutToIn(exchange);

        // ensure there is a content type header (even if binding is off)
        ensureHeaderContentType(produces, isXml, isJson, exchange);

        if (bindingMode == null || "off".equals(bindingMode)) {
            // binding is off, so no message body binding
            return;
        }

        // is there any marshaller at all
        if (jsonMarshal == null && xmlMarshal == null) {
            return;
        }

        // is the body empty
        if (exchange.getMessage().getBody() == null) {
            return;
        }

        String contentType = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class);
        // need to lower-case so the contains check below can match if using upper case
        contentType = contentType.toLowerCase(Locale.US);
        try {
            // favor json over xml
            if (isJson && jsonMarshal != null) {
                // only marshal if its json content type
                if (contentType.contains("json")) {
                    jsonMarshal.process(exchange);
                    setOutputDataType(exchange, new DataType("json"));

                    if (enableNoContentResponse) {
                        String body = MessageHelper.extractBodyAsString(exchange.getMessage());
                        if (ObjectHelper.isNotEmpty(body) && (body.equals("[]") || body.equals("{}"))) {
                            exchange.getMessage().setHeader(Exchange.HTTP_RESPONSE_CODE, 204);
                            exchange.getMessage().setBody("");
                        }
                    }
                }
            } else if (isXml && xmlMarshal != null) {
                // only marshal if its xml content type
                if (contentType.contains("xml")) {
                    xmlMarshal.process(exchange);
                    setOutputDataType(exchange, new DataType("xml"));

                    if (enableNoContentResponse) {
                        String body = MessageHelper.extractBodyAsString(exchange.getMessage()).replace("\n", "");
                        if (ObjectHelper.isNotEmpty(body)) {
                            int open = 0;
                            int close = body.indexOf('>');
                            // xml declaration
                            if (body.startsWith("<?xml")) {
                                open = close;
                                close = body.indexOf('>', close + 1);
                            }
                            // empty root element <el/> or <el></el>
                            if (body.length() == close + 1 || body.length() == (open + 1 + 2 * (close - open) + 1)) {
                                exchange.getMessage().setHeader(Exchange.HTTP_RESPONSE_CODE, 204);
                                exchange.getMessage().setBody("");
                            }
                        }
                    }
                }
            } else {
                // we could not bind
                if (bindingMode.contains("xml")) {
                    exchange.setException(new CamelExchangeException(
                            "Cannot bind to xml as message body is not xml compatible", exchange));
                } else if (!bindingMode.equals("auto")) {
                    // okay for auto we do not mind if we could not bind
                    exchange.setException(new CamelExchangeException(
                            "Cannot bind to json as message body is not json compatible", exchange));
                }
            }
        } catch (Exception e) {
            exchange.setException(e);
        }
    }