Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 向Spring数据Rest Api发送POST并传递RestTemplate_Json_Spring Data Rest_Resttemplate_Spring Hateoas - Fatal编程技术网

Json 向Spring数据Rest Api发送POST并传递RestTemplate

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_

我一直在开发一个云应用程序,让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,结果出现了各种各样的错误。这些是我尝试过的一些片段(还有更多,只是我处理了它们)

我的实体:

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

//