java - 向尤里卡休息服务端点发送多部分文件请求的异常
问题描述
我正在开发一个文件存储库来存储 pdf 文件。我正在使用生产者和消费者架构中的 eureka + spring boot。客户有
public boolean uploadBooks(MultipartFile file, String fileLocation, String fileName) {
boolean callResponse = false;
try {
if(!file.isEmpty()) {
ByteArrayResource fileResource = new ByteArrayResource(file.getBytes()) {
public String getFileName() {
return file.getOriginalFilename();
}
};
LinkedMultiValueMap<String, Object> requestMap = new LinkedMultiValueMap<>();
requestMap.add("file", fileResource);
requestMap.add("repoLocation", fileLocation);
requestMap.add("fileId", fileName);
HttpHeaders requestHeader = new HttpHeaders();
requestHeader.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<LinkedMultiValueMap<String, Object>>(
requestMap, requestHeader);
System.err.println(requestEntity.getBody());
System.err.println(uploadBooks);
ResponseEntity<Boolean> response = restTemplate.exchange(uploadBooks,HttpMethod.POST, requestEntity,
Boolean.class);
callResponse = response.getBody();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return callResponse;
}
其余的终点是
@PostMapping("/uploadFile")
public boolean uploadFile(@RequestParam("file") MultipartFile file,
@RequestParam("repoLocation") String repoLocation, @RequestParam("fileId") String fileId) {
boolean process = false;
try {
System.out.println("---->"+fileId);
process = fileServices.saveFile(file, repoLocation, fileId);
} catch (RepoStorageException e) {
e.printStackTrace();
}
if (process) {
return true;
}
return false;
}
当我上传文件时,我得到
org.springframework.web.client.HttpClientErrorException$BadRequest: 400 null
例外。请帮助我编写处理客户端请求的端点。
错误堆栈跟踪
org.springframework.web.client.HttpClientErrorException$BadRequest: 400 null
at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:79)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:97)
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:79)
at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:777)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:669)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:578)
at com.library.remoteservices.repository.LibraryFileRepository.uploadBooks(LibraryFileRepository.java:76)
at com.library.LibraryServiceDiscoveryClient.FileServiceController.uploadBooks(FileServiceController.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:142)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:998)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:901)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:875)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
解决方案
现在,像Spring Content这样的项目为非结构化数据(即文件、图像、视频等)提供了与 Spring Data 为结构化数据提供的非常相似的编程模型。此外,它还允许您将这些文件与您的实体相关联。
因此(假设您使用的是 Spring Boot)您将添加以下依赖项:
pom.xml
<!-- Java API -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-fs-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>
将以下属性添加到您的 File 实体,以便内容可以与之关联。
文件.java
@Entity
public class File {
...existing fields...
@ContentId
private UUID contentId;
@ContentLength
private long contentLength = 0L;
// if you have rest endpoints
@MimeType
private String mimeType;
...
}
创建一个ContentStore
(相当于您的 FileRepository 但用于您的文件):
文件内容存储.java
@StoreRestResource(path="fileContents")
public interface FileContentStore extends ContentStore<File, UUID> {
}
当您运行应用程序时,Spring Content 将看到FileContentStore
接口和spring-content-fs
依赖项,并为您注入该接口的文件系统实现。它还将查看spring-content-rest
依赖关系并添加一个 @Controller 实现,该实现也将 GET、PUT、POST 和 DELETE REST 请求转发到FileContentStore
。这使您不必编写上面的任何控制器代码。REST 端点将在/fileContents
...
curl -X POST -F "image=@/path/to/local/file.pdf" /fileContents/{fileId}
将上传 file.pdf 并将其与您的文件实体相关联。和:
curl /fileContents/{fileId}
将再次获取它。
此编程模型还创建了对文件存储实现的抽象,允许您选择 Spring Content 支持的任何类型的存储(当前是 Filesystem、S3、JPA BLOB、Mongo 的 Gridfs 和 Google Storage)。无论如何,您的应用程序代码将保持不变。
高温高压
推荐阅读
- json - SwiftUI 文本视图:当可选字符串为零时,预期的默认值不起作用
- sql - 我不明白这些查询对我来说是一样的。这些查询有什么区别?
- python - “ImageField”对象没有属性“_committed”
- android - JNI Android qt 问题
- reactjs - 我正在将我的反应与 firebase 联系起来并收到此错误。错误:无效的挂钩调用
- android - 无法将数据形式的数据库分配给 MutableLiveData
- python - python TypeError:'list'和'int'的实例之间不支持'> ='
- ios - 推送到 Testflight 时适用于 iOS 的 Azure DevOps 超时
- java - 为什么我的程序会检查彼此相邻的匹配项而不是一般情况下的匹配项?
- php - PhpSpreadsheet - 使用 --prefer-source 与作曲家一起安装以获取文档和示例,但我没有得到它们