Рубрики
Без рубрики

Пример загрузки загрузочного файла Spring – Ajax и REST

– Пример загрузки загрузочного файла весной – Ajax и REST

В этой статье показано, как загружать файлы в веб-приложение Spring Boot (структура REST) с помощью Ajax-запросов.

Инструменты, используемые в этой статье:

  1. Пружинный ботинок 1.4.3.ВЫПУСК
  2. Пружина 4.3.5. ВЫПУСК
  3. Вилочковый лист
  4. jQuery (веб-сайты)
  5. Знаток
  6. Встроенный Tomcat 8.5.6
  7. Браузер Google Chrome (Проверка сети)

1. Структура проекта

Стандартная структура проекта Maven.

2. Зависимость от проекта

Объявляет дополнительную зависимость jQuery webjar для Ajax-запросов в форме HTML.


    4.0.0

    com.mkyong
    spring-boot-file-upload
    jar
    1.0

    
        org.springframework.boot
        spring-boot-starter-parent
        1.4.3.RELEASE
    

    
        1.8
    

    

        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        

        
        
            org.springframework.boot
            spring-boot-devtools
            true
        

        
            org.webjars
            jquery
            2.2.4
        

    

    
        
            
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


3. Загрузка файла

Для поддержки запроса и ответа Ajax самым простым решением является возврат ResponseEntity .

3.1 Приведенный ниже пример демонстрирует три возможных способа загрузки файлов:

  1. Загрузка одного файла – Составной файл
  2. Загрузка нескольких файлов – Составной файл[]
  3. Загрузка файла карты в модель – @ModelAttribute
package com.mkyong.controller;

import com.mkyong.model.UploadModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@RestController
public class RestUploadController {

    private final Logger logger = LoggerFactory.getLogger(RestUploadController.class);

    //Save the uploaded file to this folder
    private static String UPLOADED_FOLDER = "F://temp//";

    // 3.1.1 Single file upload
    @PostMapping("/api/upload")
    // If not @RestController, uncomment this
    //@ResponseBody
    public ResponseEntity uploadFile(
            @RequestParam("file") MultipartFile uploadfile) {

        logger.debug("Single file upload!");

        if (uploadfile.isEmpty()) {
            return new ResponseEntity("please select a file!", HttpStatus.OK);
        }

        try {

            saveUploadedFiles(Arrays.asList(uploadfile));

        } catch (IOException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }

        return new ResponseEntity("Successfully uploaded - " +
                uploadfile.getOriginalFilename(), new HttpHeaders(), HttpStatus.OK);

    }

    // 3.1.2 Multiple file upload
    @PostMapping("/api/upload/multi")
    public ResponseEntity uploadFileMulti(
            @RequestParam("extraField") String extraField,
            @RequestParam("files") MultipartFile[] uploadfiles) {

        logger.debug("Multiple file upload!");

        // Get file name
        String uploadedFileName = Arrays.stream(uploadfiles).map(x -> x.getOriginalFilename())
                .filter(x -> !StringUtils.isEmpty(x)).collect(Collectors.joining(" , "));

        if (StringUtils.isEmpty(uploadedFileName)) {
            return new ResponseEntity("please select a file!", HttpStatus.OK);
        }

        try {

            saveUploadedFiles(Arrays.asList(uploadfiles));

        } catch (IOException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }

        return new ResponseEntity("Successfully uploaded - "
                + uploadedFileName, HttpStatus.OK);

    }

    // 3.1.3 maps html form to a Model
    @PostMapping("/api/upload/multi/model")
    public ResponseEntity multiUploadFileModel(@ModelAttribute UploadModel model) {

        logger.debug("Multiple file upload! With UploadModel");

        try {

            saveUploadedFiles(Arrays.asList(model.getFiles()));

        } catch (IOException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }

        return new ResponseEntity("Successfully uploaded!", HttpStatus.OK);

    }

    //save file
    private void saveUploadedFiles(List files) throws IOException {

        for (MultipartFile file : files) {

            if (file.isEmpty()) {
                continue; //next pls
            }

            byte[] bytes = file.getBytes();
            Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());
            Files.write(path, bytes);

        }

    }
}

3.2 Простая модель для приведенного выше примера 3.1.3 – @ModelAttribute

package com.mkyong.model;

import org.springframework.web.multipart.MultipartFile;

public class UploadModel {

    private String extraField;

    private MultipartFile[] files;

    //getters and setters
}

4. Взгляды

HTML-форма для нескольких загрузок файлов.






Spring Boot - Multiple file upload example - AJAX







Ajax Post Result

    

5. jQuery – Запрос Ajax

jQuery для получения формы через форму #id и отправьте данные составной формы с помощью Ajax-запроса.

$(document).ready(function () {

    $("#btnSubmit").click(function (event) {

        //stop submit the form, we will post it manually.
        event.preventDefault();

        fire_ajax_submit();

    });

});

