【问题标题】:Spring Boot REST API gives empty rowsSpring Boot REST API 提供空行
【发布时间】:2019-07-29 16:36:39
【问题描述】:

我是 Spring Boot 的新手。我有一个 MYSQL 表“客户”,其数据如下所示: Data in the table 使用 Postman 测试 API 输出时,似乎有几行空的 JSON 输出。

API Output

下面是我的代码:

package com.semika.customer;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="customer") 
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

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

    public Customer() {
       super();

    }

}

客户存储库

package com.semika.customer;

import org.springframework.data.repository.CrudRepository;

public interface CustomerRepository extends CrudRepository<Customer, Long>{

}

客户服务

package com.semika.customer;

public interface CustomerService {
    public Iterable<Customer> findAll(); 
}

CustomerServiceImpl

package com.semika.customer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CustomerServiceImpl implements CustomerService{

    @Autowired
    private CustomerRepository customerRepository;

    public Iterable<Customer> findAll() {
        return customerRepository.findAll(); 
    }
}

客户控制器

package com.semika.customer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CustomerController {
    @Autowired
    private CustomerService  customerService;

    @RequestMapping("/customers") 
    @ResponseBody
    public Iterable<Customer> findAll() {
       Iterable<Customer> customers = customerService.findAll();
       return customers;
    }
}

我不知道我还需要在控制器中修改什么才能看到带有数据的输出。

【问题讨论】:

  • 有什么错误吗?我建议调试

标签: java rest spring-boot


【解决方案1】:

乍一看,您的代码看起来不错。所以,我复制了你的代码并尝试运行它并得到一个空响应,就像你一样。花了一些时间后,我弄清楚了原因。

Use getter and setter in you customer class and recompile the code.

它会解决你的问题。还要进行以下更改:

1) Annotate CustomerRepository with @Repository
2) use @EnableJpaRepositories("package path") in your application's main class if your repository is not in the same or sub package.
3) use method type or @GetMapping annotation in your controller.

为了您的方便,我在所有修改后编写您的代码:

TestDemoApplication.java

    package testdemo;

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

    @SpringBootApplication
    @EnableJpaRepositories("put repository path here")
    public class TestDemoApplication {

        public static void main(String[] args) {
            SpringApplication.run(TestDemoApplication.class, args);
        }
    }

CustomerServiceImpl.java

package testdemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CustomerServiceImpl implements CustomerService{

    @Autowired
    private CustomerRepository customerRepository;

    public Iterable<Customer> findAll() {
        return customerRepository.findAll(); 
    }
}

CustomerService.java

package testdemo;

public interface CustomerService {
    public Iterable<Customer> findAll(); 
}

CustomerRepository.java

package testdemo;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface CustomerRepository extends CrudRepository<Customer, Long>{

}

CustomerController.java

package testdemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CustomerController {

    @Autowired
    private CustomerService  customerService;

    @GetMapping(value = "/customers") 
     public Iterable<Customer> findAll() {
       Iterable<Customer> customers = customerService.findAll();
       return customers;
    }
}

Customer.java

package testdemo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="customer") 
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

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

    public Customer() {
       super();

    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

此外,CrudRepository 在 findAll() 中返回一个 Iterable。它是返回 List 的 JpaRepository,所以不用担心。

【讨论】:

    【解决方案2】:

    您可能需要遍历数据集并将结果添加到 List 或如 Vishal 所述,更改您的接口和实现以返回 List 而不是 Iterable

    package com.semika.customer;
    
    import java.util.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    public class CustomerController {
        @Autowired
        private CustomerService  customerService;
    
        @RequestMapping("/customers") 
        @ResponseBody
        public Iterable<Customer> findAll() {
            List<Customer> results = new ArrayList<>();
            Iterator<Customer> iter = customerService.findAll().iterator();
            while (iter.hasNext()) results.add(iter.next());
            return results;
        }
    }
    

    在以下postAndy 状态下,

    虽然List 保证是Iterable,但Iterable 可能不是List。这意味着如果您将Iterable 转换为List,它可能会在运行时失败。即使它有效,也不能保证它会在未来继续有效,因为它可能会在新版本的 Spring Data JPA 中发生变化而不会破坏接口的约定。

    您应该声明自己的返回 List 的查询方法,而不是使用强制转换。

    在那篇文章中还指出,您可以使用JpaRepository 而不是CrudRepository,因为JPA 将返回List 而不是Iterable,如here 所述。

    【讨论】:

    • 我已将如上所示的代码修改为: 1. 使用 JpaRepository 而不是 CrudRepository 如上所述:2. 我还在控制器中将 Iterable 替换为 List :但行仍然是空的。
    • 你需要将Iterable的三个方法全部更改为返回List,在服务、服务实现和控制器中。
    • 还是不行。仍然给我三行数据的三个空 json 输出
    猜你喜欢
    • 2019-12-28
    • 1970-01-01
    • 2021-08-28
    • 2019-03-11
    • 2020-11-13
    • 2015-05-31
    • 2018-03-30
    • 2020-03-15
    • 2023-03-25
    相关资源
    最近更新 更多