Json 向Spring数据Rest Api发送POST并传递RestTemplate
我一直在开发一个云应用程序,让SpringCloud之类的东西有点乱。现在,我一直在尝试使用RestTemplate API向Spring数据Rest后端发送POST或PUT请求,但我尝试的所有操作都以一个错误结束:HttpMessageTreadableException:无法从START_对象令牌中反序列化java.lang.String的实例,HttpMessageNodeTableException:无法读取文档:无法从内容类型为application/xml的请求中反序列化START_数组令牌中的java.lang.String实例;字符集=UTF-8!,错误400空。。。你说吧。经过研究,我发现用RestTemplate(如果我没记错的话,是3级JSON超媒体)使用HAL JSON实际上是相当困难的,但我想知道这是否可行 我希望看到一些RestTemplate发送POST并放到SpringDataREST后端的工作(如果可能的话,请详细说明)示例 编辑:我尝试了postForEntity、postForLocation和exchange,结果出现了各种各样的错误。这些是我尝试过的一些片段(还有更多,只是我处理了它们) 我的实体:Json 向Spring数据Rest Api发送POST并传递RestTemplate,json,spring-data-rest,resttemplate,spring-hateoas,Json,Spring Data Rest,Resttemplate,Spring Hateoas,我一直在开发一个云应用程序,让SpringCloud之类的东西有点乱。现在,我一直在尝试使用RestTemplate API向Spring数据Rest后端发送POST或PUT请求,但我尝试的所有操作都以一个错误结束:HttpMessageTreadableException:无法从START_对象令牌中反序列化java.lang.String的实例,HttpMessageNodeTableException:无法读取文档:无法从内容类型为application/xml的请求中反序列化START_
@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"].
创建公共帐户(帐户){
//不起作用:S
MultiValueMap=新链接的MultiValueMap();
add(“name”,account.getName());
add(“username”,account.getUsername());
add(“password”,account.getPassword());
map.add(“authorities”,account.getAuthorities());
HttpHeaders=新的HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
最终HttpEntity=新HttpEntity(映射,
标题);
返回restemplate.exchange(serviceUrl+“/accounts”,HttpMethod.POST,entity,Account.class).getBody();
}
//还尝试使用从ResourceSupport扩展而来的AccountResource,但也不起作用。这个错误告诉我它无法反序列化帐户[“name”]。
也尝试过这样做,但得到了一个关于标头为application/xml的错误:
其他的只是重复其中一个错误。您需要配置RestTemplate,以便它可以使用应用程序/hal+json内容类型 它已经在其他一些帖子中得到了解决,比如or,还有一些博客帖子,比如。 以下解决方案适用于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的众多变体之一:
对于集合,您将操作
//用于集合
参数化类型引用响应类型=
新的ParameteredTypeReference(){};
//得到
PagedResources帐户=
restemplate.exchange(url,HttpMethod.GET,null,responseType.getBody();
//
愿意分享你的代码吗?我们非常乐意为您提供帮助。您确定服务器在发布时会返回一个正文吗?服务器不会返回任何内容,因为RestTemplate已损坏。它在控制器上给出了一个错误的请求错误,以及我在SpringDataREST后端的回答中评论的错误。我记得那个博客,但我没有实现代码,因为我不知道“HAL_JSON”来自哪里。我尝试使用MediaType.parseMediaType(“application/hal+json”)而不是hal_json,但不起作用。错误是相同的:无法反序列化java.lang.String实例的START_数组标记这是确切的轨迹:无法读取文档:无法反序列化java.lang.String实例的START_数组标记,位于[Source:org.apache.catalina.connector]。CoyoteInputStream@278f6875;第1行第9列](通过引用链:com.example.core.webservicesrepositories.accounts.entities.Account[“name”]);嵌套异常是com.fasterxml.jackson.databind.JsonMappingException:无法从START_数组令牌中反序列化java.lang.String实例我设法通过使用postForEntity替换该帖子来解决它。我将检查您的答案,因为您指导我解决这个问题的方式太多了。非常感谢!我有了G在我提出这个问题之前,正如你所建议的那样,即使没有RestTemplate的调子,它也能工作,你知道为什么吗?@ManuelPáez抱歉,我通常省略导入指令以节省一些空间,但有时静态导入有点难以识别。为了清晰起见,我编辑了我的帖子。想想看,postForObject可能是even如果您不关心响应头和状态,则在这种情况下更合适(这样可以避免调用getBody()。
@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);
// for a collection
ParameterizedTypeReference<PagedResources<Account>> responseType =
new ParameterizedTypeReference<PagedResources<Account>>() {};
// GET
PagedResources<Account> accounts =
restTemplate.exchange(url, HttpMethod.GET, null, responseType).getBody();
//