2017-02-20 34 views
2

Я разрабатываю облачное приложение, чтобы немного помахать с Spring Cloud и т. Д. Теперь я застрял, пытаясь отправить запрос POST или PUT на бэкэнд Spring Data Restend с помощью API RestTemplate, но все, что я пробовал, заканчивается ошибкой: HttpMessageNotReadableException: не может десериализовать экземпляр java.lang.String из токена START_OBJECT, HttpMessageNotReadableException : Не удалось прочитать документ: не удается десериализовать экземпляр java.lang.String из маркера START_ARRAY, ... из запроса с типом содержимого приложения/xml; charset = UTF-8 !, Error 400 null ... вы его называете , После исследования я обнаружил, что на самом деле довольно сложно потреблять HAL JSON с RestTemplate (гиперссылка JSON уровня 3, если я правильно помню), но я хочу знать, возможно ли это.Отправлять POST и PUT через RestTemplate в Spring Data Rest Api

Я бы хотел увидеть некоторые рабочие (подробные, если это возможно) примеры RestTemplate, отправляющие POST и PUT в бэкэнд памяти данных Spring.

Редактировать: Я попробовал 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

Другие из них просто повторить одна из этих ошибок.

+0

Не забудьте поделиться своим кодом? Мы определенно будем рады помочь – Coder

+0

Вы уверены, что сервер вернет тело при публикации? – zeroflagL

+0

Сервер ничего не возвращает, потому что RestTemplate ломается. Это дает неверную ошибку запроса на контроллере и ошибку, которую я прокомментировал в ответе в бэкэнде Spring Data Rest. –

ответ

3

Вам необходимо настроить свой RestTemplate, чтобы он мог использовать тип контента /hal + json.

Это уже было указано в некоторых других сообщениях, таких как this one или that one, а также на кучке сообщений в блоге, таких как here. Следующее решение работает для проекта Spring загрузки:

Во-первых, настроить 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; 
    } 

}

Тогда пусть весна впрыскивать RestTemplate где вы должны потреблять REST бэкенд, и использовать один из множества вариантов RestTemplate # обмена:

@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 и не работает. Ошибка одинакова: нельзя десериализовать экземпляр java.lang.String из токена START_ARRAY –

+0

Это точный трек: не удалось прочитать документ: невозможно десериализовать экземпляр java.lang.Строка из токена START_ARRAY в [Источник: [email protected]; строка: 1, столбец: 9] (через цепочку ссылок: com.example.core.webservicesrepositories.accounts.entities.Account ["name"]); Вложенное исключение - com.fasterxml.jackson.databind.JsonMappingException: не удается десериализовать экземпляр java.lang.String из токена START_ARRAY –

+0

Мне удалось решить его, заменив этот POST, используя обмен с postForEntity. Я проверю ваш ответ как тот, поскольку вы слишком много наводили меня на решение этого. Большое спасибо! У меня был GET, как вы предложили, прежде чем я задал этот вопрос, и он работал даже без этой мелодии в RestTemplate, вы знаете, почему? –