How do I display validation errors about an uploaded multipart file using Spring MVC

后端 未结 2 1629
谎友^
谎友^ 2021-01-14 06:47

I have a Spring MVC application with a file upload form.

I would like to be able to display validation errors to a user if the upl

相关标签:
2条回答
  • 2021-01-14 06:51

    If you are using Java Bean Validation (JSR 303) you can make annotation that validates content type. See code below.

    import static java.lang.annotation.ElementType.*;
    import static java.lang.annotation.RetentionPolicy.*;
    /**
     * The annotated element must have specified content type.
     *
     * Supported types are:
     * <ul>
     * <li><code>MultipartFile</code></li>
     * </ul>
     *
     * @author Michal Kreuzman
     */
    @Documented
    @Retention(RUNTIME)
    @Constraint(validatedBy = {ContentTypeMultipartFileValidator.class})
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    public @interface ContentType {
    
        String message() default "{com.kreuzman.ContentType.message}";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    
    /**
     * Specify accepted content types.
     *
     * Content type example :
     * <ul>
     * <li>application/pdf - accepts PDF documents only</li>
     * <li>application/msword - accepts MS Word documents only</li>
     * <li>images/png - accepts PNG images only</li>
     * </ul>
     *
     * @return accepted content types
     */
         String[] value();
    }
    

    /**
      * Validator of content type. This is simple and not complete implementation
      * of content type validating. It's based just on <code>String</code> equalsIgnoreCase
      * method.
      *
      * @author Michal Kreuzman
      */
     public class ContentTypeMultipartFileValidator implements ConstraintValidator<ContentType, MultipartFile> {
    
    private String[] acceptedContentTypes;
    
    @Override
    public void initialize(ContentType constraintAnnotation) {
        this.acceptedContentTypes = constraintAnnotation.value();
    }
    
    @Override
    public boolean isValid(MultipartFile value, ConstraintValidatorContext context) {
        if (value == null || value.isEmpty())
            return true;
    
        return ContentTypeMultipartFileValidator.acceptContentType(value.getContentType(), acceptedContentTypes);
    }
    
    private static boolean acceptContentType(String contentType, String[] acceptedContentTypes) {
        for (String accept : acceptedContentTypes) {
                // TODO this should be done more clever to accept all possible content types
            if (contentType.equalsIgnoreCase(accept)) {
                return true;
            }
        }
    
        return false;
    }
    }
    

    public class MyModelAttribute {
    
    @ContentType("application/pdf")
    private MultipartFile file;
    
    public MultipartFile getFile() {
        return file;
    }
    
    public void setFile(MultipartFile file) {
        this.file = file;
    }
    }
    @RequestMapping(method = RequestMethod.POST)
    public String processUploadWithModelAttribute(@ModelAttribute("myModelAttribute") @Validated final MyModelAttribute myModelAttribute, final BindingResult result, final Model model) throws IOException {
     if (result.hasErrors()) {
         // Error handling
         return "fileupload";
     }
    
     return "fileupload";
    }
    
    0 讨论(0)
  • 2021-01-14 06:59

    I got the answer to my question Spring community forums:

    Here is the controller method:

    @RequestMapping(method = RequestMethod.POST)
        public String processUploadWithModelAttribute(@ModelAttribute("myModelAttribute") final MyModelAttribute myModelAttribute, final BindingResult result, final Model model) throws IOException {
            String mimeType = determineMimeType(myModelAttribute.getFile().getBytes());
            if (mimeType.equalsIgnoreCase("application/pdf")){
                result.addError(new ObjectError("file", "pdf not accepted"));
            }
                return "fileupload";
        }
    

    And the model attribute class:

    public class MyModelAttribute {
    
        private MultipartFile file;
    
        public MultipartFile getFile() {
            return file;
        }
    
        public void setFile(MultipartFile file) {
            this.file = file;
        }
    }
    

    The idea is to put the MultipartFile into the ModelAttribute as an attribute.

    0 讨论(0)
提交回复
热议问题