java - 尝试上传文件转换类型不匹配时出错
问题描述
我有以下实体。
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]]
解决方案
@ModelAttribute
将启用从 HTTP 请求到@ModelAttribute
实例的数据绑定。
如果它们的名称匹配,它将尝试将查询参数、表单数据的字段名称和其他(参见this)的值绑定到实例的字段。@ModelAttribute
在您的情况下,由于您的控制器方法有一个名为 file 的查询参数,它会尝试将其值绑定到Documents
的 file 字段。由于文件查询参数在MultipartFile
type 中但Documents
在String
type 中,它需要转换但没有Converter
注册这样做。
不确定您是否真的要将 的内容绑定MultipartFile
到Documents
的文件字段。如果没有,您可以简单地重命名其中一个,使它们不匹配。
否则,您可以实现 aConverter
以转换MultipartFile
为String
:
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());
}
}
推荐阅读
- docker - 无法从 k8s pod 内部解析 home dns
- node.js - Firefox NodeJS 内容安全策略(“default-src”)错误
- php - 如何处理显示为网页 laravel 的 405 错误
- python - 如何实现扩展欧几里得算法?
- html - 视图函数未返回有效响应。该函数要么返回 None 要么在没有返回语句的情况下结束 flask elasticsearch
- php - 此集合实例上不存在属性 [jenis_penyedia]
- flutter - 如何在颤动中生成带有徽标的二维码
- css - CSS 多列蛇形图案
- jquery - 未捕获的 ReferenceError:$ 未使用 Ruby on Rails 定义
- javascript - 如何在具有多个 y 轴的多折线图上绘制数据点