menteith
menteith

Reputation: 678

Spring sends empty JSON despite of object being not null

In my controller I have the following method:

    @RequestMapping(value = "/getAll", method = RequestMethod.GET)
    public List<Topic> getAllTopics() {

        List<Topic> allTopics = service.getAllTopics();

        assert allTopics.size() > 0; // is not empty
        System.out.println(allTopics.get(0)); // Topic{id=1, name='bla', description='blahhh'}

        return allTopics;
    }

When I go to http://localhost:8080/getAll I get [{},{},{},{}] as a result but service.getAllTopics() returns non empty List So the list to be send is not empty but the browser receives invalid JSON. However, there is no problem in serializing objects since the following method return valid JSON. What's the problem?

    @GetMapping("/json")
    public List<Locale> getLocales() {
        return Arrays.asList(DateFormat.getAvailableLocales());
    }

I'm running latest Spring Boot, i.e. 2.1.3.RELEASE.

Update Here's my entity class - Topic

@Entity
@Table(name = "topic", schema="tetra")
public class Topic {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private String description;

    public Topic() {
    }

    public Topic(String name, String description) {
        this.name = name;
        this.description = description;
    }

    @Override
    public String toString() {
        return "Topic{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", description='" + description + '\'' +
                '}';
    }
}

Upvotes: 1

Views: 1462

Answers (1)

Ken Chan
Ken Chan

Reputation: 90427

By default , Jackson will only serialise the public fields and public getters into JSON. As the Topic neither have public fields nor the public getter , nothing will be serialised and you get an empty JSON object.

There are plenty of ways to configure it such as:

(1) Simply add public getter for all fields

(2) Use @JsonAutoDetect(fieldVisibility = Visibility.ANY) such that private fields can also be auto detected :

@Entity
@Table(name = "topic", schema="tetra")
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
public class Topic {


}  

(3) Use @JsonProperty to explicitly pick what fields/getter to be serialised .The nice things of this approach is that the field name in JSON can be different from the POJO :

@Entity
@Table(name = "topic", schema="tetra")
public class Topic {

   @JsonProperty("id")
   private Integer id;

   @JsonProperty("name")
   private String name;

   @JsonProperty("description")
   private String description;
}

Upvotes: 2

Related Questions