【问题标题】:java spring mvc json databind custom json responsesjava spring mvc json数据绑定自定义json响应
【发布时间】:2018-10-07 11:03:33
【问题描述】:

所以我正在做学生测试系统,我的第一个宁静的网络服务,我需要摆脱 JSON 响应中的信息,我不需要发送。我知道我可以使用@JsonIgnore 之类的注释,但它不适合我的情况,因为我需要的数据以不同的方法与同一个对象区分开来。

我知道有映射器和混合器,但我认为它不适合这里,因为我只需要从嵌套对象中排除一个属性,而不是对象中的整个对象。也许有一些简单的解决方案可以针对不同的响应方法进行多种 JSON 自定义。

我正在使用jackson-databindspring data、弹簧MVChibernate

我只需要来自testObjtestName,但我可以排除testOptionsList 吗?不使用@JsonIgnore

或者这可能是我的整体 API 架构缺陷?

控制器:

@RestController
@RequestMapping("/test")
public class TestController {

    @Autowired
    ScoresByTestDao scoreRep;

    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public List<ScoreByTest> getScoresListByUserId(@PathVariable int id) {
        return scoreRep.getTestScoresByUser(id);
    }

存储库:

public interface ScoresByTestDao extends JpaRepository<ScoreByTest, Integer> {

