Gustavo Vilas Boas
Gustavo Vilas Boas

Reputation: 13

How can I return an object from a POST method with Spring Boot?

I'm trying to create a communication between two services with Spring Boot, and I'm failing to return a custom object from a POST.

I have tried something like

1st service:

@RestController
@RequestMapping("/broker")
class HostController{
    @PostMapping(value = "/bid")
    public Bid bid(@RequestBody Auction auction){
        return new Bid(new URI("http://url:8080"));
    }
}

2nd service:

ResponseEntity<Bid> response = rest.postForEntity(hostURL + "/bid", auction, Bid.class);
response.getBody();

The problem is I get an error message saying "cannot deserialize from Object value" for the Bid class, which makes me think the Auction is being sent but the Bid isn't sent back.

I'm also not sure how the serialization happens for the auction, as I only put the "@RequestBody" and it started working. The Auction class even has a Bid object inside, but that doesn't seem to be a problem.

class Bid{
    private URI host;
    
    public Bid(URI host){ this.host = host; }

    public URI getHost() { return host; }
}

class Auction{
    URI host;

    private Bid winner; //Not defined when the problem happens

    public Auction(URI host){ this.host = host; }
    
    public URI getHost(){ return host; }
}

The full stack trace is gigantic, but the part I think is relevant is this:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.gustavovbs.microservicesoffloading.Bid` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)\n at [Source: (PushbackInputStream); line: 1, column: 2]\n\tat
 
com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)\n\tat
 com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1764)\n\tat
 com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)\n\tat

com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1209)\n\tat
 com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1415)\n\tat
 com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:362)\n\tat
 com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:195)\n\tat
 com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)\n\tat
 com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4593)\n\tat
 com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3601)\n\tat
 org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:378)\n\t... 63 more\n","message":"Type definition error: [simple type, class com.gustavovbs.microservicesoffloading.Bid]; 

nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.gustavovbs.microservicesoffloading.Bid` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)\n at [Source: (PushbackInputStream); line: 1, column: 2]","path":"/broker/broadcast"}"

Upvotes: 1

Views: 1945

Answers (2)

Gustavo Vilas Boas
Gustavo Vilas Boas

Reputation: 13

I managed to make it work just by adding the default constructor to the Bid class, as discussed in the comments.

class Bid{
    private URI host;

    public Bid(){}
    
    public Bid(URI host){ this.host = host; }

    public URI getHost() { return host; }
}

Upvotes: 0

huseyinkadioglu
huseyinkadioglu

Reputation: 119

When you transfer some stuff, make sure its serializable and also dont forget to add no arg constructor. This should work.

   class Bid implements Serializable {
    
    private URI host;

    public Bid();

    public URI getHost() {
        return host;
    }

    public void setHost(URI host) {
        this.host = host;
    }
}

Upvotes: 2

Related Questions