【问题标题】:Spring REST Controller returns empty JSON. Iterable data structure. Why?Spring REST 控制器返回空 JSON。可迭代的数据结构。为什么?
【发布时间】:2018-08-13 12:44:40
【问题描述】:

我意识到有人问了一个非常相似的问题并结束了,因为它不够具体,也没有具体说明结果。 Closed Off Topic

问题:从 REST 控制器返回的 JSON 为空。经过验证的数据存在并且在 Iterable 中。

预期结果:将返回一个包含对象的 JSON 数组。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.codeexcursion</groupId>
  <organization>
    <name>Chris Lynch</name>
  </organization>
  <version>1.00.000</version>
  <artifactId>work-tracking</artifactId>
  <packaging>jar</packaging>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.10.RELEASE</version>
  </parent>

  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>


  <name>Work Tracking</name>

  <inceptionYear>2017</inceptionYear>

  <developers>
    <developer>
      <id />
      <name>Chris Lynch</name>
      <email>chrislynch42@yahoo.com</email>
      <timezone>-4</timezone>
      <roles>
        <role>Chief cook and bottle washer.</role>
      </roles>
    </developer>
  </developers>

  <dependencies>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-all</artifactId>
      <version>1.10.19</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>1.5.10.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <version>1.5.10.RELEASE</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
      <version>1.5.10.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-rest</artifactId>
      <version>1.5.10.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.apache.derby</groupId>
      <artifactId>derby</artifactId>
      <version>10.13.1.1</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>


  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <mainClass>com.codeexcursion.Application</mainClass>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

实体

//Package and import Omitted

@Entity
public class Category {

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

  private Long parentId;

  private String title;

  private String description;

  protected Category() {
  }

  public Category(final String title, String description) {
    this(0L, title, description);
  }

  public Category(Long parentId, final String title, String description) {
    if (parentId == null) {
      parentId = 0L;
    }
    if (title == null || title.trim().isEmpty()) {
      throw new IllegalArgumentException("Title may not be null or empty.");
    }
    if (description == null) {
      description = "";
    }
    this.parentId = parentId;
    this.title = title;
    this.description = description;
  }

  @Override
  public String toString() {
    return "id = " + id + "; parentId=" + parentId + "; title=" + title + "; description=" + description;
  }


}

资源

//Package and import Omitted

@Repository
public interface CategoryCRUD  extends CrudRepository<Category, Long> {
  List<Category> findByTitle(String title);
}

休息控制器

//Package and import Omitted

@RestController
@RequestMapping("/categories")
public class CategoryController {

  @Autowired
  private CategoryCRUD categoryCRUD;  


  @RequestMapping(value = "", method = RequestMethod.GET)
  public @ResponseBody Iterable<Category> list() {
    System.out.println("findAll");
    categoryCRUD.findAll().forEach((category) -> {
      System.out.println("category=" + category);
    });    
    return categoryCRUD.findAll();
  }

  private List<Category> findAll() {
    final Iterable<Category> data = categoryCRUD.findAll();
    List<Category> returnList = new ArrayList<>();
    data.forEach(returnList::add);
    return returnList; 
  }


}

【问题讨论】:

    标签: json spring rest spring-boot


    【解决方案1】:

    我找到了一个在已关闭帖子中暗示但不详细的答案。我需要向我的实体添加吸气剂。我希望 JPA/Spring 能够自动添加 getter 和 setter。下面解决了我的问题。

    实体

    //Package and imports omitted
    @Entity
    public class Category {
    
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private Long id;
    
      private Long parentId;
    
      private String title;
    
      private String description;
    
      protected Category() {
      }
    
      public Category(final String title, String description) {
        this(0L, title, description);
      }
    
      public Category(Long parentId, final String title, String description) {
        if (parentId == null) {
          parentId = 0L;
        }
        if (title == null || title.trim().isEmpty()) {
          throw new IllegalArgumentException("Title may not be null or empty.");
        }
        if (description == null) {
          description = "";
        }
        this.parentId = parentId;
        this.title = title;
        this.description = description;
      }
    
      @Override
      public String toString() {
        return "id = " + id + "; parentId=" + parentId + "; title=" + title + "; description=" + description;
      }
    
      public Long getId() {
        return id;
      }
    
      public Long getParentId() {
        return parentId;
      }
    
      public String getTitle() {
        return title;
      }
    
      public String getDescription() {
        return description;
      }
    
    }
    

    欢迎提供更好的答案。

    【讨论】:

    • 如果你想自动生成getter/setter,你可能想看看lombok项目:projectlombok.org
    • 伙伴非常感谢您!像魅力一样工作。刚刚在我的模型中添加了吸气剂,就成功了。太傻了忘记了!
    【解决方案2】:

    在我的例子中,entity 字段的 getter 不是 public

    将它们公开为我解决了这个问题。

    【讨论】:

    • 你拯救了我的一天。我忘了在entity 类中添加getters
    • 是的,做吸气剂并享受。
    【解决方案3】:

    您必须在您的pom.xml 文件中包含lombok 依赖项,并且您必须在您使用的IDE 中设置lombok jar(可以是Intellij 或Eclipse)。如果您想使用注解@Data,它会在Java Bean 或Pojo 类中自动生成getter、setter 和toString() 方法。

    您可以使用来自 lombok 的 @Getter, @Setter, @AllArgsConstructor, @NoArgsConstructor javadoc 注释将为您的字段生成 getter 和 setter 以及构造函数。

    请查看此http://www.baeldung.com/intro-to-project-lombok 了解更多信息。

    谢谢!

    【讨论】:

    • 我是否正确理解 Lombok 不是 Spring 的一部分,而是提供 getter 和 setter 注释的第 3 方库?
    • 是的,它是第三方依赖,主要用于许多项目。如果您使用的是 spring boot,您可以将其包含在 start.spring.io(spring 项目初始化程序)中。是的,它不是 Spring 框架的一部分。
    猜你喜欢
    • 2017-02-16
    • 2019-10-04
    • 1970-01-01
    • 2019-06-06
    • 1970-01-01
    • 2016-09-23
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    相关资源
    最近更新 更多