Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with Spring Boot returning Map with own object as key

I have a problem with Spring Boot. I am making a REST application, and I have a service that returns a Map(Share, Integer)

Share is a class written by me:

public class Share {

    private String ticker;
    private String name;
    private Double value;

    public Share() {
        super();
    }

    public Share(String ticker, String name, Double value) {
        super();
        this.ticker = ticker;
        this.name = name;
        this.value = value;
    }

    public String getTicker() {
        return ticker;
    }

    public void setTicker(String ticker) {
        this.ticker = ticker;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getValue() {
        return value;
    }

    public void setValue(Double value) {
        this.value = value;
    }

    @Override
    public int hashCode() {
       final int prime = 31;
       int result = 1;
        result = prime * result + ((ticker == null) ? 0 : ticker.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Share other = (Share) obj;
        if (ticker == null) {
            if (other.ticker != null)
                return false;
            } else if (!ticker.equals(other.ticker))
                return false;
        return true;
    } 

    @Override
    public String toString() {
        return "Share [ticker=" + ticker + ", name=" + name + ", value=" + value + "]";
    }
}

And the @RestController is:

public class ShareController {

    @Autowired
    private ShareBussines shareBussines;

    @RequestMapping("/getShare/{ticker}")
    public Share getShare(@PathVariable("ticker") String ticker) throws BrokerNotFoundException, BrokerArgumentException, BrokerGeneralException {
        return shareBussines.getShare(ticker);
    }

    @RequestMapping(value="/buyShares", method=RequestMethod.POST)
    public Map<Share, Integer> buyShares(@RequestBody Map<String,Double> sharesToBuy) throws BrokerGeneralException, BrokerArgumentException, BrokerInsufficientStockException {
        return shareBussines.buyShares(sharesToBuy);
    }

}

The problem is when I call the service from Postman.

The result is:

{
    "Share [ticker=AMZN, name=Amazon, value=259.32126508258295]": 1,
    "Share [ticker=GOOGL, name=Google, value=249.35339337497606]": 1,
    "Share [ticker=FB, name=Facebook, value=181.15005639608364]": 55
}

The Map key is share.toString()... I want the key to be the share JSON. I try to remove the toString method from Share class, but the result was:

{
    "Share@1eb87f": 1,
    "Share@40d9fab": 1,
    "Share@8db": 54
}

It is using the Object's toString().

Thank you for your advice.

like image 890
Alejandro Leone Avatar asked Sep 11 '25 10:09

Alejandro Leone


1 Answers

First, it works as you coded it to work:

@RequestMapping(value="/buyShares", method=RequestMethod.POST)
public Map<Share, Integer> buyShares(@RequestBody Map<String,Double> sharesToBuy) throws BrokerGeneralException, BrokerArgumentException, BrokerInsufficientStockException {
    return shareBussines.buyShares(sharesToBuy);
}

Share is a key here. And that is kinda weird. Why not create some object like:

public class ShareResponse {
    private Share share;
    private Integer someVal; // that's the one you have in your Map as a value

    // getters and setters
}

And afterward change your service a bit:

@RequestMapping(value="/buyShares", method=RequestMethod.POST)
public List<ShareResponse>  buyShares(@RequestBody Map<String,Double> sharesToBuy) throws BrokerGeneralException, BrokerArgumentException, BrokerInsufficientStockException {
    // do your business here, create a list of ShareResponse and return it
    return shareBussines.buyShares(sharesToBuy); // instead of this
}

And you should get a valid, nicely 'formatted' JSON. If you need each item to be identifiable by some unique value just add some ID field to ShareResponse.

Does it make any sense?)

like image 168
ikos23 Avatar answered Sep 14 '25 01:09

ikos23