Rest模板Spring Android PUT与原始内容类型

时间:2013-07-17 08:55:22

标签: android spring resttemplate

我正在尝试修复我的RestTemplate PUT请求的问题。基本上,服务器期望将数据(对象)放在“Raw”内容类型中,但作为xml流。 我尝试了很多组合(转换器,内容类型等)但没有任何帮助。我最终得到的异常是" org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type com.test.myObject"

或者:

"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.
".

任何解决此问题的建议都具有重要价值。

1 个答案:

答案 0 :(得分:3)

您可以提供自己的消息转换器:

考虑到您需要发送自定义内容类型,您需要创建一个扩展AbstractHttpMessageConverter的类,让我们说RawHttpMessageConverter。您需要为抽象方法提供具体实现:

  1. supports(...) - 随时返回true
  2. readInternal(Class<? extends T> clazz, HttpInputMessage inputMessage) - 在这里,您将从inputMessage.getBody() InputStream
  3. 解组您的自定义对象
  4. writeInternal(T t, HttpOutputMessage outputMessage) - 在这里,您可以将对象T编组为outputMessage.getBody() OutputStream
  5. 另外,非常重要的是设置预期内容类型列表:new MediaType("Raw", "8");并注册到您的消息转换器列表中。

    这是一种做法。另一种方法是扩展现有的消息转换器,并仅为您需要的内容提供具体的实现。我能看到的最接近的消息转换器(如果我理解正确的话)是StringHttpMessageConverter。在提供实现时,您只需创建一个MediaTypes List作为类变量,并在其中添加“Raw”类型 - 在构造函数中。覆盖getSupportedMediaTypes()并返回此列表。

    设置RestTemplate时,您将拥有:

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

    为了提供更多信息,以下是我用于Bitmap下载的自定义消息转换器:

    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);
        }