Unable to send new relationship object using RestTemplate and Spring Data REST

I am trying to use Spring RestTemplate with the hateoas module to create new related objects. I tried to extract the Foo object and assign it to the Bar object that I am trying to create. When I send a message, the server gives me an Http 400 Bad Request. When I tried to publish the Resource object with a link, I get this exception:

Exception in thread "main" org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.hateoas.Resource] 

I find it difficult to figure out how to create the correct POST request using RestTemplate using the Data REST service.

Background: I have two classes Foo and Bar. Foo has a OneToMany relationship with Bar, and therefore Bar has a ManyToOne relationship with Foo.

The code for each class is as follows:

Foo:

 package com.foo; //Imports omitted for clarity @Entity @Getter @Setter @Table(name="Foo", schema="dbo") public class Foo implements Identifiable<Integer> { @Id @Column(name="FOO_I") @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column(name="Name") private String name; @Column(name="descript") private String description; @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="foo") private Set<Bar> bars; } 

Bar:

 package com.foo; @Entity @Getter @Setter @Table(name="Bar", schema="dbo") public class Bar implements Identifiable<Integer> { @Id @Column(name="BAR_I") @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column(name="barname") private String name; @Column(name="bardescription") private String description; @Column(name="qty") private int qty; @ManyToOne @JoinColumn(name="FOO_I", referencedColumnName="FOO_I", nullable=false) private Foo foo; } 

I am trying to publish http://nonexistantdomain.com.mx.uk.ch:8080/bars to create a new panel related to foo whose FOO_I is 1.

I can see the output from things like http://nonexistantdomain.com.mx.uk.ch:8080/foos/1 and http://nonexistantdomain.com.mx.uk.ch:8080/foos/1/bars and http://nonexistantdomain.com.mx.uk.ch:8080/bars/5 . Therefore, I know that relationships work.

Next, I can create a new panel using wget and the following message body http://nonexistantdomain.com.mx.uk.ch:8080/bars/ :

 { "name": "newWgetBar", "description": "just another bar", "qty": 2, "foo" : "http://nonexistantdomain.com.mx.uk.ch:8080/foos/1" } 

What works successfully. How can I use Spring RestTemplate for this to accomplish what I need from my java code?

Edit:

Here are the examples I tried.

 private RestTemplate acquireTemplate(boolean isHalJson) { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.registerModule(new Jackson2HalModule()); mapper.registerModule(new JodaModule()); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json")); converter.setObjectMapper(mapper); return new RestTemplate(Collections.<HttpMessageConverter<?>> singletonList(converter)); } public void addABar(String name) { Bar b = new Bar(); b.setName(name); b.setDescription("An added bar."); b.setQty(2); RestTemplate template = acquireTemplate(); ResponseEntity<Foo> f = template.getForEntity("http://localhost:8080/foos/1", Foo.class); Link l = new Link("foo","http://localhost:8080/foos/1"); Resource<Bar> r = new Resource<Bar>(b,l); URI i = template.postForLocation("http://localhost:8080/bars", r); } public void addABarAttempt2(String name) { Bar b = new Bar(); b.setName(name); b.setDescription("An added bar."); b.setQty(2); RestTemplate template = acquireTemplate(); ResponseEntity<Foo> f = template.getForEntity("http://localhost:8080/foos/1", Foo.class); b.setFoo(f.getBody()); URI i = template.postForLocation("http://localhost:8080/bars", b); } public void addABarAttempt3(String name) { Bar b = new Bar(); b.setName(name); b.setDescription("An added bar."); b.setQty(2); RestTemplate template = acquireTemplate(); template.put("http://localhost:8080/foos/1/bars",b); } 

All three examples are not suitable for various reasons.

+5
source share
1 answer

How about using this code:

  RestTemplate restTemplate = new RestTemplate(); restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter()); restTemplate.getMessageConverters().add(new StringHttpMessageConverter()); String uri = new String("url"); Bar b= new Bar(); bar.setName("newWgetBar"); rt.postForObject(uri, b, Bar.class); 

it would be helpful if you show us that you are still programming on RestTemplate

+2
source

Source: https://habr.com/ru/post/1208778/


All Articles