java—使用springboot、jpa和EleAF将图像上载到数据库

vjrehmav  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(267)

我正在开发一个简单的应用程序,使用spring引导和jpa和thymeleaf,我需要上传图像到我的数据库,但当我在我的页面上点击提交字段被插入数据库除了图像字段。我在网站上读了不同的帖子,但没有一个真正接近我的问题,我也不知道为什么它不把文件插入数据库。我要说的是位于recipe实体中的图像字段
控制器

@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";
    }
}

查看页面

<!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>

回购

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

}

实体

@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

错误

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链接

5lhxktic

5lhxktic1#

关于输入未绑定到modelattribute的问题:
在输入字段中将th:name改为name。
关于您的类型错误:
也许这可以帮助您:使用thymeleaf将文件上传到@modeltattribute
您需要为您的图像使用正确的类型multipartfile。考虑在控制器方法签名上使用另一个名为recipedto的类。将此Map到您的配方实体,以便您可以手动将多部分文件转换为字节数组。
编辑:org.springframework.web.multipart.multipartfile#getbytes可以帮您完成这项工作
关于dto:spring框架中的dao、dto和服务层是什么?
https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application

fsi0uk1n

fsi0uk1n2#

我们来看看胸腺碎片

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

我们得到的错误信息是:

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">

名字 image 科里德斯和 Recipe 具有不同类型的字段( Byte[]MultipartFile 我们正在尝试传递请求)。
一种方法是:
第一步。更改 th:name="image" 其他(与字段名不冲突的),例如。 th:name="imagefile" ```
upload picture

第二步。更改 `@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;
}
附加说明:
看看sfg如何处理图像上传和在教程存储库中的显示
最好是搬家 `MultiPartFile` 至 `Byte[]` 转换为独立服务(参见sfg的回购/教程)
编辑:
回答评论中的问题:我不使用xampp。这个 `.bin` 扩展名表明它是一个二进制文件(因为图像文件存储为字节数组)。
下面是一个片段,您可以在浏览器中显示图像。 `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());

}

如果你知道配方的id,只需键入 `localhost:8080/recipe/<recipe id>/recipeimage` 

相关问题