我首先要说的是我对Spring的了解非常有限。但是,我已经能够解决过去遇到过的问题。我最新的问题对我来说没有多大意义。
所以我得到的是一个表格,它取得了在拍卖会上出售的物品的属性。此表单有一个可选字段,可以上传正在销售的商品的图片。图像上传按原样工作。我注意到我的表单实际上没有显示验证期间给出的错误,所以我开始查看可能导致错误的原因。如果我从方法签名中删除MultipartFile,则Web将正确显示表单验证错误(如果存在)。但是,现在我没有我需要的图像。
另一方面,如果我将Required = false属性添加到MultipartFile上的RequestParam,我的问题仍然存在,当表单不符合验证集时,我遇到了following。
如果该项有效或显示验证错误,该方法的Java端应该保存该项:
@RequestMapping(method = RequestMethod.POST)
public ModelAndView save(@Valid Item item, @RequestParam(name = "itemImage", required = false) MultipartFile file,
BindingResult result, RedirectAttributes redirect) {
if (result.hasErrors()) {
return new ModelAndView("item/save", "formErrors", result.getAllErrors());
}
boolean isCreate = (null == item.getId());
if (file != null && !file.isEmpty()) {
if (isCreate) {
item = itemService.save(item);
}
Path directory = Paths.get(itemImageDir + "/" + item.getAuction().getId() + "/" + item.getId());
if (!Files.exists(directory)) {
try {
Files.createDirectories(directory);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
Files.copy(file.getInputStream(), Paths.get(directory.toString(), file.getOriginalFilename()),
StandardCopyOption.REPLACE_EXISTING);
item.setImageUrl(String.format("/items/image/%s/%s/%s", item.getAuction().getId(), item.getId(), file
.getOriginalFilename()));
itemService.save(item);
} catch (IOException | RuntimeException e) {
result.addError(new ObjectError("imageUrl", "Failed to upload " + file.getOriginalFilename() + " => "
+ e.getMessage()));
return new ModelAndView("item/save", "formErrors", result.getAllErrors());
}
} else {
itemService.save(item);
}
String message = "Successfully created a new item.";
if (!isCreate)
message = "Item has been successfully updated.";
redirect.addFlashAttribute("globalMessage", message);
return new ModelAndView("redirect:/auctions/{item.auction.id}", "item.auction.id", item.getAuction().getId());
}
此页面的视图,没有任何额外的绒毛,看起来如此:
<form id="auctionForm" class="col-xs-12" th:action="@{/items/(item)}" th:object="${item}"
action="#" method="post" enctype="multipart/form-data">
<div th:class="'form-group row'">
<label for="itemImage" class="control-label col-sm-2"> Image Upload: </label>
<div class="col-sm-4">
<input id="itemImage" type="file" name="itemImage"/>
</div>
</div>
</form>
问题的额外上下文:如果我删除了@Valid注释,则该方法将被调用,并且在表单无效时不会失败。但是,当我有@Valid时,控制器方法甚至没有命中。有没有办法可以检查它是否失败,如果它没有到达控制器?我将这个控制器与所有其他控制器进行了比较,它似乎遵循相同的模式。
如果有人有任何建议,我会非常感激。我真的不知道自己错过了什么,所以欢迎任何建议。
答案 0 :(得分:0)
添加控制器方法sigMultipartHttpServletRequest mrequest并检查一次
答案 1 :(得分:0)
好吧,所以我弄明白我错过了什么。作为Spring的新手,我没有意识到参数顺序可能很重要。显然BindingResult必须立即遵循您要验证的参数。所以,我将方法签名更改为以下内容,现在所有方法都按预期工作:
public ModelAndView save(@Valid Item item, BindingResult result, @RequestParam(name = "itemImage", required = false) MultipartFile file,
RedirectAttributes redirect) {