function fire_ajax_submit() {

    // Get form
    var form = $('#fileUploadForm')[0];

    var data = new FormData(form);

    data.append("CustomField", "This is some extra data, testing");

    $("#btnSubmit").prop("disabled", true);

    $.ajax({
        type: "POST",
        enctype: 'multipart/form-data',
        url: "/api/upload/multi",
        data: data,
        //http://api.jquery.com/jQuery.ajax/
        //https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects
        processData: false, //prevent jQuery from automatically transforming the data into a query string
        contentType: false,
        cache: false,
        timeout: 600000,
        success: function (data) {

            $("#result").text(data);
            console.log("SUCCESS : ", data);
            $("#btnSubmit").prop("disabled", false);

        },
        error: function (e) {

            $("#result").text(e.responseText);
            console.log("ERROR : ", e);
            $("#btnSubmit").prop("disabled", false);

        }
    });

}

6. Обработчик исключений

Чтобы обработать исключение из Ajax-запроса, просто расширьте ResponseEntityExceptionHandler и вернуть обратно Отзывчивость .

package com.mkyong.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.servlet.http.HttpServletRequest;

//http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-error-handling
@ControllerAdvice
public class RestGlobalExceptionHandler extends ResponseEntityExceptionHandler {

    // Catch file size exceeded exception!
    @ExceptionHandler(MultipartException.class)
    @ResponseBody
    ResponseEntity handleControllerException(HttpServletRequest request, Throwable ex) {

        HttpStatus status = getStatus(request);
        return new ResponseEntity(ex.getMessage(), status);

        // example
        //return new ResponseEntity("success", responseHeaders, HttpStatus.OK);

    }

    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        return HttpStatus.valueOf(statusCode);
    }

}

7. ДЕМОНСТРАЦИЯ

Запустите Spring Boot с помощью встроенного по умолчанию Tomcat mvn spring-boot:выполнить .

7.1 Доступ http://localhost:8080/ , выберите несколько файлов и нажмите кнопку отправить, чтобы запустить ajax-запрос.

7.2 Google Chrome, просмотрите запрос и ответ в разделе “Проверка сети”

7.3 Google Chrome, “Запрашивать полезную нагрузку”

8. локон Тестирование

Дополнительное тестирование с помощью команды cURL .

8.1 Тестовая загрузка одного файла.

$ curl -F file=@"f:\\data.txt" http://localhost:8080/api/upload/
Successfully uploaded - data.txt

8.2 Протестируйте загрузку нескольких файлов.

$ curl -F extraField="abc" -F files=@"f://data.txt" -F files=@"f://data2.txt"  http://localhost:8080/api/upload/multi/
Successfully uploaded - data.txt , data2.txt

8.3 Проверка загрузки нескольких файлов, сопоставление с моделью.

$ curl -F extraField="abc" -F files=@"f://data.txt" -F files=@"f://data2.txt"  http://localhost:8080/api/upload/multi/model
Successfully uploaded!

8.4 Протестируйте большой видеофайл (100 МБ), появится следующее сообщение об ошибке.

$ curl -F file=@"F://movies//300//Sample.mkv"  http://localhost:8080/api/upload/
Attachment size exceeds the allowable limit! (10MB)

9. Завиток Тестирование + Пользовательский объект ошибки

9.1 Создайте объект для хранения сведений об ошибке.

package com.mkyong.exception;

public class CustomError {

    String errCode;
    String errDesc;

    public CustomError(String errCode, String errDesc) {
        this.errCode = errCode;
        this.errDesc = errDesc;
    }

    //getters and setters
}

9.2 Обновите глобальный обработчик исключений для поддержки Пользовательская ошибка объект.

package com.mkyong.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.servlet.http.HttpServletRequest;

@ControllerAdvice
public class RestGlobalExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(MultipartException.class)
    @ResponseBody
    ResponseEntity handleControllerException(HttpServletRequest request, Throwable ex) {

        HttpStatus status = getStatus(request);

        return new ResponseEntity(new CustomError("0x000123", 
                "Attachment size exceeds the allowable limit! (10MB)"), status);

        //return new ResponseEntity("Attachment size exceeds the allowable limit! (10MB)", status);

    }

    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        return HttpStatus.valueOf(statusCode);
    }

}

9.3 Сверните, чтобы снова загрузить большой файл.

$ curl -F file=@"F://movies//300//Sample.mkv"  http://localhost:8080/api/upload/

{"errCode":"0x000123","errDesc":"Attachment size exceeds the allowable limit! (10MB)"}

Сделано. Обратная связь приветствуется.

10. Скачать Исходный Код

Рекомендации

  1. Обработка ошибок при весенней загрузке
  2. Пример загрузки файла весенней загрузки
  3. Пример загрузки файла Spring MVC
  4. Пример весеннего ботинка Hello World – Thymeleaf
  5. Википедия – Завиток
  6. jQuery.аякс()
  7. MDN – Использование объектов FormData

Оригинал: “https://mkyong.com/spring-boot/spring-boot-file-upload-example-ajax-and-rest/”