2014-12-11 16 views
5

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.

+0

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

+0

Come stai facendo questa richiesta? Javascript? – yunandtidus

+0

Fornire codice stack completo + codice java del client (che tenta di creare una barra) –

risposta

2

Che dire di questo codice:

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

Sarebbe utile se ci fai vedere che cosa si programma finora sul tuo RestTemplate

Problemi correlati