Backend Development 7 min read

Implementing Multi-Image Upload and Preview in Spring MVC

This article demonstrates how to implement a merchant registration backend feature that supports uploading multiple images with preview using Spring MVC's MultipartFile, including controller handling, front‑end HTML/JS code, configuration for file size limits, and global exception handling.

Top Architect
Top Architect
Top Architect
Implementing Multi-Image Upload and Preview in Spring MVC

These days the company needed a merchant registration backend where merchants can upload multiple pictures and see them previewed; this article records the necessary knowledge points.

Upload

The controller uses Spring MVC’s MultipartFile array to receive the files; the parameter name must match the name attribute of the <input> element.

@RequestMapping("/pic")
@ResponseBody
public ResponseEntity
pic(MultipartFile[] pictures) throws Exception {
    ResponseEntity
responseEntity = new ResponseEntity<>();
    long count = Arrays.asList(pictures).stream()
            .map(MultipartFile::getOriginalFilename)
            .filter(String::isEmpty).count();
    if (count == pictures.length) {
        responseEntity.setCode(ResponseEntity.ERROR);
        throw new NullOrEmptyException("图片不能同时为空");
    }
    responseEntity.setCode(ResponseEntity.OK);
    responseEntity.setMessage("上传成功");
    return responseEntity;
}

The front‑end HTML uses an input type="file" with name="pictures" and a preview container whose background image is set via JavaScript.

<div class="container">
    <div class="avatar-upload">
        <div class="avatar-edit">
            <input type='file' name="pictures" id="imageOne" accept=".png, .jpg, .jpeg"/>
            <label for="imageOne"></label>
        </div>
        <div class="avatar-preview">
            <div id="imageOnePreview" style="background-image: url(... )"></div>
        </div>
    </div>
</div>

JavaScript reads the selected file and sets the preview background, then uploads the form data via AJAX.

function readURLOne(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();
        reader.onload = function(e) {
            $('#imageOnePreview').css('background-image', 'url(' + e.target.result + ')');
            $('#imageOnePreview').hide().fadeIn(650);
        };
        reader.readAsDataURL(input.files[0]);
    }
}
$("#imageOne").change(function () { readURLOne(this); });

function getUpload() {
    var formData = new FormData($("#picForm")[0]);
    $.ajax({
        url: '/pic',
        type: 'POST',
        dataType: "json",
        data: formData,
        processData: false,
        contentType: false,
        success: function (data) {
            window.confirm(data.message);
            window.location.reload();
        },
        error: function (res) {
            alert("失败");
        }
    });
}

Configuration

Spring Boot multipart settings can limit file size, e.g.:

spring:
  servlet:
    multipart:
      enabled: true
      max-file-size: 20MB
      max-request-size: 20MB

Additional properties such as spring.servlet.multipart.file-size-threshold and spring.servlet.multipart.location are also shown.

Exception Handling

A global exception handler annotated with @ControllerAdvice catches custom NullOrEmptyException and generic exceptions, returning a unified ResponseEntity structure.

@ControllerAdvice
@Slf4j
public class CommonExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(NullOrEmptyException.class)
    @ResponseBody
    public ResponseEntity
nullOrEmptyExceptionHandler(HttpServletRequest request, NullOrEmptyException exception) {
        log.info("nullOrEmptyExceptionHandler");
        return handleErrorInfo(request, exception.getMessage());
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResponseEntity
defaultErrorHandler(HttpServletRequest request, Exception exception) {
        log.info("defaultErrorHandler");
        return handleErrorInfo(request, exception.getMessage());
    }

    private ResponseEntity
handleErrorInfo(HttpServletRequest request, String message) {
        ResponseEntity
responseEntity = new ResponseEntity<>();
        responseEntity.setMessage(message);
        responseEntity.setCode(ResponseEntity.ERROR);
        responseEntity.setData(message);
        responseEntity.setUrl(request.getRequestURL().toString());
        return responseEntity;
    }
}

Pitfalls

If the controller method returns a view name, do not annotate it with @ResponseBody , otherwise the view name will be serialized as JSON.

Parameter names in the front‑end must exactly match those in the back‑end; otherwise a 405 error may occur.

When using Lombok in IDEA, enable annotation processing in the IDE settings.

The complete source code is available at GitHub .

BackendJavaExceptionHandlingFileUploadSpringMVCmultipartfile
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.