Basically I want to be able to post a form with some fields (JSON) and an attachment (multipart). Following is actually working code, the problem is that I don't like it so it mainly functions because of workarounds.
Angular controller
$http({
method: 'POST',
url: 'rest/store/logo',
headers: {'Content-Type': undefined },
transformRequest: function (data) {
var formData = new FormData();
//need to convert our json object to a string version of json otherwise the browser will do a 'toString()' on the object which will result in the value '[Object object]' on the server.
formData.append("store", angular.toJson(data.store));
formData.append("file", data.file);
return formData;
},
data: { store: $scope.selectedStore, file: $scope.myFile } //not important but $scope.myFile comes from a directive: http://jsfiddle.net/JeJenny/ZG9re/
});
Spring controller
@RequestMapping(value = "/logo", method = RequestMethod.POST)
public @ResponseBody void updateLogo(HttpServletRequest request, @RequestParam(value = "store", required = false) String store, @RequestPart("file") MultipartFile file) {
System.err.println("store: " + store); //the JSON
StoreEditTO storeEditTO = new Gson().fromJson(store, StoreEditTO.class);
System.err.println("storeEditTO: " + storeEditTO);
}
So, although this works there are 2 things that I'm sure could be simplified:
store
to String
or Spring will give me a 'no matching editors or conversion strategy found'. Somehow the request parameter is not recognized as being JSON which I guess is because of setting the content-type to undefined but if I don't I get: 'org.springframework.web.multipart.MultipartException: The current request is not a multipart request'?Posting both separately works just fine by the way. The JSON is converted to the correct type and the file is received. I've already spent hours an getting the mixed mode to work (in a clean way) with no luck so far...
Thanks to above mentioned comment/link I got it working cleanly. I was actually already very close but was missing {type: "application/json"}
.
Complete solution:
@RequestMapping(value = "/logo", method = RequestMethod.POST, consumes = {"multipart/form-data"})
public @ResponseBody void updateLogo(@RequestPart(value = "store") StoreEditTO store, @RequestPart("file") MultipartFile file) {
}
$http({
method: 'POST',
url: 'rest/store/logo',
headers: {'Content-Type': undefined },
transformRequest: function (data) {
var formData = new FormData();
formData.append('store', new Blob([angular.toJson(data.store)], {
type: "application/json"
}));
formData.append("file", data.file);
return formData;
},
data: { store: $scope.selectedStore, file: $scope.myFile }
}).
success(function (data, status, headers, config) {
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With