Spring MultipartFile 验证和转换 [英] Spring MultipartFile validation and conversion

查看:28
本文介绍了Spring MultipartFile 验证和转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有一个采用 MultipartFile 的 Spring MVC 控制器

I currently have a Spring MVC controller that takes a MultipartFile

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

该文件包含将用于创建域对象列表的 csv 数据,每行一个.这是有效的.

The file contains csv data which will be used, one per row, to create a list of domain objects. This is working.

我已经为行数据编写了一个转换器:

I have written a converter for the line data:

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

和文件的验证器

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

我有一个表格可以上传:

And I have a form to do the uploading:

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

但我真正想做的是将它们结合在一起,这样我的控制器就可以有一个类似

But what I really want to do is tie it all together so that my controller can have a method something like

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

我知道 Spring MVC 框架支持转换器和验证器,但我不明白如何让它们协同工作.

I know that the Spring MVC framework supports converters and validators, but I am failing to understand how to get them to work together.

推荐答案

首先我将 MultipartFile 包装在一个表单支持对象中:

First I wrapped the MultipartFile in a form backing object:

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

然后我绑定到我的表单:

Which I then bound to my form:

<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>

在控制器中我分配了一个验证器:

In the controller I assign a validator:

@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.

The validator uses a Converter for the line-item conversion to MyObj.

doPost 方法现在看起来像这样:

The doPost method now looks like this:

@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 非常相似:

The UploadConverter is much the same as the 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;
    }
}

唯一的问题是验证和转换过程大致相同.好在上传的文件不会很大,所以重复工作不是大问题.

The only problem is that the validation and conversion processes are much the same thing. Luckily the upload files will not be very large so the duplication of effort is not a big problem.

这篇关于Spring MultipartFile 验证和转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