Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mixed POST submit from AngularJS to Spring RestController

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:

  1. Angular: not too bad but the code seems to more complicated then it should be
  2. Spring: this is the most disturbing; the file is OK but I need to set the parameter type of 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...

like image 529
Stijn Geukens Avatar asked Mar 17 '23 15:03

Stijn Geukens


1 Answers

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) {
});
like image 188
Stijn Geukens Avatar answered Mar 20 '23 00:03

Stijn Geukens