Итак, я занимаюсь тестированием системы студентов, моим первым полноценным веб-сервисом, и мне нужно избавиться от информации в JSON ответах, которые мне не нужно отправлять.Я знаю, что могу использовать аннотации типа @JsonIgnore
, но в моей ситуации это не подходит, потому что данные, которые мне нужны, отличаются в разных методах от одного и того же объекта.
Я знаю, что существуют картостроители и миксины, но яне думаю, что это подходит здесь, потому что мне нужно исключить только одно свойство из вложенного объекта, а не весь объект в объекте.Возможно, есть какое-то простое решение для нескольких JSON настроек для разных методов ответа.
Я использую jackson-databind
, spring data
, пружину MVC
, а также hibernate
.
Мне нужно просто testName
из testObj
, но можно ли исключить 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...
Какую таблицу я хочу заполнить в пользовательском интерфейсе:
+------+------+-------+
|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