Mam problem z wykorzystaniem Spring's RestTemplate z modułem hateoas do tworzenia nowych powiązanych obiektów. Próbowałem już pobrać obiekt Foo i przypisać go do obiektu Bar, który próbuję utworzyć. Kiedy ogłaszam, że serwer daje mi HTPp 400 Bad Request. Kiedy próbowałem umieścić przedmiot zasobów z linkiem, mam ten wyjątek:Nie można wysłać nowej encji ze związkiem za pomocą RestTemplate i 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]
jestem ze stratą na zastanawianie się, jak stworzyć poprawne żądanie POST przy użyciu RestTemplate przeciwko służbie Wiosna danych REST.
Tło: Mam dwie klasy Foo i Bar. Foo ma OneToMany relacje z Barem, a więc Bar ma związek ManyToOne z Foo.
Kod dla każdej klasy jest następujący:
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;
}
Ja próbując odpowiedzieć na http://nonexistantdomain.com.mx.uk.ch:8080/bars aby utworzyć nowy pasek, który jest związane z foo którego FOO_I jest 1.
Widzę wyjście z rzeczy l ike http://nonexistantdomain.com.mx.uk.ch:8080/foos/1 i http://nonexistantdomain.com.mx.uk.ch:8080/foos/1/bars i http://nonexistantdomain.com.mx.uk.ch:8080/bars/5. Wiem więc, że związki działają.
Dalej jestem w stanie utworzyć nowy pasek używając wget i następujące pocztowy ciało 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"
}
Który działa skutecznie. Jak mogę użyć Spring's RestTemplate, aby to zrobić, abym mógł osiągnąć to, czego potrzebuję z mojego kodu Java?
Edytuj:
Oto przykłady, których próbowałem.
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);
}
Wszystkie trzy przykłady kończą się niepowodzeniem z różnych powodów.
Zobaczymy, czy rozumiem pytanie, nie można utworzyć nowy Publikuj instancję, która ma pożądany zestaw "Foo". Jeśli nie możesz utworzyć nowego paska, dlaczego możesz zobaczyć relacje i obiekt paska? Jeśli nie możesz utworzyć nowego pręta, to nie powinno być obiektu z paskiem? – hofan41
Jak tworzysz tę wiadomość? JavaScript? – yunandtidus
Proszę podać pełny ślad stosu + kod klienta java (który próbuje utworzyć pasek) –