无法将类型 [org.springframework.web.multipart.MultipartFile] 的值转换为所需类型 [java.lang.String]
Posted
技术标签:
【中文标题】无法将类型 [org.springframework.web.multipart.MultipartFile] 的值转换为所需类型 [java.lang.String]【英文标题】:Cannot convert value of type [org.springframework.web.multipart.MultipartFile] to required type [java.lang.String] 【发布时间】:2021-09-02 12:54:42 【问题描述】:没有验证它工作得很好,但后来我尝试验证字段名称。现在,当我尝试将项目添加到我的数据库时(尽管字段名称中的数据正确/不正确),我遇到了一个奇怪的错误,例如图像中的问题。但是我没有编辑这部分代码。没有验证它再次运行良好。
Pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>2.5.1</version>
</dependency>
实体,物品类
@Entity
@Table(name = "items")
public class Item
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private int id;
@NotBlank(message = "Введите наименование")
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@Column(name = "price")
private int price;
@JsonIgnore
@Lob
@Column(name = "image")
private String image;
(...)
主控制器
@PostMapping("/items")
public String add(
@Valid Item item,
@RequestParam String description,
@RequestParam int price,
@RequestParam("image") MultipartFile file,
BindingResult bindingResult,
Model model
) throws IOException
item.setDescription(description);
item.setPrice(price);
if (bindingResult.hasErrors())
Map<String, String> errorsMap = ControllerUtils.getErrors(bindingResult);
model.mergeAttributes(errorsMap);
model.addAttribute("item", item);
else
if (file != null && !file.getOriginalFilename().isEmpty())
byte[] data = file.getBytes();
String imageString = Base64.getEncoder().encodeToString(data);
item.setImage(imageString);
model.addAttribute("item", null);
itemService.saveItem(item);
Iterable<Item> items = itemService.getAllItems();
model.addAttribute("items", items);
return "items";
html 部分(引导程序、FreeMarker)
<form method="post" enctype="multipart/form-data">
<div class="form-group mt-3">
<input type="text" class="form-control $(nameError??)?string('is-invalid', '')"
value="<#if item??>$item.name</#if>" name="name" placeholder="Name">
<#if nameError??>
<div class="invalid-feedback">
$nameError
</div>
</#if>
</div>
<div class="form-group">
<input type="text" class="form-control" name="description" placeholder="Description"/>
</div>
<div class="form-group">
<input type="number" class="form-control" name="description" placeholder="Price"/>
</div>
<div class="form-group">
<div class="custom-file">
<input type="file" name="image" id="customFile">
<label class="custom-file-label" for="customFile">Choose file</label>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Add</button>
</div>
</form>
还有错误
object='item' 的验证失败。错误计数:1 org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 个错误 字段“图像”上的对象“项目”中的字段错误:拒绝值 [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@4c4b8716];代码 [typeMismatch.item.image,typeMismatch.image,typeMismatch.java.lang.String,typeMismatch];参数 [org.springframework.context.support.DefaultMessageSourceResolvable: 代码 [item.image,image];论据 [];默认消息[图像]];默认消息 [无法将类型“org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile”的属性值转换为属性“图像”所需的类型“java.lang.String”;嵌套异常是 java.lang.IllegalStateException:无法将类型“org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile”的值转换为属性“image”所需的类型“java.lang.String”:没有匹配的编辑器或转换找到策略]
这里有什么问题?
【问题讨论】:
提交的 HTML 表单是什么?而且我猜您在任何方法代码运行之前都会收到此错误?听起来好像有一个图像字段试图绑定到 Item 对象中,并且它的值对它无效。 (这可能是一个字符串字段,但作为 MultipartFile 提交?) 是的,我在问题中添加了 html 部分。但是当我删除验证并且根本不编辑字段“图像”时,它可以正常工作。 所以你只添加或删除@Valid
,对吗?但它显然试图自动将您的表单图像字段绑定到Item.image
属性。看起来您的方法正在尝试将请求参数绑定到 Item 对象并分别处理请求参数,我认为您不想这样做。
【参考方案1】:
我通过创建新的 formParams(与具有所有验证参数的实体 Items 非常相似)解决了这个问题,并将这个表单作为参数传递给了 post 方法。
@PostMapping("/items/save")
public String add(@AuthenticationPrincipal User user, @Valid ItemInputParams formParams,
BindingResult bindingResult, Model model) throws IOException
if (bindingResult.hasErrors())
Map<String, String> errorsMap =
ControllerUtils.getErrors(bindingResult);
model.mergeAttributes(errorsMap);
model.addAttribute("item", formParams);
return initItems(null, model);
Item item = new Item();
item.setName(formParams.getName());
item.setCategory(formParams.getCategory());
item.setDescription(formParams.getDescription());
item.setPrice(formParams.getPrice());
item.setAuthor(user);
MultipartFile file = formParams.getImage();
if (file != null && !file.getOriginalFilename().isEmpty())
byte[] data = file.getBytes();
String imageString = Base64.getEncoder().encodeToString(data);
item.setImage(imageString);
itemService.saveItem(item);
Iterable<Item> items = itemService.getAllItems();
model.addAttribute("items", items);
return "items";
【讨论】:
以上是关于无法将类型 [org.springframework.web.multipart.MultipartFile] 的值转换为所需类型 [java.lang.String]的主要内容,如果未能解决你的问题,请参考以下文章
@PreAuthorize 不起作用 - 是不是存在无法解析的循环引用?
Spring-boot OAuth2 实现:NoSuchBeanDefinitionException:没有 AuthenticationManager 类型的合格 bean