简体   繁体   中英

Spring Boot API returns json without labels

I'm building a rest API with Java Spring Boot and I'm running into a problem, I have the following class with a method (which is in my controller for testing purposes, I will send its logic to the service later):

@RestController
@RequestMapping("/api/readings")
public class Readings {
    @Autowired
    private ReadingService readingService;

    @RequestMapping(method = RequestMethod.GET, produces = "application/json")
    public List<Reading> getRelevant(@RequestParam("start") String start, @RequestParam("end") String end){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:MM:SS");
        start += " 00:00:00";
        end += " 23:59:59";
        try {
            Date startdate = df.parse(start);
            Date enddate = df.parse(end);
            return readingService.getRelevant(startdate, enddate);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
}

This makes use of a service that calls the following repository function:

@Query("SELECT pmtwofive, pmten, recording FROM Reading WHERE recording >= ?1 AND recording <= ?2")
List<Reading> getRelevant(Date start, Date end);

Everything works fine, except for the format of the result:

[[10,20,1505801743816],[14,21,1505802311976],[14,21,1505802330610],[10,13,1505803302960],[10,13,1505803321966]]

Instead of this, I was expecting something like I get when using the CrudRepository from hibernate querying my whole table instead of just these three values:

{
    {
        pmtwofive: 10,
        pmten: 20,
        reading: 1505801743816
    },
    {
        ...
    }
}

What should I do to get my expected result? Thank you!

Reading Class:

package com.amione.models;

import javax.persistence.*;
import java.sql.Timestamp;

@Entity
public class Reading {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(columnDefinition = "serial")
    private long reading_id;

    private int sensor_id;
    private int function;
    private int directionstart;
    private int pmtwofive;
    private int pmten;
    private int checksumlow;
    private int checksumhigh;
    private Timestamp recording;

    public long getReading_id() {
        return reading_id;
    }

    public void setReading_id(int reading_id) {
        this.reading_id = reading_id;
    }

    public int getSensor_id() {
        return sensor_id;
    }

    public void setSensor_id(int sensor_id) {
        this.sensor_id = sensor_id;
    }

    public int getFunction() {
        return function;
    }

    public void setFunction(int function) {
        this.function = function;
    }

    public int getDirectionstart() {
        return directionstart;
    }

    public void setDirectionstart(int directionstart) {
        this.directionstart = directionstart;
    }

    public int getPmtwofive() {
        return pmtwofive;
    }

    public void setPmtwofive(int pmtwofive) {
        this.pmtwofive = pmtwofive;
    }

    public int getPmten() {
        return pmten;
    }

    public void setPmten(int pmten) {
        this.pmten = pmten;
    }

    public int getChecksumlow() {
        return checksumlow;
    }

    public void setChecksumlow(int checksumlow) {
        this.checksumlow = checksumlow;
    }

    public int getChecksumhigh() {
        return checksumhigh;
    }

    public void setChecksumhigh(int checksumhigh) {
        this.checksumhigh = checksumhigh;
    }

    public Timestamp getRecording() {
        return recording;
    }

    public void setRecording(Timestamp recording) {
        this.recording = recording;
    }
}

Ok I have the answer. It must be done with custom constructor:

@Data
@EqualsAndHashCode(callSuper = true)
@Entity
public class City extends AbstractEntity {

@Column
private String name;

@Embedded
private Geopoint centre=new Geopoint();

public City(){}
public City(String name){
    this.setName(name);
    }
//  @OneToMany(mappedBy="city")
//  private Set<Place> places;

}

Repository:

public interface CityRepository extends JpaRepository<City, Long>{

    City findOneByName(String name);
    @Query("SELECT name FROM City")
    public List<City> findMethod1();

    @Query("SELECT c.name FROM City c")
    public List<City> findMethod2();

Controller:

@Autowired
private CityRepository cityRepository;
@GetMapping("/test")
public List<City> test(){
    List<City> ret=new ArrayList();
    ret.addAll(cityRepository.findMethod1());
    ret.addAll(cityRepository.findMethod2());
    ret.addAll(cityRepository.findMethod3());
    return ret;
}

and the result:

在此处输入图片说明

As you can see, 3rd method works. I told you it will came up.

As empty values are still serialized, you can use a DTO object to encapsule only required fields (and SELECT new EntityDTO(field1,field2,field3) FROM Entity )

Another option would bo to configure Jackson to not to serialize null values with annotation or configuratio, but that is just beyond the scope of question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM