Mixed POST submit from AngularJS to Spring RestCon

2019-05-03 23:51发布

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...

1条回答
家丑人穷心不美
2楼-- · 2019-05-04 00:43

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) {
});
查看更多
登录 后发表回答