4 回答

TA贡献1946条经验 获得超4个赞
MultipartFile包含一个byte array内容文件。您可以使用 fromgetBytes()方法。
在application.properties添加:
spring.servlet.multipart.enabled=true
或者使用YAML可以添加:
spring:
servlet:
multipart:
enabled: true
并且可以从 MultipartFile 中获取字节数组,例如:
MultipartFile file;
//for your segment file fill from client side(in request)
byte [] content = file.getBytes();

TA贡献1807条经验 获得超9个赞
作为替代方法,我建议您查看社区项目Spring Content。该项目旨在完全解决您的问题,为非结构化数据的存储提供抽象,为您注入服务和控制器实现,这样您就不需要自己实现,并允许您将上传的内容与 Spring Data 实体相关联。
此外,所有 Spring Content 存储模块,包括 JPA,都是基于流的,因此能够处理该byte[]方法无法处理的非常大的文件。
将其添加到您的项目中将如下所示:
pom.xml(假设是 Maven)
<!-- Java API -->
<!-- just change this depdendency if you want to store somewhere else -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-jpa-boot-starter</artifactId>
<version>0.8.0</version>
</dependency>
<!-- REST API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest-boot-starter</artifactId>
<version>0.8.0</version>
</dependency>
定义内容存储(与 Spring Data Repository 的概念相同):
用户内容存储.java
@StoreRestResource(path="photos")
public interface UserPhotoStore extends ContentStore<User, UUID> {
}
将内容与您的User实体关联:
@Entity(name = "users")
public class User {
@Id
@GeneratedValue
private long id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
// Spring Content annotations
@ContentId
private UUID contentId;
@ContentLength
private Long contentLen;
@MimeType
private String mimeType;
就是这样。UserPhotoStore本质上是一个通用的 Spring ResourceLoader 。依赖项将导致 Spring Content 注入该spring-content-jpa-boot-starter 接口的基于 jpa 的实现,并且spring-content-rest-boot-starter依赖项将导致 Spring Content 注入@Controller将 HTTP 请求转发到UserPhotoStore服务方法的实现。
总而言之,您现在将拥有一个功能齐全的(POST、PUT、GET、DELETE)基于 REST 的文件服务/photoso/{userId},它将使用您UserPhotoStore在数据库中存储(和检索)文件并将它们与您的用户实体相关联。
所以:
curl -F ‘file=@/path/to/local/file.jpg’ /photos/{userId}
将上传/path/to/local/file.jpg,将其存储在您的数据库中并将其与用户实体相关联userId。
和:
curl /photos/{userId}
将再次检索它。
内容可以按照文档(关联模式)中描述的各种方式关联。
高温高压

TA贡献1884条经验 获得超4个赞
Spring 不会将字节存储在类本身中,而是强制您从中打开一个流。
文件内容要么存储在内存中,要么临时存储在磁盘上。在任何一种情况下,如果需要,用户负责将文件内容复制到会话级别或持久存储。临时存储将在请求处理结束时被清除。
我通常使用以下代码将中间存储到文件或内存中:
private final Path rootLocation;
try (InputStream inputStream = file.getInputStream()) {
byte[] in = StreamUtils.copyToByteArray(inputStream);
//Files.copy(inputStream, this.rootLocation.resolve(filename),
// StandardCopyOption.REPLACE_EXISTING);
}
当然,您可以使用任何您喜欢的东西来从流中创建 byte[]。如果你在春天,可以推荐 StreamUtils

TA贡献1827条经验 获得超9个赞
我可能弄错了,但我相信 Spring 正在尝试自动映射传递到您的端点的整个“用户”对象并且失败,因为传入的用户对象中没有“照片”字段,或者它是无法将该字段自动转换为字节 []。
为了测试是否是这种情况,您可以执行以下操作之一 1)如果传入的 User 对象没有照片字段,请将其从您的 User 对象中删除 2)如果有并且它正在进来作为 MultipartFile 然后从 byte[] 更改为 multipartfile。
我知道这些都不能帮助您将其输入数据库,但它会帮助您确定这是否真的是您的问题。那么我很乐意提供进一步的帮助。
编辑
好的,我一直在努力让它工作,最后我得到了它!请参阅下面的更改。像这样更改控制器端点
@PostMapping
@ResponseBody
public void postUser(@ModelAttribute User user, @RequestParam("file") MultipartFile file) throws IOException {
user.setPhotoByteArray(file.getBytes());
//Do Service Call here(user)
}
我像这样更新了 User 对象。
@Entity(name = "users")
public class User {
@Id
@GeneratedValue
private long id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
@Column(name = "photo")
private byte[] photoByteArray;
public User(long id, String firstName, String lastName, String email) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
就是这样!我通过邮递员发送带有所有必要字段的表单数据请求来验证这项工作,我还添加了以下几行以将文件保存在本地目录中,以便我可以打开它以确认它正确处理了我传递的图像进入邮递员
FileUtils.writeByteArrayToFile(new File("test.png"), user.getPhotoByteArray());
我还向您的实体添加了一个构造函数,当它从模型属性创建对象时,它将允许它开始为空,我可以稍后设置它。
如果您仍有问题或疑问,请告诉我。
添加回答
举报