无法将类型 [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

零基础搭建SpringBoot框架

ThreadPoolTaskExecutor

SpringBoot idea maven打包war及运行war包

springboot+solr基本使用