因此,我看到了在MultiPartFile
中而不是@RequestParam
中传递@RequestBody
类型的示例。这似乎是人们建议使用@RestController
这样的文件内容的一种非常常见的方式
public ResponseEntity<String> submitFile(@RequestParam(value="file") MultipartFile file)
我想知道如何通过URL传递文件数据是一种好习惯。为什么不通过@RequestBody
传递它呢?
所以我将上面的代码更改为这样的
public ResponseEntity<String> submitFile(@RequestBody MyCustomObj myObj)
myCustomObj
是一种pojo,只有一个名为MultipartFile
类型的文件的字段
问题是我只有招摇和邮递员来测试它,并且当我使用@RequestBody
方法时,没有一个像在传递{{1 }}在MultipartFile
中。
有人可以进一步说明这一点,并告诉我正确的方法吗?
答案 0 :(得分:0)
@RequestParam映射到多部分请求中的查询参数,表单数据和零件,而不仅仅是官方文档中提到的查询参数。 https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html
不应将文件作为请求主体(以JSON序列化)发送。 相反,您应该使用内容类型“ multipart / form-data”进行文件上传(如下面的HTML 4规范所述),在这种情况下,@ RequestParam将是要使用的适当注释 https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
答案 1 :(得分:0)
作为替代方案,根据您的评论,我建议您看一下名为Spring Content的社区项目。这提供了存储上的资源抽象,从而为您的内容的存储位置提供了灵活性,并且为您注入了服务和控制器实现,因此您无需自己实现。另外,正如您提到的那样,它很重要,Spring Content允许您也将上传的内容与Spring Data实体相关联。
将其添加到项目中将如下所示:
pom.xml(假设还提供Maven。也可以使用Spring Boot启动器)
<!-- Java API -->
<!-- just change this depdendency if you want to store somewhere else -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-fs</artifactId>
<version>0.8.0</version>
</dependency>
<!-- REST API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest</artifactId>
<version>0.8.0</version>
</dependency>
StoreConfig.java
@Configuration
@EnableFilesystemStores
@Import(RestConfiguration.class)
public class StoreConfig {
@Bean
FileSystemResourceLoader fileSystemResourceLoader() throws IOException {
return new FileSystemResourceLoader(new File("/path/to/uploaded/files").getAbsolutePath());
}
}
FileStore.java
@StoreRestResource(path="files")
public interface FileStore extends Store<String> {
}
就是这样。 FileStore本质上是一个通用的Spring ResourceLoader。 spring-content-fs
依赖性将导致Spring Content注入基于文件系统的实现。如果spring-content-rest
将HTTP请求转发到@Controller
服务的方法上,则FileStore
依赖性将导致Spring Content也注入一个实现。
因此,您现在在/files
处可以使用基于REST的全功能(POST,PUT,GET,DELETE)文件服务,该服务将使用您的FileStore
来检索(和存储){{ 1}}。
所以:
/path/to/uploaded/files
将上传curl --upload-file some-image.jpg /files/some-image.jpg
并将其存储在服务器上的some-image.jpg
中。
并且:
/path/to/uploaded/files
将再次检索它。
HTH
在有用的情况下,注入的控制器也支持视频流。
稍后/如果要将内容与Spring Data实体关联时,只需将FileStore扩展为curl /files/some-image.jpg
而不是ContentStore
,然后将其键入Spring与您关联的数据实体,并将Spring Content批注添加到您的实体,如下所示:
Store
就是这样。如您所料,REST端点会发生变化,因此您现在可以使用与Spring Data实体相同的URI空间来寻址内容。所以:
//@StoreRestResource(path="files") <-- no longer required
public interface FileStore extends ContentStore<YourEntity, String> {
}
@Entity
public class YourEntity {
@Id
...
@ContentId
private String contentId;
@ContentLength
private String contentLen;
@MimeType
private String contentType;
}
将上传curl --upload-file some-image.jpg /yourEntities/{yourEntityId}
,将其存储在服务器上的some-image.jpg
中,并将其与实体/path/to/uploaded/files
关联。
并且:
yourEntityId
将再次检索它。
可以使用常规的curl /yourEntities/{yourEntityId}
和@OneToOne
关联多个内容,并以一种(希望的)直观的方式将其反映在URI中。
HTH