I have the following resource (implemented using Spring 4.05.RELEASE) which accepts a file and a JSON object:
(P.S. activityTemplate is a serializable entity class)<
This took me two days to work for me!
client (angular):
$scope.saveForm = function () {
var formData = new FormData();
var file = $scope.myFile;
var json = $scope.myJson;
formData.append("file", file);
formData.append("ad",JSON.stringify(json));//important: convert to string JSON!
var req = {
url: '/upload',
method: 'POST',
headers: {'Content-Type': undefined},
data: formData,
transformRequest: function (data, headersGetterFunction) {
return data;
}
};
Spring (Boot):
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public @ResponseBody
Advertisement storeAd(@RequestPart("ad") String adString, @RequestPart("file") MultipartFile file) throws IOException {
Advertisement jsonAd = new ObjectMapper().readValue(adString, Advertisement.class);
//do whatever you want with your file and jsonAd
The default content type is 'application/octet-stream'. Since you are uploading jar file and JSON the content type should be set in the @RequestMapping
annotation as follows:
@RequestMapping(value="/create", method=RequestMethod.POST, headers="content-type=application/json,application/java-archive")
this may help you, while receiving MultipartFile you should set request header content-type to "multipart/form-data" , then in your controller use consumes="multipart/form-data" , consumes also used to map our request to our method in controller.
If you want to receive JSON data , better to send request in the form of JSONString , just receive that jsonstring, later convert into json Object format then, use that object for yours operations.
check below code :
@RequestMapping(value="/savingImg", method=RequestMethod.POST,
consumes="multipart/form-data", produces="application/json")
public ResponseEntity<?> savingAppIMgDtlss(
@RequestParam(value="f1", required = false) MultipartFile f1 ,
@RequestParam(value="f2", required = false) MultipartFile f2 ,
@RequestParam(value="f3", required = false) MultipartFile f3 ,
@RequestParam(value="f4", required = false) MultipartFile f4 ,
@RequestParam(value="f5", required = false) MultipartFile f5 ,
@RequestParam(value="f6", required = false) MultipartFile f6 ,
@RequestParam(value="f7", required = false) MultipartFile f7 ,
@RequestParam(value="f8", required = false) MultipartFile f8 ,@RequestParam("data") String jsonString)
throws Exception , ParseException {
try{
JSONObject gstcTranObj = new JSONObject();
//converting JSONString to JSON
net.sf.json.JSONObject jsonDtls = net.sf.json.JSONObject.fromObject(jsonString);
System.out.println("f1::"+f1.getOriginalFilename());
System.out.println("f2::"+f2.getOriginalFilename());
System.out.println("f3::"+f3.getOriginalFilename());
System.out.println("f4::"+f4.getOriginalFilename());
System.out.println("f5::"+f5.getOriginalFilename());
System.out.println("f6::"+f6.getOriginalFilename());
System.out.println("f7::"+f7.getOriginalFilename());
System.out.println("f8::"+f8.getOriginalFilename());
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>("Failed",HttpStatus.NOT_FOUND);
}finally{
}
return new ResponseEntity<>("Success", HttpStatus.OK);
}
}
You can use @RequestPart from org.springframework.web.bind.annotation.RequestPart; It is used as Combining @RequestBody and file upload.
Using @RequestParam like this @RequestParam("file") MultipartFile file you can upload only file and multiple single data (key value ) like
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE })
public void saveFile(
@RequestParam("userid") String userid,
@RequestParam("file") MultipartFile file) {
}
you can post JSON Object data and and File both using @RequestPart like
@RequestMapping(value = "/patientp", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<?> insertPatientInfo(
@RequestPart PatientInfoDTO patientInfoDTO,
@RequestPart("file") MultipartFile file) {
}
You are not limited to using multipart file uploads directly as controller method parameters. Your form objects can contain Part or MultipartFile fields, and Spring knows automatically that it must obtain the values from file parts and converts the values appropriately.
Above method can respond to the previously demonstrated multipart request containing a single file. This works because Spring has a built-in HTTP message converter that recognizes file parts. In addition to the javax.servlet.http.Part type, you can also convert file uploads to org.springframework.web.multipart.MultipartFile. If the file field permits multiple file uploads, as demonstrated in the second multipart request, simply use an array or Collection of Parts or MultipartFiles.
@RequestMapping(value = "/patientp", method = RequestMethod.POST, consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<?> insertPatientInfo(
@RequestPart PatientInfoDTO patientInfoDTO,
@RequestPart("files") List<MultipartFile> files) {
}
Happy To Help...
Exception is thrown because you don't have appropriate HttpMessageConverter, to process multipart/form-data request. Workaround
You have not given the param names to your @RequestParts ?
public @ResponseBody ActivityTemplate createActivityTemplate(
@RequestPart("activityTemplate") ActivityTemplate activityTemplate, @RequestPart("file") MultipartFile jarFile)
{
//process the file and JSON
}
Note: do not forget to include the jackson mapper .jar (maps your Json to ActivityTemplate) file in your classpath.