2016-06-01 9 views
0

У меня есть форма, которая отправляется на мой back-end (Kotlin, Spring Web). У этой формы были некоторые текстовые входы, и почта работала безупречно. Но когда я добавил вход файла, пост перестал работать, возвращая ошибку:Угловая: как отправить файл на сервер в форме submit

{status: 400, error: "Bad Request",…} 
error: "Bad Request" 
exception: "org.springframework.http.converter.HttpMessageNotReadableException" 
message: "Could not read document: No suitable constructor found for type [simple type, class com.test.InsertConfigCommand]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)↵ at [Source: [email protected]; line: 1, column: 2]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.test.InsertConfigCommand]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)↵ at [Source: [email protected]; line: 1, column: 2]" 

Ниже приведены коды моего стека:

Вид:

<form ng-submit="insert(config)"> 
    <input type="text" ng-model="config.name"> 
    <input type="text" ng-model="config.address"> 
    <input type="file" ng-model="config.file"> 
    <button type="submit">Save</button> 
</form> 

контроллер (front-end):

$scope.insert = function (config) { 
    $http.post('/config', config) 
     .then(function (response) { 
      $.snackbar({content: "Success!"}); 
     }, $scope.showErrorMessage); 
}; 

Controller (фоновый):

@RequestMapping(method = arrayOf(RequestMethod.POST)) 
fun insert(@RequestBody config: InsertConfigCommand) = service.save(config) 

InsertConfigCommand

data class InsertConfigCommand (
    val name : String = "", 
    val address : String = "", 
    val file : MultipartFile 
) 

Я попытался сделать пост следующим образом, она работает, но только посылает файл:

Контроллер (front-end):

$scope.insert = function (file) { 
    var fd = new FormData(); 
    fd.append('file', file); 

    return $http.post('/config', fd, { 
     transformRequest: angular.identity, 
     headers: { 
      'Content-Type': undefined 
     } 
    }); 
}; 

Controller (фоновый):

@RequestMapping(method = arrayOf(RequestMethod.POST)) 
fun insert(@RequestParam(value = "file", required = true) file: MultipartFile) = service.save(file) 

Что мне нужно изменить для этого поста работать? Я хочу отправить входной файл на том же объекте, что имя и адрес.

ответ

0

Я использовал этот учебник, который инкапсулирует файл внутри объекта FormData и сообщения, которые возражают https://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs

$scope.insert = function (config) { 
    var fd = new FormData(); 
    fd.append('name', config.name); 
    fd.append('address', config.address); 
    fd.append('file', $scope.file); 
    $http.post('/config', fd, { 
      transformRequest: angular.identity, 
      headers: {'Content-Type': undefined} 
     }) 
     .then(function (response) { 
      $.snackbar({content: "Success!"}); 
     }, $scope.showErrorMessage); 
}; 

И на моем контроллере Котлина, я получаю каждый атрибут как отдельные пары:

@RequestMapping(method = arrayOf(RequestMethod.POST)) 
fun insert(@RequestParam(value = "name", required = true) name: String, 
      @RequestParam(value = "address", required = true) address: String, 
      @RequestParam(value = "file", required = false) file: MultipartFile): InsertConfigCommand? { 

    val command = InsertConfigCommand(
        name = name, 
        address = address, 
        file = file) 

    return service.save(command) 
} 
0

Я полагаю, вы используете Джексона, верно?

Байткод классов данных в Котлин выглядит иначе, чем один из обычных POJO (с конструктором по умолчанию), и поэтому Джексон не может инициализировать такой класс. Попробуйте добавить зависимость от Jackson Kotlin Module и обязательно зарегистрируйтесь.

Если вы используете Spring загрузка добавьте следующий код в любой из ваших @Configuration аннотированных классов:

@Bean 
open fun kotlinModule(): KotlinModule { 
    return KotlinModule() 
} 

и посмотреть, если это помогает.

+0

Извините, но это не сработало. Я не думаю, что это проблема Джексона, потому что, когда я делаю сообщение без параметра файла, синтаксический анализ работает. –