我在后端使用spring-boot 2.0.4,在前端使用vue 2.5.16 / axios 0.18.0,我希望将PDF文件上传到后端数据库,并从前端检索它们。
最初,我的灵感来自于spring部分的这个例子:https://grokonez . com/frontend/angular/angular-6/angular-6-client-upload-files-download-files-to-MySQL-with-spring boot-restapis
Axios部分的要点如下:https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743
我的代码如下:
> < li>
使用axios在Vue中上传文件(使用" input type="file " "表单输入将this.file变量正确设置为my file,AxiosService()仅用于设置正确的baseUrl并包含带有令牌的授权头):
createRecord() {
let formData = new FormData();
formData.append("file", this.file);
AxiosService()
.post("/commands/material/", formData, {
headers: {
"Content-Type": "multipart/form-data"
}
})
.then(response => {
console.log("File uploaded");
})
.catch(error => {
console.log(error);
});
处理上传的Spring部分如下所示。在我的实体中,内容字段被定义为用@Lob注释的byte[]。
@BasePathAwareController
@RequestMapping("/commands/material")
public class MaterialCommandHandler {
@Autowired
MaterialRepository MaterialRepository;
@RequestMapping(method=POST, path = "/")
public ResponseEntity create(@RequestParam("file") MultipartFile file){
MaterialEntity material = new MaterialEntity();
material.setName(file.getOriginalFilename());
material.setMimetype(file.getContentType());
try {
material.setContent(file.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
try {
MaterialRepository.save(material);
} catch (Exception e) {
if (e instanceof DataIntegrityViolationException) {
throw new InvalidCommandException("Data is invalid for creation.");
}
throw(e);
}
return ResponseEntity.status(HttpStatus.CREATED).body(material.getId());
}
使用这段代码,条目在数据库中正确创建,mysql中的内容字段的类型为longblob。
>
为返回文件内容而定义的方法:
@RequestMapping(method = GET, path = "/download/{fileId}")
public ResponseEntity<byte[]> getFile(@PathVariable Long fileId) {
Optional<MaterialEntity> fileOptional = materialRepository.findById(fileId);
if(fileOptional.isPresent()){
FrancaisMaterialEntity file = fileOptional.get();
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachement; filename=\"" + file.getName() + "\"");
return ResponseEntity.ok()
.headers(headers)
.body(file.getContent());
}
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
最后,使用公有理从前端发送的 GET 方法:
downloadFile() {
AxiosService()
.get(`/commands/material/download/${this.material.id}`, {
responseType: "blob",
})
.then(response => {
console.log(response);
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", "CalculRanking.pdf");
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
})
.catch(error => {
console.log(error);
this.errorMessage = error.response.data.message;
});
}
尝试下载文件时,导航器中的弹出窗口显示正确,但不幸的是,下载的. pdf文件似乎已损坏,因为Chrome状态:“错误加载PDF文档失败”,我也无法在预览中打开它。
我认为问题来自于在过程中的某个时候对内容的错误解释。我做了很多研究,但我尝试的解决方案都不起作用(我尝试的一些事情:添加值为“application/pdf”的“Accept”头,并在get请求中设置“responseType: arrayBuffer”),所以我决定在这里问这个问题。预先感谢你的帮助。
你为什么不看看Spring的内容呢。它的设计目的正是为了完成您想要做的事情,并将一个或多个内容对象与Spring数据实体关联起来。
要将其添加到您现有的Spring启动项目中,请执行以下操作:
pom.xml
<!-- Java API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-jpa-boot-starter</artifactId>
<version>0.4.0</version>
</dependency>
<!-- REST API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest-boot-starter</artifactId>
<version>0.4.0</version>
</dependency>
MaterialEntity.java
@Entity
public class MaterialEntity {
@Id
@GeneratedValue
private long id;
...other existing fields...
@ContentId
private String contentId;
@ContentLength
private long contentLength = 0L;
@MimeType
private String mimeType = "text/plain";
...
}
物料实体内容商店.java
@StoreRestResource(path="materialEntityContents")
public interface MaterialEntityContentStore extends ContentStore<MaterialEntity, String> {
}
这就是获取RESTendpoint所需要做的一切,它将允许您存储和检索与每个MaterialEntity相关的内容。这实际上的工作原理非常类似于Spring Data。当您的应用程序启动时,Spring Content将看到sping-content-jpa-boot-starter
依赖项,并知道您想将内容存储在数据库中。然后,它将在数据库中创建一个模式来执行此操作,并注入MaterialEntityContentStore
接口的JPA实现。它还将看到sping-content-rest-boot-starter
,并将注入与内容存储接口对话的RESTendpoint。这意味着您不必自己做任何事情。
例如:
卷曲 -X POST /材料实体内容/{材料实体 Id} -F “文件=@/路径/收件人/图像.jpg”
会将图像存储在数据库中,并将其与 ID 为材料实体的材料实体相关联
。
curl /materialEntityContents/{材料实体}
将再次获取它等等...实际上也支持完整的CRUD和视频流。
具体来说,这里有一个(非Spring靴)MySQL示例。
您还可以决定将内容存储在其他地方,比如文件系统上,或者通过将< code > spring-Content-JPA-boot-starter 依赖项替换为适当的Spring内容存储模块,将内容存储在S3。这里是每种储物类型的示例。
不幸的是,前端方面没有任何vuejs示例,但我们确实有一个角度js 1.x示例。这可能对前端有所帮助,因为它们是类似的技术(在我有限的经验中!
你能改变你的方法得到文件
:
@GetMapping("/download/{fileId}")
@CrossOrigin
@ResponseBody
public ResponseEntity<InputStreamResource> getFile(@PathVariable(required = true, value = "fileId") Long fileId,
HttpServletRequest request) throws IOException {
Optional<MaterialEntity> fileOptional = materialRepository.findById(fileId);
if (ensemblesRegles.isPresent()) {
String fileName = "example.xlsx";
MediaType mediaType = MediaType.parseMediaType("application/vnd.ms-excel");
File file = new File(fileName); //the fileUtils is org.apache.commons.io.FileUtils;
FileUtils.writeByteArrayToFile(file, fileOptional.get()); // Hope that your get return a byte[] array
InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
return ResponseEntity.ok()
// Content-Disposition
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + file.getName())
// Content-Type
.contentType(mediaType)
// Contet-Length
.contentLength(file.length()) //
.body(resource);
}
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
我正在努力使用axios将xml文件上载到我的asp。net服务器。我正在使用vue端的以下代码获取一个xml文件,该文件正在工作,然后将其上载到我的服务器: 在asp。net端我得到了这个函数: 上载文件会导致代码415:不支持的媒体类型。 我找到了一些建议将xml格式化程序添加到我的项目中,这不起作用,而且我不想解析xml文件,我只想将文件保存到我的文件系统中。 我尝试将原始文件和解析的文本与
我正试图通过React将文件上载到s3存储桶,我正在与4xx和5xx进行斗争:( 下面是我的代码库: 如果我发了这篇文章,我会得到500英镑,而这个错误是: java.io.IOException:UT000036:解析多部分数据时连接终止 我还注意到documents属性为空: 这是后端的API文档: 谢谢!
对于要添加到formData中的文本值,我使用类Blob,这样文件和文本值都是相同的。 在webservice java中,我有一个作为参数,并且只有文本值,我有我的数据。如果我在axios post请求中添加该文件,则会出现错误500并且服务器没有记录任何事件,我认为它会在与的映射中崩溃。 然后我尝试使用,但问题是一样的。 如果我像预期的那样只使用String作为param,那么在axios p
springboot接收前端上传到后端的文件时,在controller层内大多数使用的是MultipartFile进行接收的,当使用file进行接收时会报错 有大佬知道为啥不能用file接收文件吗?
我试图发送一个csv文件到我的javaSpring启动后端。发送文件的代码如下: 以及从Spring Boot接受我的文件的代码: 然而,这似乎行不通。我一直收到一个错误,说当前请求不是一个多部分请求。有什么想法吗?
我希望能够从开发和生产的前端直接将图像上传到ReactJS公共文件夹。对于生产,我使用带有nodejs后端的heroku应用程序。 从我在网上找到的所有使用ReactJS上传图像的教程中,他们都使用服务器端将图像上传到云,但我想知道是否有可能像Lavarel那样将图像上传到公共文件夹,这样做是否有任何缺点?