I'm trying to upload multiple multipart file using feign client, but I am not being able to do so.
After few research,
File Upload Using Feign - multipart/form-data
File upload spring cloud feign client
Array Multipart[] file upload using Feign client
Client side:
#FeignClient(name = "file-server", configuration = {FileUploadService.MultipartSupportConfig.class})
#RequestMapping
public interface FileUploadService {
#RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = MULTIPART_FORM_DATA_VALUE)
public #ResponseBody
List<FileUploadResponseDTO> handleFileUpload(#RequestPart(name = "file") MultipartFile[] file);
#Configuration
public class MultipartSupportConfig {
#Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
#Bean
#Primary
#Scope("prototype")
public Encoder feignEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
}
Module I'm trying to access:
#PostMapping(value = "/upload", consumes = MULTIPART_FORM_DATA_VALUE)
#ApiOperation(UPLOAD_FILE)
public List<FileUploadResponseDTO> uploadFiles(#RequestPart(name = "file") MultipartFile[] file){
System.out.println("****hello ****");
return fileUploadService.uploadFiles(file);
}
The above works fine for a single Multipart file but it shows following error for multiple files:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.codec.EncodeException: Could not write request: no suitable HttpMessageConverter found for request type [[Lorg.springframework.web.multipart.MultipartFile;] and content type [multipart/form-data]] with root cause
feign.codec.EncodeException: Could not write request: no suitable HttpMessageConverter found for request type [[Lorg.springframework.web.multipart.MultipartFile;] and content type [multipart/form-data]
you should set the encoder during feign configuration:
public class FeignSimpleEncoderConfig {
#Bean
public Encoder encoder() {
return new FormEncoder();
}
}
Related
I've created a Restful service with Spring MVC as shown below. I called it using Postman. I placed a breakpoint on 'return "hello World"'. There's no hit on the breakpoint with the error message "Required request part 'file' is not present".
However, if I comment out the '#RequestParam("file")' annotation, the breakpoint is hit with the parameter "file" being null.
What could have gone wrong? Very puzzled.
#RestController
#RequestMapping("/dp")
public class DpWebService implements IDpWebService {
#Override
#Bean
public MultipartConfigElement multipartConfigElement() {
return new MultipartConfigElement("");
}
#Override
#Bean
public MultipartResolver multipartResolver() {
org.springframework.web.multipart.commons.CommonsMultipartResolver multipartResolver = new org.springframework.web.multipart.commons.CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(1000000);
return multipartResolver;
}
#Override
#RequestMapping(path = "/send", method = RequestMethod.POST, consumes = "multipart/form-data")
public String sendManifest(#RequestParam("file") MultipartFile file) {
return "Hello World";
}
}
Postman
Postman Header
Check your POSTMAN request Configuration. I think you have not changed the input type to File from Text. Uploading images, check the images. Hover the mouse over that area in Postman and select File from the drop-down menu.
Having Beans defined in your RestController is not a good design. Please separate out a Configuration class with #Configuration annotation and define your beans. The reasons being: Single Responsibility Principle - each class should only do about one thing.
https://java-design-patterns.com/principles/#single-responsibility-principle
#RequestParam might not be working for you because of the nature of the data that is contained in the file that you are sending through the request. RequestParam is likely to be used with name-value form fields. For complex data like json/xml it is advisable to use #RequestPart instead.
Instead of the #RequestParam annotation use the #RequestPart annotation.
Annotation that can be used to associate the part of a
"multipart/form-data" request with a method argument.
Try using it like :
#RestController
#RequestMapping("/dp")
public class DpWebService implements IDpWebService {
#Override
#Bean
public MultipartConfigElement multipartConfigElement() {
return new MultipartConfigElement("");
}
#Override
#Bean
public MultipartResolver multipartResolver() {
org.springframework.web.multipart.commons.CommonsMultipartResolver multipartResolver = new org.springframework.web.multipart.commons.CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(1000000);
return multipartResolver;
}
#Override
#RequestMapping(path = "/send", method = RequestMethod.POST, consumes = "multipart/form-data")
public String sendManifest(#RequestPart("file") MultipartFile file) {
return "Hello World";
}
}
Also make sure that the request from the postman is getting triggered correctly :
Remove any un wanted request params from postman.
Make sure that under 'Body' tab the form-data is selected. Also make
sure that when selected the file in the key the name is provided as
'file' and type is also selected as file instead of text.
This is my working example.
#PostMapping("/uploadFile")
public UploadFileResponse uploadFile(#RequestParam("file") MultipartFile file) {
String fileName = fileStorageService.storeFile(file);
String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath().path("/downloadFile/")
.path(fileName).toUriString();
return new UploadFileResponse(fileName, fileDownloadUri, file.getContentType(), file.getSize());
}
application.properties
## MULTIPART (MultipartProperties)
# Enable multipart uploads
spring.servlet.multipart.enabled=true
# Threshold after which files are written to disk.
spring.servlet.multipart.file-size-threshold=2KB
# Max file size.
spring.servlet.multipart.max-file-size=200MB
# Max Request Size
spring.servlet.multipart.max-request-size=215MB
## File Storage Properties
# Please change this to the path where you want the uploaded files to be stored.
file.upload-dir=C://Users//abc//Documents//
I'm trying to send the following request through my Controller
#RequestMapping(value = {"/fileupload"}, method = RequestMethod.POST, consumes = {MediaType.ALL_VALUE)
#ResponseStatus(value = HttpStatus.OK)
#ResponseBody
public Object fileupload(#RequestPart MultipartFile[] file,#RequestPart DTO dto) throws Exception {
}
But I get the following error
CORSFilter HTTP Request: POST
org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/octet-stream' not supported
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:226)
at org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver.resolveArgument(RequestPartMethodArgumentResolver.java:132)
I face the same issue and i resolved this on Angular side using below code. On the server side it is fine, you can even remove consume.ALL
url: 'api/import_bot',
data: {
file: vm.file,
DTO: new Blob([angular.toJson(DTO)], {type : 'application/json'})
}
You have to send file and wrap the DTO as BLOB and set its content-type.
i am trying to call the api through feign client and upload the file along with some string parameter through MultipartFile.
This is my client code:
package com.abc;
import feign.codec.Encoder;
#FeignClient(url = "https://xys.com", name = "uploadfile", configuration = UploadFileFeign.MultipartSupportConfig.class)
public interface UploadFileFeign {
#PostMapping(value = "leaveApplication", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ObjectRestResponse<?> handleFileUpload(#RequestParam(value = "request") String request,
#RequestPart(value = "file") MultipartFile srcFile);
class MultipartSupportConfig {
#Bean
public Encoder feignFormEncoder() {
return new FeignSpringFormEncoder();
}
#Bean
public feign.Logger.Level multipartLoggerLevel() {
return feign.Logger.Level.FULL;
}
}
}
Below is the API code which my client is calling.
#RequestMapping(value="/services/leaveApplication", method=Request.POST, produces = MediaType.MULTIPART_FORM_DATA_VALUE, headers="Accept=application/json")
public ResponseOutput leaveApplication(#RequestParam("request") String request, #RequestParam(value = "file", required=false) MultipartFile srcFile) throws Exception {
}
But i am getting error in response:
403 - Forbidden error.
You do not have permission to access the /services/leaveApplication
Other api's which do not involve file upload are working fine.
Typo here :
Request mapping URL is : /services/leaveApplication
But you are accessing : /service/leaveApplication
Change service to services
I need to consume a OAuth2 Rest service with ClientCredential Grant.
I'm using spring security and spring oauth2.
To get the access token i need to call the token uri passing to it a clientId and a password
Basically i need to send a POST with this body
{"clientId":"demo",
"password": "demo_password"
}
and I should get something like that in the response
{
"expiresIn": 3600,
"accessToken": "EF2I5xhL2GU9pAwK",
"statusCode": 200,
"refreshToken": "72BIcYWYhPjuPDGb"
}
I was trying to configure OAuth2RestTemplate in this way
#Configuration
#EnableOAuth2Client
public class RestTemplateConf {
#Value("${ApiClient}")
private String oAuth2ClientId;
#Value("${ApiSecret}")
private String oAuth2ClientSecret;
#Value("${ApiUrl}")
private String accessTokenUri;
#Bean
public OAuth2RestTemplate oAuthRestTemplate() {
ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
resourceDetails.setClientId(oAuth2ClientId);
resourceDetails.setClientSecret(oAuth2ClientSecret);
resourceDetails.setAccessTokenUri(accessTokenUri);
resourceDetails.setTokenName("accessToken");
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails, new DefaultOAuth2ClientContext());
return restTemplate;
}
}
but i get always
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is error="access_denied", error_description="Error requesting access token."] with root cause
org.springframework.web.client.HttpServerErrorException: 500 Internal Server Error
If i make a POST call to the tokenUri with POSTMAN, for instance, i get the token correctly...
I am using angular2 and spring to upload file but when i used small size of file than i am getting error are:-
Resolved exception caused by Handler execution: org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present
my code are
In angular2 code:-
function uploadRecord()
{
var formData = new FormData();
var record_id = 1234
formData.append("file", $scope.file);
formData.append("record_id",record_id); uploadRecordFile.save(formData, function(result) {
// some code here
}, onParseError);
}
Code in Resources class
#RequestMapping(value = "/uploadRecordFile",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public boolean uploadRecordFile(#RequestParam("file") MultipartFile file,#RequestParam("record_id") Long id)
throws Exception {
return true;
}
Is there any way to upload all size of files or is there any setting for it?
I am using following bean setting in my config:-
#Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver=new CommonsMultipartResolver();
resolver.setDefaultEncoding("utf-8");
return resolver;
}
When i remove above mention settings from config than files were uploading but big size files were not uploading as i need this setting i cannot change it so is there any setting from which i can upload both small and big size file?