2016-08-09 126 views
0

Gibt es eine Möglichkeit zu validieren StandardMultipartHttpServletRequest mit Standard @Valid Annotation und benutzerdefinierte Validator?Spring StandardMultipartHttpServletRequest Validierung

Ich habe solche Validator, annotierte Methode Param im Controller implementiert der Validator wird nicht aufgerufen.

+0

Ich habe Validator für MultipartFile-Schnittstelle implementiert und es funktioniert. Warum müssen Sie "StandardMultipartHttpServletRequest" genau validieren? –

+0

@SlavaSemushin, da dies das Argument der Methode im Controller ist. Daraus extrahiere ich die Upload-Dateien. – Opal

+0

Ja, und 'StandardMultipartHttpServletRequest' implementiert' MultipartFile'. Wenn Sie keine implementierungsspezifischen Methoden verwenden, können Sie den Argumenttyp durch diese Schnittstelle ersetzen. Ich sehe nicht, was hier dein Problem ist. Eigenen Validator implementieren, Annotation einfügen, Annotation "@ Valid" hinzufügen usw. –

Antwort

0

Ich habe es selbst herausgefunden. Damit es funktioniert benötigen Sie einen DTO:

import lombok.Getter; 
import lombok.Setter; 
import org.springframework.web.multipart.MultipartFile; 

import java.util.List; 

@Getter 
@Setter 
public class NewOrderFilesDTO { 
    List<MultipartFile> files; 
} 

Dann wird ein Validator:

import org.springframework.stereotype.Component; 
import org.springframework.validation.Errors; 
import org.springframework.validation.Validator; 
import org.springframework.web.multipart.MultipartFile; 

import java.util.List; 

import static org.springframework.util.CollectionUtils.isEmpty; 

@Component 
public class NewOrderFilesValidator implements Validator { 

    private static final String MIME_TYPE_PDF = "application/pdf"; 
    private static final long ALLOWED_SIZE = 3 * 1024 * 1024; 

    @Override 
    public void validate(Object target, Errors errors) { 
     if (target == null) { 
      return; 
     } 

     NewOrderFilesDTO newOrderFilesDTO = (NewOrderFilesDTO) target; 
     List<MultipartFile> newOrderFiles = newOrderFilesDTO.getFiles(); 

     if (isEmpty(newOrderFiles)) { 
      return; 
     } 

     for (MultipartFile file : newOrderFiles) { 
      if (!MIME_TYPE_PDF.equals(file.getContentType())) { 
       errors.rejectValue(file.getName(), file.getName(), "'application/pdf' files allowed only!"); 
      } 

      if (file.getSize() > ALLOWED_SIZE) { 
       errors.rejectValue(file.getName(), file.getName(), "File size allowed up to 3MB!"); 
      } 
     } 
    } 

    @Override 
    public boolean supports(Class<?> cls) { 
     return NewOrderFilesDTO.class.equals(cls); 
    } 
} 

Und schließlich einen Controller:

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.WebDataBinder; 
import org.springframework.web.bind.annotation.InitBinder; 
import org.springframework.web.bind.annotation.ModelAttribute; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.ResponseStatus; 

import javax.validation.Valid; 

import static org.springframework.http.HttpStatus.NO_CONTENT; 
import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; 
import static org.springframework.web.bind.annotation.RequestMethod.POST; 

@Controller 
class OrderController { 

    private final NewOrderFilesValidator newOrderFilesValidator; 

    @Autowired 
    OrderController(NewOrderFilesValidator newOrderFilesValidator) { 
     this.newOrderFilesValidator = newOrderFilesValidator; 
    } 

    @InitBinder("newOrderFiles") 
    void initOrderFilesBinder(WebDataBinder binder) { 
     binder.addValidators(newOrderFilesValidator); 
    } 

    @ResponseStatus(NO_CONTENT) 
    @RequestMapping(value = ORDERS_PATH, method = POST, consumes = MULTIPART_FORM_DATA_VALUE) 
    void createOrder(
      @Valid @ModelAttribute NewOrderFilesDTO newOrderFiles 
    ) { 

    } 
} 

Mit der Konfiguration über dem DTO werden automatisch validiert werden bis zum Frühling.

+0

Nur um Sie wissen zu lassen, dass die Suche nach einem Dateityp schwach ist, da er auf den Headern der Benutzeranforderung basiert. –

+0

@SlavaSemushin, ja ich weiß das. Vielleicht wird es auf eine andere Weise verifizieren. – Opal

+0

Ein weiterer Raum zur Verbesserung wäre die Umwandlung Ihres Validators in den JSR-303 Validator. In diesem Fall kann es leicht wiederverwendet werden und wäre nicht vom Frühling abhängig. –