ジョシュ・M.:
私は、オブジェクト(例えばません投稿する必要があるMultiValueMap
経由)RestTemplate
コンテンツタイプにapplication/x-www-form-urlencoded
。私はそうしようとすると...
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)
...私は次のエラーを取得します:
org.springframework.web.client.RestClientException:書き込み要求できませんでした:なし適当HttpMessageConverter要求タイプ[com.whatever.MyRequestPayload]及びコンテンツタイプ[アプリケーション/ x-www-form-urlencodedで]見つかり
ここで私は内見たものですrestTemplate.getMessageConverters()
。
なぜ私が提供したくありませんかMultiValueMap
?二つの理由:
- これはこれのために特別に過負荷を追加して、複数のエンドポイントに要求を送信するために使用される汎用コードで
x-www-form-urlencoded
意志だけ複雑なものを - 私が持っている必要がありますようにそれはいないようだ-私はちょうどHttpMessageConverterはにオブジェクトを変換するサポートするために使用する必要があるか分からない
x-www-form-urlencoded
文字列
ジョシュ・M.:
私は、任意のオブジェクトを受け取り、リクエストボディにwww-form-urlencodedで返しますコンテンツとして、それを書き出しカスタムHTTPメッセージコンバータを書くためになってしまいました。
使用法
RestTemplate template = new RestTemplate(...);
template.getMessageConverters().add(new ObjectToUrlEncodedConverter(mapper));
ObjectToUrlEncodedConverter
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();
}
}
}