使用thymelaf表单时绑定的字段错误并传递给控制器



我正在开发一个带有spring-mvcReddit-clone,它有一个链接和注释实体。

问题是添加了一个新的注释函数。

当我尝试提交表单时,在我的控制器中,bindingResult出现错误。

日志信息显示,字段"link"上的对象"comment"中存在字段错误。该错误是由于type mismatch从字符串到链接造成的。

我不知道String从哪里来,也不知道为什么链接字段没有正确绑定。

当前视图页面的get mapping模型中添加了一个链接和一个与链接关联的空注释

我是初来乍到的春天,正为此而挣扎,我很感激任何帮助。

以下是controllerthymeleaf的代码,以及我的链接和注释实体

@GetMapping("/link/{id}")
public String read(@PathVariable Long id,Model model) {
Optional<Link> optionalLink = linkRepository.findById(id);
if( optionalLink.isPresent() ) {
Link link = optionalLink.get();
Comment comment = new Comment();
comment.setLink(link);
model.addAttribute("comment",comment);
model.addAttribute("link",link);
}
@PostMapping("/link/comments")
public String addComment(Comment comment, BindingResult bindingResult) {
log.info(comment.toString());
if( bindingResult.hasErrors() ) {
log.info(bindingResult.toString());
log.info("Something went wrong.");
} else {
log.info("New Comment Saved!");
commentRepository.save(comment);
}
return "redirect:/link/" + comment.getLink().getId();
}
<form id="frmAddComment" method="POST" th:action="@{/link/comments}" th:object="${comment}">
<input type="hidden" th:field="*{link}"/>
<div class="form-group">
<textarea class="form-control" id="comment" rows="3" th:field="*{body}"></textarea>
</div>
<button type="submit" class="btn btn-primary">Add Comment</button>
</form>
@Entity
@Getter@Setter
@RequiredArgsConstructor
@NoArgsConstructor
public class Comment extends Auditable{
@Id
@GeneratedValue
private long id;
@NonNull
private String body;
@ManyToOne
@NonNull
private Link link;
}
public class Link extends Auditable{
@Id
@GeneratedValue
private long id;
@NonNull @NotEmpty(message = "Please enter a title")
private String title;
@NonNull @URL(message = "Please enter a valid url")
private String url;
// comments
@OneToMany(mappedBy = "link")
private List<Comment> comments = new ArrayList<>();
}

HTML仅适用于字符串。问题是Spring不知道如何从String转换为Link

创建一个专用的表单数据对象并在我们的@GetMapping@PostMapping中使用它更容易。

public class AddCommentToLinkFormData {
private long linkId;
@NotNull
@Size(min=1,max=1000) // Set this to the values you want
private String comment;
// add getters and setters 
}

在您的控制器中:

public class MyController {

@GetMapping("...") // URL that you want to use
public String linkInfo(Model model) {
model.addAttribute("formData", new AddCommentToLinkFormData());
return "..." // name of your Thymeleaf view
}
@PostMapping("/link/comments")
public String addComments(Model model,
@Valid @ModelAttribute("formData") AddCommentToLinkFormData formData,
BindingResult bindingResult) {
if( bindingResult.hasErrors() ) {
return "..." // name of your Thymeleaf view. Use `#fields.hasErrors('comment')` in your HTML if you want to show a message if the comment String is not valid.
} else {
service.addCommentToLink(formData.getLinkId(), formData.getComment());
return "redirect:/link/" + formData.getLinkId();
}
}
}

HTML应该是:

<form id="frmAddComment" method="POST" th:action="@{/link/comments}" th:object="${formData}">
<input type="hidden" th:field="*{linkId}"/>
<div class="form-group">
<textarea class="form-control" id="comment" rows="3" th:field="*{comment}"></textarea>
</div>
<button type="submit" class="btn btn-primary">Add Comment</button>
</form>
your controller should be like this
@PostMapping("/link/comments")
public String add(Model model,
@Valid @ModelAttribute(value = "commentForm") CommentForm commentForm,
BindingResult bindingResult,
RedirectAttributes redirectAttributes) {
if( bindingResult.hasErrors() ) {
//
}else{
//
}
return "redirect:/link/" + comment.getLink().getId();
}

CommentForm.java类应该有一个字符串字段注释和链接类型字段链接。

public class CommentForm {

@NotEmpty
private String comment;
@NotNull
private Link link;
}

在您的HTML访问链接中,类似于隐藏文件中的vlaue

<input type="hidden" th:value="*{link}"/>
or
<input type="hidden" th:value="*{link.?id}"/>

最新更新