Non riesco a utilizzare Spring RestTemplate con il modulo hateoas per creare nuove entità correlate. Ho provato a recuperare un oggetto Foo e ad assegnarlo all'oggetto Bar che sto cercando di creare. Quando post che il server mi dà una richiesta Bad Http 400. Quando ho provato a inserire un oggetto di risorse con un link, ottengo questa eccezione:Impossibile pubblicare nuova entità con relazione usando RestTemplate e Spring Data REST
Exception in thread "main" org.springframework.web.client.RestClientException: Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.hateoas.Resource]
Sono in perdita per capire come creare la richiesta POST corretta utilizzando RestTemplate contro un servizio di primavera dati REST.
Contesto: Ho due classi Foo e Bar. Foo ha una relazione OneToMany con Bar e quindi Bar ha una relazione ManyToOne con Foo.
Il codice per ogni classe è la seguente:
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;
}
Sto tentando di inviare a http://nonexistantdomain.com.mx.uk.ch:8080/bars per creare un nuovo bar che è relativo a un foo il cui FOO_I è 1.
Riesco a vedere l'output dalle cose l ike http://nonexistantdomain.com.mx.uk.ch:8080/foos/1 e http://nonexistantdomain.com.mx.uk.ch:8080/foos/1/bars e http://nonexistantdomain.com.mx.uk.ch:8080/bars/5. Quindi so che le relazioni stanno funzionando.
Inoltre sono in grado di creare una nuova barra utilizzando wget e il seguente corpo post per 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"
}
che opera con successo. Come posso utilizzare Spring's RestTemplate per fare questo in modo da poter realizzare ciò che mi serve dal mio codice java?
Edit:
Ecco gli esempi che ho provato.
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);
}
Tutti e tre gli esempi non riescono per motivi diversi.
Vediamo se ho capito la domanda, non è possibile creare un nuovo Istanza di Bar tramite post che ha il set "Foo" desiderato. Se non riesci a creare una nuova barra, perché sei in grado di vedere le relazioni e l'oggetto bar? Se non è possibile creare una nuova barra, non dovrebbe esserci un oggetto bar giusto? – hofan41
Come stai facendo questa richiesta? Javascript? – yunandtidus
Fornire codice stack completo + codice java del client (che tenta di creare una barra) –