    @Query("select s from ScoreByTest s where s.userObj.id = :userId")
    List<ScoreByTest> getTestScoresByUser(@Param("userId") int userId);
}

请求响应示例:

{  
   id:1,
   score:20.1,
   givenTestObj:{  
      id:1,
      date:1535749200000,
      code:"ABCD123",
      testObj:{  
         id:1,
         testName:"Java I test",
         testQuestionsList:[  
            {  
               id:3,
               question:"What is JRE?",
               rightChoices:1,
               testOptionsList:[  
                  {  
                     id:1,
                     testOption:"JRE is a java based GUI application.",
                     correct:false
                  },
                  {  
                     id:2,
                     testOption:"JRE is an application development framework.",
                     correct:false
                  },
                  {  
                     id:3,
                     testOption:"JRE is an implementation of the Java Virtual Machine which executes Java programs.",
                     correct:true
                  },
                  {  
                     id:4,
                     testOption:"None of the above.",
                     correct:false
                  }
               ]
            },
            {  
               id:4,
               question:"Can we compare int variable with a boolean variable?",
               rightChoices:1,
               testOptionsList:[  
                  {  
                     id:5,
                     testOption:"True",
                     correct:false
                  },
                  {  
                     id:6,
                     testOption:"False",
                     correct:true
                  }
               ]
            },
            {  
               etc...

UI我要填什么表:

+------+------+-------+
|Test  |Date  |Score  | 
+------+------+-------+

ScoreByTest 类:

@Entity
@Table(name = "scores_by_test")
public class ScoreByTest implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;

@Basic(optional = false)
@NotNull
@Column(name = "score")
private float score;

@JoinColumn(name = "id_given_tests", referencedColumnName = "id")
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private GivenTest givenTestObj;

@JoinColumn(name = "id_user", referencedColumnName = "id")
@ManyToOne(optional = false, fetch = FetchType.EAGER)

private User userObj;

public ScoreByTest() {
}

public ScoreByTest(Integer id) {
    this.id = id;
}

public ScoreByTest(Integer id, float score) {
    this.id = id;
    this.score = score;
}

public Integer getId() {
    return id;
}

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

public float getScore() {
    return score;
}

public void setScore(float score) {
    this.score = score;
}

public GivenTest getGivenTestObj() {
    return givenTestObj;
}

public void setGivenTestsObj(GivenTest givenTestsObj) {
    this.givenTestObj = givenTestsObj;
}

public User getUserObj() {
    return userObj;
}

public void setUserObj(User userObj) {
    this.userObj = userObj;
}

GivenTest 类:

@Entity
@Table(name = "given_tests")
public class GivenTest implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;

    @Basic(optional = false)
    @NotNull
    @Column(name = "date")
    @Temporal(TemporalType.DATE)
    private Date date = new Date();

    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 50)
    @Column(name = "code")
    private String code;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "givenTestObj", fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SELECT)
    @JsonIgnore
    private List<ChosenOption> chosenOptionsList;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "givenTestObj", fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SELECT)
    @JsonIgnore
    private List<ScoreByTest> scoresByTestList;

    @JoinColumn(name = "id_test", referencedColumnName = "id")
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    private Test testObj;

    public GivenTest() {
    }

    public GivenTest(Integer id) {
        this.id = id;
    }

    public GivenTest(Integer id, Date date, String code) {
        this.id = id;
        this.date = date;
        this.code = code;
    }

    public Integer getId() {
        return id;
    }

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

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public List<ChosenOption> getChosenOptionsList() {
        return chosenOptionsList;
    }

    public void setChosenOptionsList(List<ChosenOption> chosenOptionsList) {
        this.chosenOptionsList = chosenOptionsList;
    }

    public List<ScoreByTest> getScoresByTestList() {
        return scoresByTestList;
    }

    public void setScoresByTestList(List<ScoreByTest> scoresByTestList) {
        this.scoresByTestList = scoresByTestList;
    }

    public Test getTestObj() {
        return testObj;
    }

    public void setTestObj(Test testObj) {
        this.testObj = testObj;
    }

TestQuestion 类:

@Entity
@Table(name = "test_questions")
public class TestQuestion implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")

    private Integer id;
    @Basic(optional = false)
    @NotNull
    @Lob
    @Size(min = 1, max = 65535)
    @Column(name = "question")

    private String question;
    @Basic(optional = false)
    @NotNull
    @Column(name = "right_choices")
    private short rightChoices;

    @JoinColumn(name = "id_test", referencedColumnName = "id")
    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JsonIgnore
    private Test testObj;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "testQuestionObj", fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SELECT)
    private List<TestOption> testOptionsList;

    public TestQuestion() {
    }

    public TestQuestion(Integer id) {
        this.id = id;
    }

    public TestQuestion(Integer id, String question, short rightChoices) {
        this.id = id;
        this.question = question;
        this.rightChoices = rightChoices;
    }

    public Integer getId() {
        return id;
    }

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

    public String getQuestion() {
        return question;
    }

    public void setQuestion(String question) {
        this.question = question;
    }

    public short getRightChoices() {
        return rightChoices;
    }

    public void setRightChoices(short rightChoices) {
        this.rightChoices = rightChoices;
    }

    public Test getTestObj() {
        return testObj;
    }

    public void setTestObj(Test testObj) {
        this.testObj = testObj;
    }

    public List<TestOption> getTestOptionsList() {
        return testOptionsList;
    }

    public void setTestOptionsList(List<TestOption> testOptionsList) {
        this.testOptionsList = testOptionsList;
    }

TestOption 类:

@Entity
@Table(name = "test_options")
public class TestOption implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;

@Basic(optional = false)
@NotNull
@Column(name = "test_option")
private String testOption;

@Basic(optional = false)
@NotNull
@Column(name = "correct")
private boolean correct;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "testOptionObj", fetch = FetchType.EAGER)
@Fetch(value = FetchMode.SELECT)
@JsonIgnore
private List<ChosenOption> chosenOptionsList;

@JoinColumn(name = "id_test_question", referencedColumnName = "id")
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JsonIgnore
private TestQuestion testQuestionObj;

public TestOption() {
}

public TestOption(Integer id) {
    this.id = id;
}

public TestOption(Integer id, String testOption, boolean correct) {
    this.id = id;
    this.testOption = testOption;
    this.correct = correct;
}

public Integer getId() {
    return id;
}

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

public String getTestOption() {
    return testOption;
}

public void setTestOption(String testOption) {
    this.testOption = testOption;
}

public boolean getCorrect() {
    return correct;
}

public void setCorrect(boolean correct) {
    this.correct = correct;
}

public List<ChosenOption> getChosenOptionsList() {
    return chosenOptionsList;
}

public void setChosenOptionsList(List<ChosenOption> chosenOptionsList) {
    this.chosenOptionsList = chosenOptionsList;
}

public TestQuestion getTestQuestionObj() {
    return testQuestionObj;
}

public void setTestQuestionObj(TestQuestion testQuestionObj) {
    this.testQuestionObj = testQuestionObj;
}

简单概述的 SQL 关系:

https://imgur.com/a/Ok1O5Ky

【问题讨论】:

    标签: java json spring hibernate rest


    【解决方案1】:

    你看过杰克逊的@JsonView吗?我认为它应该非常适合您的场景。 Here is a simple example. 或者,如果您想完全使用 Spring,那么 Spring Data REST 也可能会有所帮助 - an example

    【讨论】:

      【解决方案2】:

      我使用了@JsonView,效果非常好, 在这里找到了一个很好的解释- What is the JSON View class in Jackson and how does it work?

      【讨论】:

      • 避免使用“谢谢”,尤其是作为单独的答案。为此使用 cmets。您能否将此答案转换为评论?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      相关资源
      最近更新 更多