向eureka rest服务端点发送多部分文件请求时发生异常

时间:2018-11-19 03:14:31

标签: java spring spring-boot microservices netflix-eureka

我正在开发一个文件存储库来存储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空

例外。请帮助我编写端点以处理客户请求。

错误堆栈跟踪

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)

1 个答案:

答案 0 :(得分:1)

如今,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,但适用于您的文件):

  

FileContentStore.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)。您的应用程序代码将保持不变。

HTH