martin k.
martin k.

Reputation: 166

How to make Spring Boot's GET return JSON

I have a little beginner's mistake in my project. I'm building a RESTful service with Spring Boot and my get method doesn't work.


I made an Entity called Project, that looks like this:

@Entity
@Table(name="project")
public class ProjectDto {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id")
    private long id;

    @Column(name="caption")
    private String caption;

    ..GETTERS AND SETTERS FOLLOW..

, than I created ProjectRepository like this:

@Repository
public interface ProjectRepository extends JpaRepository<ProjectDto, Long> {

    public static final String GET_TIMELINE_PROJECT_CAPTIONS_QUERY = "SELECT 
    p.id, p.caption FROM ProjectDto p ORDER BY p.creationDate DESC";

    @Query(GET_TIMELINE_PROJECT_CAPTIONS_QUERY)
    public List<ProjectDto> getTimelineProjectCaptions();

}

..and a Controller

@RestController
@RequestMapping("/project")
public class ProjectController {

    @Autowired
    private ProjectRepository projectRepository;


    @CrossOrigin(origins = "http://localhost:4200")
    @RequestMapping(value = "/timeline", method = RequestMethod.GET)
    public List<ProjectDto> getTimelineProjectCaptions() {
        return projectRepository.getTimelineProjectCaptions();
    }

}

but that gives[[5,"sddf"],[3,"asdf"],[2,"gb"],[1,"bg"]], which apparently isn't JSON

Upvotes: 0

Views: 3387

Answers (3)

Eirick Sayson
Eirick Sayson

Reputation: 11

You can use Projections.

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections.interfaces

If this is your Table

@Entity
@Table(name="project")
public class Project {

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name="id")
   private long id;

   @Column(name="caption")
   private String caption;

   @Temporal(TemporalType.DATE)
   @Column(name="creationDate")
   private Date creationDate;

// .. other columns ..
// ..GETTERS AND SETTERS FOLLOW..

Add an Interface-based projections

public interface ProjectCaption {
  Long getId();
  String getCaption();
}

Then add AS keyword on your query and change the return of your method

@Repository
public interface ProjectRepository extends JpaRepository<Project, Long>{

    @Query("SELECT p.id AS id, p.caption AS caption FROM Project p ORDER BY p.creationDate DESC")
    public List<ProjectCaption> getTimelineProjectCaptions();

}

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 692121

It is JSON. It's an array of arrays, which is what your query actually returns.

If you want an array of ProjectDto objects, the query should be

SELECT p FROM ProjectDto p ORDER BY p.creationDate DESC

Not sure why you're naming your entities with a Dto suffix. Entities are not DTOs. A DTO is a Data Transfer Object, i.e. an object specifically designed for data transfer.

Upvotes: 3

Patr&#237;cia Espada
Patr&#237;cia Espada

Reputation: 248

You can try changing your method to something like this:

@RequestMapping(value = "/timeline", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<ProjectDto>> getTimelineProjectCaptions() {
    return new ResponseEntity<List<ProjectDto>>(projectRepository.getTimelineProjectCaptions(), HttpStatus.OK);
}

Upvotes: 0

Related Questions