【问题标题】:Spring ConstraintValidator vs MultipartFileSpring ConstraintValidator vs MultipartFile
【发布时间】:2018-10-09 09:02:02
【问题描述】:

我想检查使用 ConstraintValidator 上传时的文件扩展名。如果文件扩展名不是注释中指定的,那么用户应该得到常见的约束验证错误响应。但是当它发生时,就会发生这个异常

java.io.FileNotFoundException: C:\Users\Tensky\AppData\Local\Temp\tomcat.4393944258717178584.8443\work\Tomcat\localhost\ROOT\upload_a19ba701_88a1_4eab_88b7_eede3a273fe0_00000011.tmp

用户得到错误请求页面

我的课程: 注解@UploadFileTypes

@Documented
@Constraint(validatedBy = UploadFileTypesValidator.class)
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface UploadFileTypes {

    String message() default "Example message";

    UploadFileType[] allowedTypes() default {UploadFileType.AUDIO, UploadFileType.VIDEO, UploadFileType.DOCUMENT, UploadFileType.IMAGE};

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @Documented
    @Target({ElementType.FIELD, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @interface List{
        UploadFileTypes[] value();
    }
}

类 UploadFileTypesValidator:

public class UploadFileTypesValidator implements ConstraintValidator<UploadFileTypes, MultipartFile> {

    @Override
    public void initialize(UploadFileTypes constraintAnnotation) {
    }

    @Override
    public boolean isValid(MultipartFile value, ConstraintValidatorContext context) {
        return false; //<- always exception
    }
}

和控制器(永远达不到,因为isValid总是返回false:

@RequestMapping(path = "/add", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity addProperty(@Valid PropertyCreateRequest request) {
        return ResponseEntity.ok(null);
}

为什么会出现这个异常,如何避免?

【问题讨论】:

  • 只需将任何其他文件放在此位置,因为 FileNotFoundException 仅在无法读取文件的情况下发生。 C:\Users\Tensky\anyfile.txt
  • 文件大小没有任何作用
  • 将应用程序属性中的spring.servlet.multipart.location 设置为某个有效目录。

标签: java spring bean-validation


【解决方案1】:

问题解决了。 Spring 尝试在错误响应中序列化 MultipartFile

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
...
@Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        ...
        builder.serializers(new JsonSerializer<MultipartFile>() {
            @Override
            public Class<MultipartFile> handledType() {
                return MultipartFile.class;
            }

            @Override
            public void serialize(MultipartFile value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
                gen.writeStartObject();
                gen.writeStringField("contentType", value.getContentType());
                gen.writeStringField("filename",value.getName());
                gen.writeStringField("originalFilename", value.getOriginalFilename());
                gen.writeNumberField("size", value.getSize());
                gen.writeEndObject();
            }
        });

        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-11
    • 2017-11-27
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 2018-04-25
    • 1970-01-01
    • 2016-12-24
    相关资源
    最近更新 更多