简体   繁体   English

使用springboot上传图片到数据库,jpa,thymeleaf

[英]uploading a image to the database using springboot , jpa ,thymeleaf

I am developing a simple app that use spring boot and jpa and thymeleaf, i need to upload the image to my database but when i click on submit on my page fields get inserted in database except image field.我正在开发一个使用 spring 启动和 jpa 和 thymeleaf 的简单应用程序,我需要将图像上传到我的数据库,但是当我点击我的页面字段上的提交时,我需要将图像上传到我的数据库中。 i read the different posts on the website but none of them was really close to my problem and i have no idea why it does not insert the file into the database.我阅读了网站上的不同帖子,但没有一个真正接近我的问题,我不知道为什么它不将文件插入数据库。 i have to say the image field located in recipe entity我不得不说位于配方实体中的图像字段

controller controller

@Controller
@RequestMapping("/recipe")
public class RecipeController {
    RecipeRepository recipeRepository;
   IngredientRepository ingredientRepository;
    public RecipeController(RecipeRepository recipeRepository, IngredientRepository ingredientRepository) {
        this.recipeRepository = recipeRepository; 
        this.ingredientRepository = ingredientRepository; //// this is other repo which cause no problem
    }
    @GetMapping("/insert_recipe")
    public String insetRecipe(Model model){
        model.addAttribute("addRecipe",new Recipe());
        model.addAttribute("addingredient",new Ingredient()); // this is other entity which cause no problem
      return   "insert_recipe";
    }
    @PostMapping("/postrecipe")
    public String postRecipe(@ModelAttribute("addRecipe")@Valid Recipe recipe, BindingResult result, Model model, @ModelAttribute("addingredient") Ingredient ingredient)  {
        recipeRepository.save(recipe);
        long id=recipe.getId();
        Recipe u=recipeRepository.findById(id);
        //model.addAttribute("addingredient",recipe);
        ingredient.setRecipe(u);
        ingredientRepository.save(ingredient);
        return "redirect:/recipe/insert_recipe";
    }
}

view page查看页面

<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form th:action="@{/recipe/postrecipe}" th:object="${addRecipe}"  enctype="multipart/form-data" method="post"  >
des:    <input type="text" name="descriptiob"/>
    serving:    <input type="text" name="servings"/>
   for ingredient description <input type="text" name="description" th:object="${addingredient}">
    upload picture <input type="file" th:name="image">

    <input type="submit" value="submit">
</form>
<br/><br/>

</body>
</html>

repo回购

public interface RecipeRepository extends CrudRepository<Recipe,Long> {
    Recipe findById(long is);


}

entity实体

