Announcement Announcement Module
Collapse
No announcement yet.
inbound-gateway/HttpRequestHandlingMessagingGateway and exceptions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • inbound-gateway/HttpRequestHandlingMessagingGateway and exceptions

    i have a scenario where i am using an si-http:outbound-gateway and si-http:inbound-gateway pair to interact using xml strings for request and response.

    i have a routine to convert an exception into an xml string.

    when an exception is thrown on the inbound side, i would like to convert it to an xml string and return it as the response.

    i set convert-exceptions to true in the inbound-gateway, and i get:

    Code:
    org.springframework.integration.MessagingException: Could not convert reply: no suitable HttpMessageConverter found for type [org.springframework.integration.MessageHandlingException] and accept types [[text/plain, */*]]
    here are some snippets of relevant configuration:

    Code:
      <http:outbound-gateway id="http" request-channel="http.output" url="${url}"
        extract-request-payload="true" charset="UTF-8" request-timeout="1000" expected-response-type="java.lang.String" />
    
      <util:list id="httpConverters">
        <bean class="com.aetna.framework.integration.test.ExceptionHttpMessageConverter" />
      </util:list>
    
      <http:inbound-gateway id="inboundGateway" request-channel="request.input" convert-exceptions="true"
        message-converters="httpConverters" />
    i even tried adding the converter listed below (which i cloned mostly from StringHttpMessageConverter) and i still get "could not convert reply".

    can any one provide some guidance for achieving my desired behavior?

    thanks,
    tony...

    Code:
    package com.aetna.framework.integration.http;
    
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.UnsupportedEncodingException;
    import java.nio.charset.Charset;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.http.HttpInputMessage;
    import org.springframework.http.HttpOutputMessage;
    import org.springframework.http.MediaType;
    import org.springframework.http.converter.AbstractHttpMessageConverter;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.integration.MessageHandlingException;
    import org.springframework.util.FileCopyUtils;
    
    import com.aetna.helper.xml.XmlHelper;
    
    public class ExceptionHttpMessageConverter extends AbstractHttpMessageConverter<MessageHandlingException>
    {
    
      public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");
    
      private final List<Charset> availableCharsets;
    
      private boolean writeAcceptCharset = true;
    
      public ExceptionHttpMessageConverter()
      {
        super(new MediaType("text", "plain", DEFAULT_CHARSET), MediaType.ALL);
        this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values());
      }
    
      public void setWriteAcceptCharset(boolean writeAcceptCharset)
      {
        this.writeAcceptCharset = writeAcceptCharset;
      }
    
      @Override
      public boolean supports(Class<?> clazz)
      {
        return MessageHandlingException.class.equals(clazz);
      }
    
      @SuppressWarnings("unchecked")
      @Override
      protected MessageHandlingException readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException
      {
        //MediaType contentType = inputMessage.getHeaders().getContentType();
        // Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : DEFAULT_CHARSET;
        return new MessageHandlingException(null, "what?");
        // FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));
      }
    
      @Override
      protected Long getContentLength(MessageHandlingException t, MediaType contentType)
      {
        String s = XmlHelper.asXml(t);
        if (contentType != null && contentType.getCharSet() != null)
        {
          Charset charset = contentType.getCharSet();
          try
          {
            return (long) s.getBytes(charset.name()).length;
          }
          catch (UnsupportedEncodingException ex)
          {
            // should not occur
            throw new InternalError(ex.getMessage());
          }
        }
        else
        {
          return null;
        }
      }
    
      @Override
      protected void writeInternal(MessageHandlingException t, HttpOutputMessage outputMessage) throws IOException
      {
        String s = XmlHelper.asXml(t);
        if (writeAcceptCharset)
        {
          outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());
        }
        MediaType contentType = outputMessage.getHeaders().getContentType();
        Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : DEFAULT_CHARSET;
        FileCopyUtils.copy(s, new OutputStreamWriter(outputMessage.getBody(), charset));
      }
    
      protected List<Charset> getAcceptedCharsets()
      {
        return this.availableCharsets;
      }
    
    }

  • #2
    Tony

    There was some last minute change which will definitely satisfy your case.
    So if I understand your use case correctly (i think i do) you have this:

    http:outbound-gateway -> http:inbound-gateway -> some-endpoint

    When something on the side of inbound-gateway results in the exception you want to have a chance to convert it into a regular message.
    So what you need to do is specify 'error-channel' attribute on the outbound-gateway and have a subscriber (e.g. ExceptionHandlingService) listening on that channel converting ErrorMessage to whatever it is you want it to be and sending it to the reply-channel of the outbound-gateway.

    Comment


    • #3
      Actually, the "error-channel" is not an option on the HTTP inbound gateway since that already provides support for HttpMessageConverters that can handle this task. So, the attempt to use the HttpMessageConverter is on the right track. Have you tried this with a debugger to ensure that it's calling into the canWrite() method and returning true there?

      Comment


      • #4
        I was talking about outbound-gateway
        So what you need to do is specify 'error-channel' attribute on the outbound-gateway

        Comment


        • #5
          My bad, error-channel is not an attribute of outbound-gateway either. I thought it was with the recent change to the gateways

          Comment


          • #6
            Override default constructor.

            Try overridding org.springframework.http.converter.AbstractHttpMes sageConverter default constructor and specify MediaType.

            Code:
                    public ExceptionHttpMessageConverter() {
            		super(MediaType.ALL);
            	}
            That worked for me.

            Comment

            Working...
            X