将图片存储在H2数据库spring boot thymleaf中

美好的一天。 我想将图像存储在h2数据库中,然后在html页面中检索并显示相同的图像。 我正在使用spring boot和文件上传方法,但是我在绑定结果中遇到错误

这是页面/类:

Category.java

package com.vishal.project.entities; @Entity @Table(name="category") public class Category implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy= GenerationType.IDENTITY) @Column(name="ID") private Long id; @Size(min=1, max=90) @Column(name="CATEGORY_NAME") private String CategoryName; @Lob @Column(name="CATEGORY_PHOTO") private byte[] CategoryPhoto; public Category(Long id, @Size(min = 1, max = 90) String categoryName, byte[] categoryPhoto) { super(); this.id = id; CategoryName = categoryName; CategoryPhoto = categoryPhoto; } public byte[] getCategoryPhoto() { return CategoryPhoto; } public void setCategoryPhoto(byte[] categoryPhoto) { CategoryPhoto = categoryPhoto; } public Category() {} @OneToMany(mappedBy = "category", cascade=CascadeType.ALL, orphanRemoval=true) private Set Books = new HashSet(); public Set getBooks() { return Books; } public void setBooks(Set books) { Books = books; } public Long getId() { return id; } public void setCategoryID(Long id) { this.id = id; } public String getCategoryName() { return CategoryName; } public void setCategoryName(String categoryName) { CategoryName = categoryName; } @Override public String toString() { return "Category ID:" + id + "Category Name:"+ CategoryName; } } 

Categorycontroller.java

 package com.vishal.project.web; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import com.vishal.project.entities.Category; import com.vishal.project.services.CategoryService; import com.vishal.project.util.Message; @Controller @RequestMapping(value="/categories") public class CategoryController { private final Logger logger = LoggerFactory.getLogger(BookController.class); @Autowired private MessageSource messageSource; @Autowired private CategoryService categoryService; @GetMapping public String list(Model uiModel) { logger.info("Listing categories:"); List categories = categoryService.findALL(); uiModel.addAttribute("categories", categories); logger.info("No. of categories: " + categories.size()); return "categories"; } @GetMapping(value = "/{id}" , consumes="Multipart/formdata") public String show(@PathVariable Long id, Model model) { Category category = categoryService.findbyID(id); model.addAttribute("category", category); return "showCategory"; } @GetMapping(value = "/edit/{id}") public String updateForm(@PathVariable Long id, Model model) { model.addAttribute("category", categoryService.findbyID(id)); return "updateCategory"; } @GetMapping(value = "/new") public String create(Model uiModel) { logger.info("creating Category ..."); Category category = new Category(); uiModel.addAttribute("category", category); return "updateCategory"; } @PostMapping(value = "/upload") public String saveCategory(@Valid @ModelAttribute("category") Category category, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, RedirectAttributes redirectAttributes, Locale locale, @RequestParam(value="file", required=true) MultipartFile file) { logger.info("Creating Category...."); logger.info("Category ID" + category.getId()); logger.info("Category ID" + category.getCategoryName()); logger.info("Category ID" + category.getCategoryPhoto()); if(bindingResult.hasErrors()) { logger.info("Error:", bindingResult.getAllErrors()); logger.debug("field Error:", bindingResult.getFieldError()); uiModel.addAttribute("message", new Message("error", messageSource.getMessage("category_save_fail", new Object[] {}, locale))); uiModel.addAttribute("category", category); return "updateCategory"; } uiModel.asMap().clear(); redirectAttributes.addFlashAttribute("message", new Message("success", messageSource.getMessage("Category_save_success", new Object[] {}, locale))); //process upload file logger.info("File Name :", file.getName() ); logger.info("File Size :", file.getSize() ); logger.info("File content type :", file.getContentType() ); if(file != null) { byte[] filecontent = null; try { InputStream inputStream = file.getInputStream(); if(inputStream == null) logger.debug("file InputStream is null"); filecontent = IOUtils.toByteArray(inputStream); category.setCategoryPhoto(filecontent); }catch(IOException ex) { logger.error("Error Saving uploaded file"); } category.setCategoryPhoto(filecontent); } categoryService.save(category); return "redirect:/categories/" + category.getId().toString(); } 

}

类别图像

categoryShow.page

  
Header

Category Details

CatName

categoryUpdate页面(创建或更新包含详细信息和图像的类别)

 

Category Details

© 2017 Iuliana Cosmina & Apress

错误:我在CategoryController.saveCategory()方法的bindingResult中获取。

当我调试代码时,我收到错误。 这是一张图片来展示:

在此处输入图像描述

我很难使用thymleaf在CategoryShow页面上显示图像。 任何帮助,将不胜感激。

更新:任何人都可以告诉我这个错误意味着什么,请:

 Failed to convert property value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'byte[]' for property 'CategoryPhoto'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type 'org.springframework.web.multipart.support. StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'byte' for property 'CategoryPhoto[0]': PropertyEditor [org.springframework.beans.propertyeditors.CustomNumberEditor] returned inappropriate value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' 

**最终更新:我收到此错误:**所需的请求部分’文件’不存在

你总能做的是比较一个工作文件上传示例和你的。

另一个有助于比较您的输入名称与控制器的方法期望您的文件的名称。

如果您发布的代码仍然相关,您可以在模板中找到文件输入名称“Fileimport”,但在控制器中您需要文件(@RequestParam(value =“file”,required = false))。

其他可以帮助您调试的东西:

  • 使用浏览器的开发人员工具,查看您通过网络发送的内容
  • 记录服务器端的传入请求 (以这种方式,或者对你来说太复杂了,你可以简单地遍历参数名称并记录它们(如果可能的话,也可以记录它们的值)

如果这对你没有帮助,请更新post:更新代码(模板+控制器,如果更改)并使用更好的堆栈跟踪:更好我的意思是你不应该只显示堆栈跟踪的最后N行,但是至少到执行通过你的代码的第一行(换句话说,类名从你的包开始),如果第一个引起或第二个(如果有意义的话)就更好了。

嗨,您的Thymeleaf表单解析如下,如果存在th:field属性,则删除name属性

 

即使你在文件输入中提到name =“file”,它也清楚地说明了你得到的错误,因为在名称标签之后提到了th:field =“* {CategoryPhoto}”,它被解析为name = categoryPhoto。

使用th:value =“$ {product.name}”th:name =“name”th:id =“name”而不是th:field它会更灵活

Spring将上传的文件转换为MultipartFile对象,因此您无法将其直接映射到字节数组。

您可以使用MultipartFile#getBytes()从MultipartFile获取字节数组。

在您的情况下,您可以使用中间对象(如CategoryForm ),其中字段CategoryPhoto将是MultipartFile类型。 然后,在控制器中,使用上面显示的方法将其映射到已有的Category对象。

问题得到解决只要告诉你我在我的案例中做了什么:

1)如果要在页面中上传一个文件,则在控制器方法中使用零件文件作为后映射的参数

2)对于我的第二个问题,使用百日咳的图像不是在html页面中渲染,因为我使用byte []来保存在我的数据库中。 所以它没有得到百里香的解决。 所以我使用Apache commons二进制编解码器Base64(可以添加为Gradle或Maven依赖项)将我的byte []图像转换为Base64字符串,以便它可以通过thymleaf解析。 喜欢这个:

  Category category = categoryService.findbyID(id); byte[] image = category.getCategoryPhoto(); String CatImage = Base64.encodeBase64String(image); 

然后是HTML

  

希望这有助于某人! 谢谢。