首页 > 解决方案 > 尝试上传文件转换类型不匹配时出错

问题描述

我有以下实体。

package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import java.util.Date;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import org.springframework.data.annotation.CreatedDate;

@Entity
@Table(name = "documents")

public class Documents {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

     @Column(name = "date_created", nullable = false, updatable = false)
        @CreatedDate
    private Date date_created;

     @Column(name = "name")
     private String name;

     @ManyToOne(fetch = FetchType.LAZY, optional = false)
        @JoinColumn(name = "type_id", nullable = false)
        @OnDelete(action = OnDeleteAction.CASCADE)
        private Documenttypes typeid;
     @Column(name = "file")
     private String file;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public Date getDate_created() {
        return date_created;
    }
    public void setDate_created(Date date_created) {
        this.date_created = date_created;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Documenttypes getTypeid() {
        return typeid;
    }
    public void setTypeid(Documenttypes typeid) {
        this.typeid = typeid;
    }
    public String getFile() {
        return file;
    }
    public void setFile(String file) {
        this.file = file;
    }


}

称为文件的字段之一是上传文档。控制器功能如下:

 public ModelAndView add(@ModelAttribute("documentsForm") Documents documents,@RequestParam("file") MultipartFile file)
     {
        //upload
         if (file.isEmpty()) {
             return new ModelAndView("redirect:/document/list");
                
            }
           try {
               byte[] bytes = file.getBytes();
               Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
            documents.setFile("test");
               Files.write(path, bytes);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

         //end
         documentsService.addDocument(documents);
         return new ModelAndView("redirect:/document/list");
         
     }

但后来我尝试上传文件并提交一个表单我得到这个异常无法将类型'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile'的属性值转换为所需的类型'java.lang.String'的属性'文件'; 嵌套异常是 java.lang.IllegalStateException:无法转换类型 'org.springframewo 的值

完整的错误是:

2021-10-15 12:44:35.029  WARN 13500 --- [nio-8888-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'documentsForm' on field 'file': rejected value [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@2c2feacc]; codes [typeMismatch.documentsForm.file,typeMismatch.file,typeMismatch.java.lang.String,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [documentsForm.file,file]; arguments []; default message [file]]; default message [Failed to convert property value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.lang.String' for property 'file'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile' to required type 'java.lang.String' for property 'file': no matching editors or conversion strategy found]]

标签: javaspring-bootspring-mvc

解决方案


@ModelAttribute将启用从 HTTP 请求到@ModelAttribute实例的数据绑定。

如果它们的名称匹配,它将尝试将查询参数、表单数据的字段名称和其他(参见this)的值绑定到实例的字段。@ModelAttribute

在您的情况下,由于您的控制器方法有一个名为 file 的查询参数,它会尝试将其值绑定到Documents的 file 字段。由于文件查询参数在MultipartFiletype 中但DocumentsStringtype 中,它需要转换但没有Converter注册这样做。

不确定您是否真的要将 的内容绑定MultipartFileDocuments的文件字段。如果没有,您可以简单地重命名其中一个,使它们不匹配。

否则,您可以实现 aConverter以转换MultipartFileString

 public class MulitpartConverter implements Converter<MultipartFile, String> {

        @Override
        public String convert(MultipartFile source) {
            try {
                return new String(source.getBytes(), StandardCharsets.UTF_8);
            } catch (IOException e) {
                throw new RuntimeException("Fail to convert multipart file to string", e);
            }
        }
    }

并注册它:

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
            @Override
            public void addFormatters(FormatterRegistry registry) {
                registry.addConverter(new MulitpartConverter());
            }
    
    }

推荐阅读