2017-02-20 13 views
2

私はSpring Cloudなどで少し混乱させるためにクラウドアプリケーションを開発してきました。今私は、RestTemplate APIを使用して、SpringのデータレストバックエンドにPOSTまたはPUTリクエストを送信しようとしているが、エラーで終了する:HttpMessageNotReadableException:START_OBJECTトークン、HttpMessageNotReadableExceptionのjava.lang.Stringのインスタンスを逆シリアル化できない:ドキュメントを読むことができませんでした:application/xml; contentsetのコンテンツタイプがrequestからのSTART_ARRAYトークンからjava.lang.Stringのインスタンスを逆シリアル化できません; charset = UTF-8!、エラー400 null ...あなたの名前。リサーチした後、私はHAL JSONをRestTemplate(レベル3のJSONハイパーメディア、正しくリコールすれば)で消費するのはかなり難しいことを発見しましたが、それが可能かどうかを知りたいのです。POSTとRestTemplateを介してPUTをSpringデータRestに送信Api

SpringデータレストバックエンドにPOSTとPUTを送信するRestTemplateの動作可能な(可能であれば詳細な)例をお見せしたいと思います。

編集:私はpostForEntity、postForLocation、交換を試してみましたが、それはちょうど異なる種類のエラーで終了しました。それらは私が試したいくつかの抜粋です(それ以上はありますが、私はそれらを処分するだけです)。

マイエンティティ:

@Entity 
public class Account implements Serializable { 

private static final long serialVersionUID = 1L; 

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private Long id; 

private String name; 

@NotNull 
@NotEmpty 
private String username; 

@NotNull 
@NotEmpty 
private String authorities; 

@NotNull 
@NotEmpty 
private String password; 

//Constructor, getter and setter 

一部restTemplateがattemps:

public Account create(Account account) { 
    //Doesnt work :S 
    MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>(); 
    map.add("name", account.getName()); 
    map.add("username", account.getUsername()); 
    map.add("password", account.getPassword()); 
    map.add("authorities", account.getAuthorities()); 

    HttpHeaders headers = new HttpHeaders(); 
    headers.setContentType(MediaType.APPLICATION_JSON); 
    final HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<MultiValueMap<String, String>>(map, 
      headers); 

    return restTemplate.exchange(serviceUrl + "/accounts", HttpMethod.POST, entity, Account.class).getBody(); 
} 

//Also tried with a AccountResource which extends from ResourceSupport and doesn't work either. This one gives me a error saying it cannot deserialize Account["name"]. 

はまた、このようにしようとしたヘッダは、アプリケーション/ xmlのことについてエラーを得た:RestTemplate POSTing entity with associations to Spring Data REST server

他のものはただ繰り返しそれらのエラーの1つ。

+0

あなたのコードを共有してください。私たちは間違いなく助けてくれるでしょう – Coder

+0

投稿すると、サーバーはボディを返すのですか? – zeroflagL

+0

RestTemplateが壊れているため、サーバーは何も返しません。それは、コントローラ上での不正なリクエストエラーと、Spring Data Restバックエンドで答えたコメントに誤りがあります。 –

答えて

3

application/hal + jsonコンテンツタイプを使用できるようにRestTemplateを設定する必要があります。

this oneまたはthat oneなどの他の投稿や、hereなどのブログ記事の投稿には既に対応しています。 次のソリューションは、春のブートプロジェクトのために動作します:

まず、豆を使用してRestTemplateを設定:

// other import directives omitted for the sake of brevity 
import static org.springframework.hateoas.MediaTypes.HAL_JSON; 

@Configuration 
public class RestTemplateConfiguration { 

    @Autowired 
    private ObjectMapper objectMapper; 

    /** 
    * 
    * @return a {@link RestTemplate} with a HAL converter 
    */ 
    @Bean 
    public RestTemplate restTemplate() { 

     // converter 
     MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); 
     converter.setSupportedMediaTypes(Arrays.asList(HAL_JSON)); 
     converter.setObjectMapper(objectMapper); 

     RestTemplate restTemplate = new RestTemplate(Collections.singletonList(converter)); 

     return restTemplate; 
    } 

}

その後、春にはあなたがRESTを消費する必要がRestTemplateを注入してみましょうバックエンドを使用して、RestTemplate#exchangeの多くのバリアントの1つを使用します。

@Autowired 
public RestTemplate restTemplate; 

... 
// for a single ressource 

// GET 
Account newAccount = restTemplate.getForObject(url, Account.class); 

// POST 
Account newAccount = restTemplate.exchange(serviceUrl + "/accounts", HttpMethod.POST, entity, Account.class).getBody(); 
// or any of the specialized POST methods... 
Account newAccount = restTemplate.postForObject(serviceUrl + "/accounts", entity, Account.class); 

コレクションの場合は、PagedResources

// for a collection 
ParameterizedTypeReference<PagedResources<Account>> responseType = 
     new ParameterizedTypeReference<PagedResources<Account>>() {}; 

// GET 
PagedResources<Account> accounts = 
     restTemplate.exchange(url, HttpMethod.GET, null, responseType).getBody(); 

// 
+0

私はブログを思い出しましたが、 "HAL_JSON"がどこから来たのかわからないのでコードを実装しませんでした。 MediaType.parseMediaType( "application/hal + json")をHAL_JSONの代わりに使ってみましたが、うまくいきません。エラーは同じです:START_ARRAYトークンからjava.lang.Stringのインスタンスを逆シリアル化できません –

+0

これは正確なトラックです:ドキュメントを読み込めませんでした:java.langのインスタンスを逆シリアル化できません。START_ARRAYトークンからの文字列 [ソース:[email protected];行:1、列:9](参照チェーン:com.example.core.webservicesrepositories.accounts.entities.Account ["name"]);ネストされた例外はcom.fasterxml.jackson.databind.JsonMappingExceptionです:START_ARRAYトークンからjava.lang.Stringのインスタンスを逆シリアル化できません –

+0

postForEntityとの交換を使用してそのPOSTを置き換えることによって解決できました。私は、あなたが私にこの問題を解決するにはあまりにも多くの方法を導いて以来、答えをあなたのものとしてチェックします。どうもありがとうございました! 私はこの質問をする前にあなたが提案したGETを持っていましたが、RestTemplateにその調整をしなくてもうまくいきました。どうしていいのですか? –

関連する問題