I am developing a file repository to store the pdf files. I am using eureka + spring boot which is in producer and consumer architecture. The client is having
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;
}
and the rest end point is having
@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;
}
when I am uploading file I am getting
org.springframework.web.client.HttpClientErrorException$BadRequest: 400 null
exception. Please help me on writing the end point to handle the client request.
Error Stack trace
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)
Now-a-days there are projects like Spring Content provide a very similar programming model for unstructured data (i.e. files, images, videos, etc) as Spring Data does for structured data. Plus it allows you to associate those files with your Entities.
So (assuming you are using Spring Boot) you would add the following dependencies:
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>
Add the following attributes to your File entity so that content can be associated with it.
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;
...
}
Create a ContentStore
(the equivalent of your FileRepository but for your files):
FileContentStore.java
@StoreRestResource(path="fileContents")
public interface FileContentStore extends ContentStore<File, UUID> {
}
When you run your application Spring Content will see the FileContentStore
interface and the spring-content-fs
dependency and inject a Filesystem implementation of this interface for you. It will also see the spring-content-rest
dependency and add an @Controller implementation that forwards GET, PUT, POST and DELETE REST requests onto FileContentStore
as well. This saves you from having to write any of the controller code you have above. REST endpoints will be available at /fileContents
so...
curl -X POST -F "image=@/path/to/local/file.pdf" /fileContents/{fileId}
will upload file.pdf and associate it with your file entity. And:
curl /fileContents/{fileId}
will fetch it again.
This programming model also creates an abstraction over the file storage implementation allowing you to choose any type of storage that Spring Content supports (currently, this is Filesystem, S3, JPA BLOBs, Mongo's Gridfs and Google Storage). Your application code will stay the same regardless.
HTH