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.
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: 20MBAdditional 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 .
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.