我需要通过内容类型为MultiValueMap
的{{1}}发布对象(例如,不是RestTemplate
)。当我尝试这样做时...
application/x-www-form-urlencoded
...我收到以下错误:
org.springframework.web.client.RestClientException:无法写入请求:未为请求类型[com.whatever.MyRequestPayload]和内容类型[application / x-www-form-urlencoded]找到合适的HttpMessageConverter
这是我在HttpHeaders headers = new HttpHeaders();
HttpEntity request;
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED)
// data is some generic type
request = new HttpEntity<>(data, headers);
// clazz is the Class<T> being returned
restTemplate.exchange(url, method, request, clazz)
中看到的内容:
我为什么不想提供restTemplate.getMessageConverters()
?两个原因:
MultiValueMap
的重载只会使事情复杂化x-www-form-urlencoded
字符串答案 0 :(得分:0)
您是否尝试过将MappingJackson2HttpMessageConverter
添加到RestTemplate
restTemplate.getMessageConverters().add(getMappingJackson2HttpMessageConverter());
public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_FORM_URLENCODED));
return mappingJackson2HttpMessageConverter;
}
答案 1 :(得分:0)
我最终不得不编写一个自定义HTTP消息转换器,该转换器接收任何对象并将其作为www-form-urlencoded内容写到请求主体中:
RestTemplate template = new RestTemplate(...);
template.getMessageConverters().add(new ObjectToUrlEncodedConverter(mapper));
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.databind.ObjectMapper;
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 sun.reflect.generics.reflectiveObjects.NotImplementedException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.List;
public class ObjectToUrlEncodedConverter implements HttpMessageConverter
{
private static final String Encoding = "UTF-8";
private final ObjectMapper mapper;
public ObjectToUrlEncodedConverter(ObjectMapper mapper)
{
this.mapper = mapper;
}
@Override
public boolean canRead(Class clazz, MediaType mediaType)
{
return false;
}
@Override
public boolean canWrite(Class clazz, MediaType mediaType)
{
return getSupportedMediaTypes().contains(mediaType);
}
@Override
public List<MediaType> getSupportedMediaTypes()
{
return Collections.singletonList(MediaType.APPLICATION_FORM_URLENCODED);
}
@Override
public Object read(Class clazz, HttpInputMessage inputMessage) throws HttpMessageNotReadableException
{
throw new NotImplementedException();
}
@Override
public void write(Object o, MediaType contentType, HttpOutputMessage outputMessage) throws HttpMessageNotWritableException
{
if (o != null)
{
String body = mapper
.convertValue(o, UrlEncodedWriter.class)
.toString();
try
{
outputMessage.getBody().write(body.getBytes(Encoding));
}
catch (IOException e)
{
// if UTF-8 is not supporter then I give up
}
}
}
private static class UrlEncodedWriter
{
private final StringBuilder out = new StringBuilder();
@JsonAnySetter
public void write(String name, Object property) throws UnsupportedEncodingException
{
if (out.length() > 0)
{
out.append("&");
}
out
.append(URLEncoder.encode(name, Encoding))
.append("=");
if (property != null)
{
out.append(URLEncoder.encode(property.toString(), Encoding));
}
}
@Override
public String toString()
{
return out.toString();
}
}
}
答案 2 :(得分:0)
如果您使用WebMvcConfigurerAdapter
,则可能会遇到此类错误。从Spring 5.x.x开始不推荐使用WebMvcConfigurerAdapter。尝试使用WebMvcConfigurer
。完成后,您将必须覆盖:
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}
答案 3 :(得分:0)
RestTemplate template = new RestTemplate(...);
template.getMessageConverters().add(new org.springframework.http.converter.FormHttpMessageConverter.FormHttpMessageConverter());
答案 4 :(得分:-1)
您可以如下所示将FormHttpMessageConverter用于内容类型“ application / x-www-form-urlencoded”,并在主体的RestTemplate post方法中以MultiValueMap
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate" lazy-init="true">
<constructor-arg name="requestFactory" ref="bufferingClientHttpRequestFactory" />
<property name="errorHandler" ref="responeErrorHandler" />
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.FormHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</list>
</property>
</bean>
Java Config版本
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new FormHttpMessageConverter());
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
return restTemplate
}