[英]uploading a image to the database using springboot , jpa ,thymeleaf
我正在开发一个使用 spring 启动和 jpa 和 thymeleaf 的简单应用程序,我需要将图像上传到我的数据库,但是当我点击我的页面字段上的提交时,我需要将图像上传到我的数据库中。 我阅读了网站上的不同帖子,但没有一个真正接近我的问题,我不知道为什么它不将文件插入数据库。 我不得不说位于配方实体中的图像字段
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";
}
}
查看页面
<!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']]
我们来看看 thymeleaf 片段
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
与具有不同类型( Byte[]
与我们尝试在请求中传递的MultipartFile
)的Recipe
字段发生冲突。
一种方法可能是:
步骤 I. 将th:name="image"
更改为其他内容(不与字段名称冲突),例如th:name="imagefile"
upload picture <input type="file" th:name="imagefile">
第二步。 将@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;
}
补充说明:
MultiPartFile
转换为Byte[]
转换为单独的服务(请参阅 Sfg 的 repo/教程)编辑:
从评论中回答问题:我不使用 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
关于输入未绑定到 ModelAttribute 的问题:
在您的输入字段中将 th:name 更改为 name。
关于您的类型错误:
也许这可以帮助您: 使用 Thymeleaf 将文件上传到 @ModelAttribute
您需要为图像使用正确的类型,即 MultipartFile。 考虑在控制器方法签名上使用另一个 class,例如 RecipeDto。 Map 将此转换为您的配方实体,以便您可以以某种方式手动将 MultipartFile 转换为 Byte 数组。
编辑:org.springframework.web.multipart.MultipartFile#getBytes 可能会为你做这个
关于 DTO: Spring 框架中的 DAO、DTO 和 Service 层是什么?
https://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.