@Entity
public class Recipe {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String descriptiob;
    @Lob
    private Byte[] image;
    private Integer servings;
    //setter and getter method also are in this class

error错误

Field error in object 'addRecipe' on field 'image': rejected value [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@12c96ba6]; codes [typeMismatch.addRecipe.image,typeMismatch.image,typeMismatch.[Ljava.lang.Byte;,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [addRecipe.image,image]; arguments []; default message [image]]; default message [Failed to convert property value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.lang.Byte[]' for property 'image'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.lang.Byte' for property 'image[0]': PropertyEditor [org.springframework.beans.propertyeditors.CustomNumberEditor] returned inappropriate value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile']]

在此处输入图像描述

GitHub link GitHub链接

Let's have a look at the thymeleaf fragment我们来看看 thymeleaf 片段

upload picture <input type="file" th:name="image">

and the error message we get:以及我们得到的错误信息:

Field error in object 'addRecipe' on field 'image': (...)
Cannot convert value of type '(...) StandardMultipartHttpServletRequest$StandardMultipartFile'
(...)to required type 'java.lang.Byte' for property 'image[0]': PropertyEditor (...)
upload picture <input type="file" th:name="image">

The name image colides with the Recipe field which has a different type ( Byte[] than the MultipartFile we are trying to pass in the request).名称image与具有不同类型( Byte[]与我们尝试在请求中传递的MultipartFile )的Recipe字段发生冲突。

One way to do it may be:一种方法可能是:

Step I. Change the th:name="image" to something else (that does not collide with the field names), eg th:name="imagefile"步骤 I. 将th:name="image"更改为其他内容(不与字段名称冲突),例如th:name="imagefile"

upload picture <input type="file" th:name="imagefile">

Step II.第二步。 Change the @RequestParam name to imagefile and convert the MultipartFile to the Byte[] before saving it.@RequestParam名称更改为imagefile并在保存之前将MultipartFile转换为Byte[]

    @PostMapping("/postrecipe")
    public String postRecipe(@ModelAttribute("addRecipe") Recipe recipe,
                             Model model,
                             @ModelAttribute("addingredient")@Valid Ingredient ingredient,
                             BindingResult bindingResult,
                             @RequestParam("imagefile") MultipartFile file, // changed from 'image'
                             @RequestParam("unitid") long id) throws IOException {
      long myid=id;
        recipeRepository.save(recipe);
        long ids=recipe.getId();
        Recipe u=recipeRepository.findById(ids);
        model.addAttribute("addingredient",recipe);
       UnitOfMeasure ob=unitOfMeasureRepository.findById(myid);

       Byte[] byteObjects = convertToBytes(file); // we have to convert it to Byte[] array
       u.setImage(byteObjects);
        recipeRepository.save(u); // TODO refactor - save once

        ingredient.setRecipe(u);
        ingredient.setUnitOfMeasure(ob);
        ingredientRepository.save(ingredient);
        return "redirect:/recipe/insert_recipe";
    }

    private Byte[] convertToBytes(MultipartFile file) throws IOException {
        Byte[] byteObjects = new Byte[file.getBytes().length];
        int i = 0;
        for (byte b : file.getBytes()) {
            byteObjects[i++] = b;
        }
        return byteObjects;
    }

Additional remarks:补充说明:

  • Have a look at how Sfg handles the image upload and the displaying of it in the tutorial repository看看 Sfg 如何处理图像上传以及在教程存储库中的显示
  • It would be better to move the MultiPartFile to Byte[] conversion to the separate service (see the Sfg's repo / tutorial)最好将MultiPartFile转换为Byte[]转换为单独的服务(请参阅 Sfg 的 repo/教程)

Edit:编辑:

Answering the question from the comment: I do not use xampp.从评论中回答问题:我不使用 xampp。 The .bin extension suggests it is a binary file (makes sense as the image file is stored as the byte array). .bin扩展名表明它是一个二进制文件(因为图像文件存储为字节数组,所以很有意义)。

Below is the snippet which should let you display the image in the browser instead.下面是应该让您在浏览器中显示图像的片段。

IOUtils is from ( import org.apache.tomcat.util.http.fileupload.IOUtils; ) IOUtils来自 ( import org.apache.tomcat.util.http.fileupload.IOUtils; )

@GetMapping("{id}/recipeimage")
public void renderImageFromDb(@PathVariable Long id, HttpServletResponse response) throws IOException {
    Recipe recipe = recipeRepository.findById(id).get();
    byte[] byteArray = new byte[recipe.getImage().length];

    int i = 0;
    for (Byte wrappedByte: recipe.getImage()) {
        byteArray[i++] = wrappedByte; // auto unboxing
    }

    response.setContentType("image/jpeg");
    InputStream is = new ByteArrayInputStream(byteArray);
    IOUtils.copy(is, response.getOutputStream());
}

If you know the id of the recipe, just type localhost:8080/recipe/<recipe id>/recipeimage如果您知道配方的 ID,只需键入localhost:8080/recipe/<recipe id>/recipeimage

Concerning your problem that the input is not bound to the ModelAttribute:关于输入未绑定到 ModelAttribute 的问题:

change th:name to name on your input field.在您的输入字段中将 th:name 更改为 name。

Concerning your type error :关于您的类型错误

Maybe this could help you: Upload files to the @ModelAttribute using Thymeleaf也许这可以帮助您: 使用 Thymeleaf 将文件上传到 @ModelAttribute

You need to use the correct type which is MultipartFile for your image.您需要为图像使用正确的类型,即 MultipartFile。 Consider using another class called eg RecipeDto on your Controllers method signature.考虑在控制器方法签名上使用另一个 class,例如 RecipeDto。 Map this to your Recipe Entity so you can somehow convert the MultipartFile to a Byte array manually. Map 将此转换为您的配方实体,以便您可以以某种方式手动将 MultipartFile 转换为 Byte 数组。

edit: org.springframework.web.multipart.MultipartFile#getBytes might do this for you编辑:org.springframework.web.multipart.MultipartFile#getBytes 可能会为你做这个


Concerning DTO: What are the DAO, DTO and Service layers in Spring Framework?关于 DTO: Spring 框架中的 DAO、DTO 和 Service 层是什么?

https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 图像未在 html thymeleaf springboot 中显示 - image is not showing in html thymeleaf springboot 使用AJAX将图像上传到数据库不会作为blob上传 - Uploading image to database using AJAX is not uploading as blob 在SpringBoot中使用Thymeleaf的下拉列表 - Dropdown list using Thymeleaf in SpringBoot 数据库数据未在视图中使用 spring 数据 JPA 和 springboot 访问 - Database data not accessing in views using spring data JPA with springboot 无法在SpringBoot应用程序中使用JPA在数据库中保存数据 - Unable to save data in database using JPA in SpringBoot application Springboot + thymeleaf在html表中显示数据库内容 - Springboot + thymeleaf displaying database contents in html table 为什么我的数据库 (mysql) 中的信息没有显示在我的 html 模板上? 这是一个使用 thymeleaf 的 springboot 应用程序 - Why is the information from my database (mysql) not showing on my html template? This is a springboot application using thymeleaf 使用JPA将对象上传到数据库时获取NULL指针异常 - Getting NULL pointer exception while uploading object to database using JPA 如何使用 Springboot thymeleaf 添加两个数字 - How to Add two Number using Springboot thymeleaf 使用 thymeleaf 和 springboot MVC 访问多个 bean - Access Multiple beans using thymeleaf and springboot MVC
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM