通过 RestTemplate 发送 POST 和 PUT 到 Spring 数据 Rest Api
Send POST and PUT through RestTemplate to a Spring Data Rest Api
我一直在开发一个云应用程序来与 Spring 云等有点混乱。现在我一直在尝试使用 RestTemplate API 向 Spring Data Rest 后端发送 POST 或 PUT 请求,但我尝试的所有操作都以错误结束:HttpMessageNotReadableException:无法反序列化实例来自 START_OBJECT 令牌的 java.lang.String,HttpMessageNotReadableException:无法读取文档:无法反序列化来自 START_ARRAY 令牌的 java.lang.String 的实例,...来自内容类型为application/xml;charset=UTF-8!, Error 400 null... 随你便。经过研究,我发现实际上很难使用 RestTemplate(如果我没记错的话是 3 级 JSON 超媒体)使用 HAL JSON,但我想知道这是否可能。
我希望看到 RestTemplate 发送 POST 和 PUT 到 Spring Data Rest 后端的一些工作示例(如果可能,请详细说明)。
编辑:我尝试了 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"].
也像这样尝试并得到关于 header 是 application/xml 的错误:RestTemplate POSTing entity with associations to Spring Data REST server
其他的只是重复其中一个错误。
您需要配置 RestTemplate,以便它可以使用 application/hal+json 内容类型。
它已经在其他一些帖子中得到解决,例如 this one or , and on a bunch of blog posts, such as here。
以下解决方案适用于 Spring 引导项目:
首先,使用 bean 配置 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;
}
}
然后,让 Spring 在您需要使用 REST 后端的地方注入 RestTemplate,并使用 RestTemplate#exchange 的众多变体之一:
@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();
//
我一直在开发一个云应用程序来与 Spring 云等有点混乱。现在我一直在尝试使用 RestTemplate API 向 Spring Data Rest 后端发送 POST 或 PUT 请求,但我尝试的所有操作都以错误结束:HttpMessageNotReadableException:无法反序列化实例来自 START_OBJECT 令牌的 java.lang.String,HttpMessageNotReadableException:无法读取文档:无法反序列化来自 START_ARRAY 令牌的 java.lang.String 的实例,...来自内容类型为application/xml;charset=UTF-8!, Error 400 null... 随你便。经过研究,我发现实际上很难使用 RestTemplate(如果我没记错的话是 3 级 JSON 超媒体)使用 HAL JSON,但我想知道这是否可能。
我希望看到 RestTemplate 发送 POST 和 PUT 到 Spring Data Rest 后端的一些工作示例(如果可能,请详细说明)。
编辑:我尝试了 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"].
也像这样尝试并得到关于 header 是 application/xml 的错误:RestTemplate POSTing entity with associations to Spring Data REST server
其他的只是重复其中一个错误。
您需要配置 RestTemplate,以便它可以使用 application/hal+json 内容类型。
它已经在其他一些帖子中得到解决,例如 this one or
首先,使用 bean 配置 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;
}
}
然后,让 Spring 在您需要使用 REST 后端的地方注入 RestTemplate,并使用 RestTemplate#exchange 的众多变体之一:
@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();
//