Question

I am trying to fix an issue with my RestTemplate PUT request. Basically, the server expects data(an object) to be put in "Raw" content-type but as xml stream. I tried many combinations(of converter, content-type etc..) but nothing helps. I either end up in getting exception as " org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type com.test.myObject"

Or:

"The server encountered an error processing the request. 
The exception message is 'Incoming message for operation 'SendRequest' contains
an unrecognized http body format value 'Xml'. The expected body format value is 'Raw'. 
This can be because a WebContentTypeMapper has not been configured on the binding.
".

Any suggestions to fix this will be of great value.

Was it helpful?

Solution

You could provide your own message converter:

Considering that you need to send a custom Content-Type, you will need to create a class that extends AbstractHttpMessageConverter let's say RawHttpMessageConverter. You will need to provide concrete implementations for abstract methods:

  1. supports(...) - feel free to return true
  2. readInternal(Class<? extends T> clazz, HttpInputMessage inputMessage) - here you'll unmarshall your custom object from inputMessage.getBody() InputStream
  3. writeInternal(T t, HttpOutputMessage outputMessage) - here you'll marshall your object T into outputMessage.getBody() OutputStream

Also, very important is to set the list of expected content types: new MediaType("Raw", "8"); and to register into your message converters list.

This is one way of doing it. Another way could be to extend an existing message converter and provide concrete implementations for only what you need. The closest message converter that I can see to your needs (If I understand them correctly) is StringHttpMessageConverter. When providing an implementation you will just create a List of MediaTypes as class variable and add "Raw" type to it - that in constructor. Override getSupportedMediaTypes() and return this list.

When setting up the RestTemplate you will have:

        RestTemplate restTemplate = new RestTemplate();
        List<HttpMessageConverter<AbstractHttpMessageConverter<?>>> converters = new ArrayList<HttpMessageConverter<AbstractHttpMessageConverter<?>>>();
        converters.add(new RawHttpMessageConverter());
        restTemplate.setMessageConverters(messageConverters);

To provide more, below is a custom message converter that I am using for Bitmap download:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
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.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;

import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;


public class BitmapMessageConverter implements HttpMessageConverter<Bitmap> {

    private static final int BUFFER_SIZE = 8 * 1024;
    private List<MediaType> imageMediaTypes;

    public BitmapMessageConverter() {
        imageMediaTypes = new ArrayList<MediaType>();
        imageMediaTypes.add(new MediaType("image", "*"));
        imageMediaTypes.add(new MediaType("image", "png"));
        imageMediaTypes.add(new MediaType("image", "jpeg"));
    }



    private boolean isRegisteredMediaType(MediaType mediaType) {
        return imageMediaTypes.contains(mediaType);
    }

    @Override
    public List<MediaType> getSupportedMediaTypes() {
        return imageMediaTypes;
    }

    @Override
    public Bitmap read(Class<? extends Bitmap> classArg, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        BufferedInputStream bis = new BufferedInputStream(inputMessage.getBody(), BUFFER_SIZE);
        Bitmap result = BitmapFactory.decodeStream(bis);
        return result;
    }

    @Override
    public void write(Bitmap bitmap, MediaType mediaType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        BufferedOutputStream bos = new BufferedOutputStream(outputMessage.getBody(), BUFFER_SIZE);
        bitmap.compress(CompressFormat.JPEG, 100, bos);
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top