2017-02-20 6 views
2

저는 Spring Cloud 등을 조금이라도 혼란에 빠뜨릴 수있는 클라우드 앱을 개발해 왔습니다. 이제 RestTemplate API를 사용하여 Spring 데이터 나머지 백엔드에 POST 또는 PUT 요청을 보내려고했지만 모든 시도가 오류로 끝납니다. HttpMessageNotReadableException : START_OBJECT 토큰, HttpMessageNotReadableException의 java.lang.String 인스턴스를 비 직렬화 할 수 없습니다. : 문서를 읽을 수 없습니다 : application/xml; charset = UTF-8의 콘텐츠 유형을 사용하는 요청에서 START_ARRAY 토큰 중 java.lang.String 인스턴스를 deserialize 할 수 없습니다. 오류 400 null ... 이름을 지정합니다. . 조사한 결과 RestTemplate (레벨 3 JSON 하이퍼 미디어가 올바르게 호출 된 경우)로 HAL JSON을 사용하는 것이 실제로 어렵다는 것을 발견했지만 가능한지 알고 싶습니다.RestTemplate을 통해 POST 및 PUT을 Spring 데이터 나머지로 보냅니다. Api

Spring 데이터 나머지 백엔드로 POST 및 PUT을 보내는 RestTemplate의 작동 가능한 (가능한 경우 자세한) 예제를보고 싶습니다.

편집 : postForEntity, postForLocation, exchange를 시도해 보았습니다. 다른 종류의 오류가 발생했습니다. 그것들은 제가 시도한 일부 발췌 문장입니다 (더 많이, 그것들을 처리하는 것입니다).

내 엔티티 :

@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는 시도한다 :

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

다른 사람은 단지 반복을 그 중 하나는 오류입니다.

+0

코드를 공유해도 좋습니까? 우리는 분명히 도와주고 싶습니다 – Coder

+0

게시 할 때 서버가 몸체를 반환합니까? – zeroflagL

+0

RestTemplate이 중단되어 서버가 아무 것도 반환하지 않습니다. 그것은 컨트롤러 및 스프링 데이터 나머지 백엔드에서 답변에 주석 오류에 나쁜 요청 오류를 제공합니다. –

답변

3

application/hal + json 콘텐트 유형을 사용할 수 있도록 RestTemplate을 구성해야합니다.

는 그것은 이미 here로, 다른 게시물에 같은 this one 또는 that one 및 블로그 게시물의 무리에가 해결되었습니다. 다음 솔루션은 봄 부팅 프로젝트에 작동합니다

첫째, 콩 사용하여 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을 주입하자 당신이 012을 조작하는 것, 모음의 경우

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

: 백엔드 및 RestTemplate 번호 교환의 많은 변종 중 하나를 사용

// 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"이 어디서 왔는지 모르기 때문에 코드를 구현하지 않았습니다. 그 HAL_JSON 대신 MediaType.parseMediaType ("application/hal + json") 대신 사용하려고 시도하고 작동하지 않습니다. 오류는 동일합니다 : START_ARRAY 토큰에서 java.lang.String의 인스턴스를 비 직렬화 할 수 없습니다. –

+0

정확한 경로 : 문서를 읽을 수 없습니다 : java.lang의 인스턴스를 직렬화 해제 할 수 없습니다.START_ARRAY 토큰 에서 [out : 출처 : [email protected]; 줄 : 1, 열 : 9] (참조 사슬을 통해 : com.example.core.webservicesrepositories.accounts.entities.Account [ "name"]); 중첩 예외는 com.fasterxml.jackson.databind.JsonMappingException입니다. START_ARRAY 토큰 중 java.lang.String 인스턴스를 deserialize 할 수 없습니다. –

+0

postForEntity와 교환을 사용하여 해당 POST를 대체하여 문제를 해결할 수있었습니다. 당신이 저를 너무 많이 풀어 주었던 이래로 당신의 답을 하나씩 점검 할 것입니다. 고마워요! 이 질문을하기 전에 당신이 제안한대로 GET을했고, RestTemplate에 조율하지 않고도 효과가있었습니다. 왜 그런지 알 수 있습니까? –