복붙노트

[SPRING] Spring MultipartFile 검증 및 변환

SPRING

Spring MultipartFile 검증 및 변환

현재 MultipartFile을 사용하는 Spring MVC 컨트롤러가 있습니다.

@RequestMapping(method = RequestMethod.POST)
public String doUpload(@RequestParam("file") final MultipartFile file) {
    /* ... */
}

이 파일에는 도메인 개체 목록을 만들기 위해 행당 하나씩 사용되는 csv 데이터가 들어 있습니다. 이것은 작동 중입니다.

나는 라인 데이터를위한 변환기를 작성했다.

class MyObjectConverter implements org.springframework...Converter<String[], MyObject> {
    /* ... */
}

파일의 유효성 검사기

class UploadFileValidator implements org.springframework.validation.Validator { 
    /* ... */
}

업로드 할 수있는 양식이 있습니다.

<form method="post" 
    action="<@spring.url '/upload'/>" 
    enctype="multipart/form-data">
        <input id="upload" type="file" name="file"/>
        <input type="submit" id="uploadButton"/>
    </form

하지만 내가 정말로하고 싶은 것은 컨트롤러를 모두 묶어서 내 컨트롤러가

@RequestMapping(method = RequestMethod.POST)
public String doUpload(
    @Valid final List<MyObject> objList, 
    final BindingResult result) { ...}

Spring MVC 프레임 워크는 변환기와 유효성 검사기를 지원하지만, 이들을 함께 작동시키는 방법을 이해하지 못하고 있습니다.

해결법

  1. ==============================

    1.먼저 MultipartFile을 폼 백업 객체에 래핑했습니다.

    먼저 MultipartFile을 폼 백업 객체에 래핑했습니다.

    public class UploadBackingForm {
        private MultipartFile multipartFile;
        /* ... getter/setter */
    }
    

    그럼 나는 내 양식에 묶여있다.

    <form method="post" enctype="multipart/form-data">
    <@spring.bind "backingform.*"/>
    <tr>
        <td><@spring.formInput 'backingform.multipartFile' '' 'file' /></td>
        <td> <button type="submit">Upload</button> </td>
    </tr>
    </form>
    

    컨트롤러에서 나는 밸리데이터를 할당합니다 :

    @InitBinder
    public void initBinder(final DataBinder binder) {
        binder.setValidator(new UploadValidator());
    }
    

    그리고 이것이 유효성 검사기입니다.

    public class UploadValidator implements Validator {
        private final Converter<String[], MyObject> converter 
            = new MyObjectConverter();
    
        @Override
        public boolean supports(final Class<?> clazz) {
            return UploadBackingForm.class.equals(clazz);
        }
    
        @Override
        public void validate(final Object target, final Errors errors) {
            final UploadBackingForm backingForm = (UploadBackingForm) target;
            final MultipartFile multipartFile = backingForm.getMultipartFile();
            final List<String[]> uploadData = /* parse file */
            for (final String[] uploadDataRow : uploadData){
                try {
                    converter.convert(uploadDataRow);
                } catch (IllegalArgumentException e) {
                    errors.rejectValue("multipartFile", "line.invalid", ...);
                }
            }
        }
    }
    

    유효성 검사기는 MyObj에 대한 라인 항목 변환을 위해 변환기를 사용합니다.

    이제 doPost 메소드는 다음과 같습니다.

    @RequestMapping(method = RequestMethod.POST)
    public String doUpload(
        @Valid @ModelAttribute("backingform") UploadBackingForm backingForm, 
        final BindingResult result, 
        final HttpSession session) throws IOException {
    
        final UploadConverter converter = new UploadConverter();
        final List<MyObj> imports = 
            converter.convert(backingForm.getMultipartFile().getInputStream());
     }
    

    UploadConverter는 UploadValidator와 거의 같습니다.

    public class UploadConverter implements Converter<InputStream, List<MyObject>> {
        private final Converter<String[], MyObject> converter = new MyObjectConverter();
    
        @Override
        public List<MyObject> convert(final InputStream source) {
            final List<String[]> detailLines = /* ... getDetailLines */
            final List<MyObject> importList = 
                new ArrayList<MyObject>(detailLines.size());
    
            for (final String[] row : detailLines) {
                importList.add(converter.convert(row));
            }
            return importList;
        }
    }
    

    유일한 문제는 유효성 검사 및 변환 프로세스가 거의 동일한 것입니다. 다행히도 업로드 파일은 그리 크지 않기 때문에 노력의 중복은 큰 문제가 아닙니다.

  2. ==============================

    2.MultipartFile을 MyObjects로 변환 할 수 있지만 String []을 MyObjectsContainer로 변환 할 수없는 변환기가 필요합니다. - MyObjectsContainer는 MyObject 목록 주위의 래퍼 일뿐입니다.

    MultipartFile을 MyObjects로 변환 할 수 있지만 String []을 MyObjectsContainer로 변환 할 수없는 변환기가 필요합니다. - MyObjectsContainer는 MyObject 목록 주위의 래퍼 일뿐입니다.

    그러나 MultipartFile이 매우 특별한 매개 변수이기 때문에이 변환기가 작동하는지 실제로 알 수 없습니다.

    유효성 검사를 위해 MyObjectsContainer에서 JSR 303 Bean 유효성 검사 주석을 강력히 권장합니다.

    그런 다음 작성할 수 있습니다.

    @RequestMapping(method = RequestMethod.POST)
    public String doUpload(@RequestParam("file") final MyObjectsContainer container) {}
    
  3. from https://stackoverflow.com/questions/7161215/spring-multipartfile-validation-and-conversion by cc-by-sa and MIT license