Thymeleaf 迭代对象列表
Thymeleaf iteration over list of objects
我在迭代 Thymeleaf 中的对象列表时遇到问题。
这是我的 HTML:
<input th:each="a,iterStatus : currentQuestion.answers" type="radio" name="answer" th:text="${a.answer}" th:value="${iterStatus.index}"></input>
这是控制器class:
@RequestMapping(value={ "/exam", "/exam/" }, method = RequestMethod.GET)
public String exam(Model model){
if (!sessionPreferences.isExamStarted()){
sessionPreferences.setQuestionList(questionService.list(Questions.findAll().paginate(0, 5).loadWith("answers")));
sessionPreferences.setCurrentQuestion(questionService.uniqueObject(Questions.findAll().withId(1L).loadWith("answers")));
}
model.addAttribute("currentQuestion", sessionPreferences.getCurrentQuestion());
sessionPreferences.setExamStarted(true);
System.out.println("TRUE!");
System.out.println(sessionPreferences.getCurrentQuestion().getAnswers().size());
System.out.println(sessionPreferences.getCurrentQuestion().getAnswers().get(0));
return "exam";
}
这是 SessionPreferences class:
@Component
@Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SessionPreferences implements Serializable {
private static final long serialVersionUID = -3875093750700352970L;
@Setter
private String displayName;
@Setter @Getter
private Question currentQuestion;
@Getter @Setter
private boolean examStarted;
@Getter @Setter
private Map<Question, Integer> selections = new LinkedHashMap<Question, Integer>();
@Getter @Setter
private List<Question> questionList = new ArrayList<Question>(5);
public String getDisplayName() {
if(StringUtils.isBlank(displayName)){
displayName = SecurityUtils.getLoggedUsername();
}
return displayName;
}
}
我们有问题模型 class:
@Entity
@Table(name = "questions")
public class Question extends BaseEntity<Long> {
private static final long serialVersionUID = -7066617446892759711L;
public static final int DESCRIPTION_MAX_LENGTH = 5120;
public static final int OPTIONS_MAX_LENGTH = 4 * 5120;
public Question() {
};
public Question(String questionDescription, List<Answer> answers) {
this.questionDescription = questionDescription;
};
@Id
@GeneratedValue
@Getter
@Setter
private Long id;
@Getter
@Setter
@Column(length = DESCRIPTION_MAX_LENGTH, nullable = false, name = "question_description")
private String questionDescription;
@Getter
@Setter
@OneToMany(mappedBy = "question", targetEntity = Answer.class, cascade = CascadeType.ALL)
private List<Answer> answers = new ArrayList<>();
@Getter
@Setter
@Column(nullable = false, name = "correct_answer_id")
private Answer correctAnswerIndex;
}
答案class:
@Entity
@Table(name="answers")
public class Answer extends BaseEntity<Long>{
private static final long serialVersionUID = -6119650375719671237L;
public Answer(){};
public Answer(String answer){
this.answer = answer;
};
@Id
@GeneratedValue
@Getter @Setter
private Long id;
@Getter @Setter
private String answer;
@ManyToOne
@JoinColumn(name = "question_id", updatable=false)
@Getter @Setter
private Question question;
}
DAO 层和服务层工作正常,因此在使用 Thymeleaf 迭代时访问 Answer 对象中的 String answer 时出现问题。
我有以下错误:
SEVERE: Servlet.service() for servlet [spring] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "a.answer" (exam:99)] with root cause
org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 2): Field or property 'answer' cannot be found on object of type 'java.lang.String'
有什么想法吗???
P.s 三个 syso 结果为:TRUE!, 4, Object..
th:each
属性的语法存在问题,因为 currentQuestion.answers
应该包含在表达式求值 (${...}
) 组中。
正确版本:
<input th:each="a,iterStatus : ${currentQuestion.answers}" type="radio" name="answer" th:text="${a.answer}" th:value="${iterStatus.index}"></input>
我在迭代 Thymeleaf 中的对象列表时遇到问题。 这是我的 HTML:
<input th:each="a,iterStatus : currentQuestion.answers" type="radio" name="answer" th:text="${a.answer}" th:value="${iterStatus.index}"></input>
这是控制器class:
@RequestMapping(value={ "/exam", "/exam/" }, method = RequestMethod.GET)
public String exam(Model model){
if (!sessionPreferences.isExamStarted()){
sessionPreferences.setQuestionList(questionService.list(Questions.findAll().paginate(0, 5).loadWith("answers")));
sessionPreferences.setCurrentQuestion(questionService.uniqueObject(Questions.findAll().withId(1L).loadWith("answers")));
}
model.addAttribute("currentQuestion", sessionPreferences.getCurrentQuestion());
sessionPreferences.setExamStarted(true);
System.out.println("TRUE!");
System.out.println(sessionPreferences.getCurrentQuestion().getAnswers().size());
System.out.println(sessionPreferences.getCurrentQuestion().getAnswers().get(0));
return "exam";
}
这是 SessionPreferences class:
@Component
@Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SessionPreferences implements Serializable {
private static final long serialVersionUID = -3875093750700352970L;
@Setter
private String displayName;
@Setter @Getter
private Question currentQuestion;
@Getter @Setter
private boolean examStarted;
@Getter @Setter
private Map<Question, Integer> selections = new LinkedHashMap<Question, Integer>();
@Getter @Setter
private List<Question> questionList = new ArrayList<Question>(5);
public String getDisplayName() {
if(StringUtils.isBlank(displayName)){
displayName = SecurityUtils.getLoggedUsername();
}
return displayName;
}
}
我们有问题模型 class:
@Entity
@Table(name = "questions")
public class Question extends BaseEntity<Long> {
private static final long serialVersionUID = -7066617446892759711L;
public static final int DESCRIPTION_MAX_LENGTH = 5120;
public static final int OPTIONS_MAX_LENGTH = 4 * 5120;
public Question() {
};
public Question(String questionDescription, List<Answer> answers) {
this.questionDescription = questionDescription;
};
@Id
@GeneratedValue
@Getter
@Setter
private Long id;
@Getter
@Setter
@Column(length = DESCRIPTION_MAX_LENGTH, nullable = false, name = "question_description")
private String questionDescription;
@Getter
@Setter
@OneToMany(mappedBy = "question", targetEntity = Answer.class, cascade = CascadeType.ALL)
private List<Answer> answers = new ArrayList<>();
@Getter
@Setter
@Column(nullable = false, name = "correct_answer_id")
private Answer correctAnswerIndex;
}
答案class:
@Entity
@Table(name="answers")
public class Answer extends BaseEntity<Long>{
private static final long serialVersionUID = -6119650375719671237L;
public Answer(){};
public Answer(String answer){
this.answer = answer;
};
@Id
@GeneratedValue
@Getter @Setter
private Long id;
@Getter @Setter
private String answer;
@ManyToOne
@JoinColumn(name = "question_id", updatable=false)
@Getter @Setter
private Question question;
}
DAO 层和服务层工作正常,因此在使用 Thymeleaf 迭代时访问 Answer 对象中的 String answer 时出现问题。
我有以下错误:
SEVERE: Servlet.service() for servlet [spring] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "a.answer" (exam:99)] with root cause
org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 2): Field or property 'answer' cannot be found on object of type 'java.lang.String'
有什么想法吗???
P.s 三个 syso 结果为:TRUE!, 4, Object..
th:each
属性的语法存在问题,因为 currentQuestion.answers
应该包含在表达式求值 (${...}
) 组中。
正确版本:
<input th:each="a,iterStatus : ${currentQuestion.answers}" type="radio" name="answer" th:text="${a.answer}" th:value="${iterStatus.index}"></input>