Я хочу опубликовать файл с некоторыми данными JSON с помощью Spring MVC. Итак, я разработал сервис отдыха как
@RequestMapping(value = "/servicegenerator/wsdl", method = RequestMethod.POST,consumes = { "multipart/mixed", "multipart/form-data" })
@ResponseBody
public String generateWSDLService(@RequestPart("meta-data") WSDLInfo wsdlInfo,@RequestPart("file") MultipartFile file) throws WSDLException, IOException,
JAXBException, ParserConfigurationException, SAXException, TransformerException {
return handleWSDL(wsdlInfo,file);
}
Когда я отправляю запрос от остального клиента
content-Type = multipart/form-data or multipart/mixed
, я получаю следующее исключение:
org.springframework.web.multipart.support.MissingServletRequestPartException
Может ли кто-нибудь помочь мне в решении этого вопроса?
Могу ли я использовать @RequestPart
для отправки на сервер как Multipart, так и JSON?
json
spring
spring-mvc
Сунил Кумар
источник
источник
org.springframework.web.multipart.commons.CommonsMultipartResolver
в контексте вашего сервлета?Ответы:
Вот как я реализовал Spring MVC Multipart Request с данными JSON.
Составной запрос с данными JSON (также называемый смешанным составным):
На основе службы RESTful в выпуске Spring 4.0.2 HTTP-запрос с первой частью в виде данных в формате XML или JSON, а второй частью в виде файла может быть выполнен с помощью @RequestPart. Ниже приведен пример реализации.
Фрагмент Java:
Служба отдыха в контроллере будет иметь смешанные @RequestPart и MultipartFile для обслуживания такого запроса Multipart + JSON.
@RequestMapping(value = "/executesampleservice", method = RequestMethod.POST, consumes = {"multipart/form-data"}) @ResponseBody public boolean executeSampleService( @RequestPart("properties") @Valid ConnectionProperties properties, @RequestPart("file") @Valid @NotNull @NotBlank MultipartFile file) { return projectService.executeSampleService(properties, file); }
Фрагмент внешнего интерфейса (JavaScript):
Создайте объект FormData.
Добавьте файл в объект FormData, используя один из следующих шагов.
formData.append("file", document.forms[formName].file.files[0]);
formData.append("file", myFile, "myfile.txt");
ИЛИ ЖЕformData.append("file", myBob, "myfile.txt");
Создайте большой двоичный объект со строковыми данными JSON и добавьте его в объект FormData. Это приводит к тому, что Content-type второй части в составном запросе будет «application / json» вместо типа файла.
Отправьте запрос на сервер.
Запрос о подробностях:
Content-Type: undefined
. Это заставляет браузер устанавливать Content-Type на multipart / form-data и правильно заполнять границу. Если вручную установить Content-Type на multipart / form-data, не удастся заполнить граничный параметр запроса.Код Javascript:
formData = new FormData(); formData.append("file", document.forms[formName].file.files[0]); formData.append('properties', new Blob([JSON.stringify({ "name": "root", "password": "root" })], { type: "application/json" }));
Детали запроса:
method: "POST", headers: { "Content-Type": undefined }, data: formData
Запросить данные:
Accept:application/json, text/plain, */* Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryEBoJzS3HQ4PgE1QB ------WebKitFormBoundaryvijcWI2ZrZQ8xEBN Content-Disposition: form-data; name="file"; filename="myfile.txt" Content-Type: application/txt ------WebKitFormBoundaryvijcWI2ZrZQ8xEBN Content-Disposition: form-data; name="properties"; filename="blob" Content-Type: application/json ------WebKitFormBoundaryvijcWI2ZrZQ8xEBN--
источник
processData: false, contentType: false
сJQuery $ajax()
Required request part file is not present
@NotBlank
аннотация к параметру метода MultipartFile на самом деле не проверяет, пуст ли файл. По-прежнему можно загружать документы с 0 байтами.Это должно сработать!
клиент (угловой):
$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 JSON! var req = { url: '/upload', method: 'POST', headers: {'Content-Type': undefined}, data: formData, transformRequest: function (data, headersGetterFunction) { return data; } };
Backend-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
источник
Как говорится в документации:
источник
В наших проектах мы видели, что почтовый запрос с JSON и файлами создает путаницу между разработчиками внешнего и внутреннего интерфейса, что приводит к ненужной трате времени.
Вот лучший подход: преобразовать массив байтов файла в строку Base64 и отправить его в формате JSON.
public Class UserDTO { private String firstName; private String lastName; private FileDTO profilePic; } public class FileDTO { private String base64; // just base64 string is enough. If you want, send additional details private String name; private String type; private String lastModified; } @PostMapping("/user") public String saveUser(@RequestBody UserDTO user) { byte[] fileBytes = Base64Utils.decodeFromString(user.getProfilePic().getBase64()); .... }
Код JS для преобразования файла в строку base64:
var reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function () { const userDTO = { firstName: "John", lastName: "Wick", profilePic: { base64: reader.result, name: file.name, lastModified: file.lastModified, type: file.type } } // post userDTO }; reader.onerror = function (error) { console.log('Error: ', error); };
источник