java - 在 Spring REST api 中验证 multipart/form-data
问题描述
我最近遇到了一个与验证有关的问题。通常,我正在构建一个允许用户创建包括头像在内的帐户的 REST api。当用户单击注册按钮时,应提交所有信息。因此,我的服务器将收到一个请求,其中包含一些字段,例如name (string), birthday (datetime), ... and avatar (multipart file)
. 因此,问题是如何验证接收到的文件是真实的图像并且具有允许的大小,同时验证其他文件(电子邮件、密码)是否也有效。
对于所有字段都是文本的情况,我们可以使用这样的注释组合轻松验证它们
控制器
@PostMapping(path = "")
public ResponseEntity<?> createNewAccount(@RequestBody @Valid RegisterRequest registerRequest) {
Long resourceId = service.createNewCoderAccount(registerRequest);
return ResponseEntity.created(location(resourceId)).build();
}
请求 DTO
@ConfirmedPassword
public class RegisterRequest extends BaseRequest implements ShouldConfirmPassword {
@NotBlank(message = "Field 'email' is required but not be given")
@Email
@Unique(message = "Email has been already in use", service = UserValidatorService.class, column = "email")
private String email;
@NotBlank(message = "Field 'password' is required but not be given")
@Size(min = 6, message = "Password should contain at least 6 characters")
private String password;
@NotBlank(message = "Field 'confirmPassword' is required but not be given")
private String confirmPassword;
@NotBlank(message = "Field 'firstName' is required but not be given")
private String firstName;
@NotBlank(message = "Field 'lastName' is required but not be given")
private String lastName;
}
或者如果请求只包含文件,我们绝对可以这样做
控制器
@PostMapping(path = "/{id}")
public ResponseEntity<?> editChallengeMetadata(
@ModelAttribute ChallengeMetadataRequest request,
BindingResult bindingResult,
@PathVariable("id") Long id,
@CurrentUser User user
) throws BindException {
challengeMetadataRequestValidator.validate(request, bindingResult);
if (bindingResult.hasErrors()) {
throw new BindException(bindingResult);
}
Long challengeId = service.updateChallengeMetadata(id, request, user);
return ResponseEntity.ok(RestResponse.build(challengeId, HttpStatus.OK));
}
验证器
public class ChallengeMetadataRequestValidator implements Validator {
@Override
public boolean supports(@NonNull Class<?> aClass) {
return ChallengeMetadataRequest.class.isAssignableFrom(aClass);
}
@Override
public void validate(@NonNull Object o, @NonNull Errors errors) {
ChallengeMetadataRequest request = (ChallengeMetadataRequest) o;
if (request.getBanner() != null && !request.getBanner().isEmpty()) {
if (!List.of("image/jpeg", "image/png").contains(request.getBanner().getContentType())) {
errors.rejectValue("banner", "challenge.mime-type.not-supported", new String[]{request.getBanner().getContentType()}, "Mime-type is not supported");
}
}
}
}
正如您在上面看到的,如果我将所有数据(包括头像)包装在一个 DTO 类中,我肯定会编写它自己的验证器。但是如果我必须手动编写数百个这样的验证器会发生什么。
那么,有没有人对此有任何想法,通常,使multipart/form-data
request 变得与application/json
request 相似?
谢谢并恭祝安康,
解决方案
推荐阅读
- python - 如何在二维列表中搜索单词并创建包含行号、列号和方向的元组?
- windows - 如何在 Windows 中禁用软件 SMI(系统管理中断)
- javascript - 导航栏滚动上的徽标克隆
- oracle - oracle 程序创建并运行 oracle-00900 错误
- java - 如何对 Arraylist 进行排序,以便特定项目排在首位
- r - 四分之一圆 ggplot-s 不存在点
- php - 如果第一个配置失败,则从其他配置发送邮件 laravel
- javascript - 进度条超过 100
- python-3.x - 如何将 S3 存储桶中的选定文件转换为雪花阶段,以便使用 python 和 boto3 将数据加载到雪花中
- java - 将字节数组子集转换为 Java 中的基元