【问题标题】:Grails error handling in controller for loop控制器 for 循环中的 Grails 错误处理
【发布时间】:2015-11-24 18:00:10
【问题描述】:

我正在使用 for 循环遍历控制器中上传的 CSV 文件。如果我的任何记录包含错误,我需要能够在 GSP 中显示整个错误列表并且不保存任何记录。如果不存在错误,则保存整批记录。

我正在努力理解如何做到这一点。你迭代 CSV 文件两次,第一次寻找错误,第二次处理 db 提交?我是否会创建一个错误列表并将它们作为 flash.message 发回?

我的代码

def uploadFile() {
    CsvToBean<EffortDetail> csvToBean = new CsvToBean<>();

    Map<String, String> columnMapping = new HashMap<String, String>();
    columnMapping.put("ExternalID", "alternateId");
    columnMapping.put("Full Name", "fullName");
    columnMapping.put("OrgKey", "orgkey");
    columnMapping.put("expenseDate", "expenseDate");
    columnMapping.put("projectHours", "projectHours");
    columnMapping.put("totalHours", "totalHours");

    HeaderColumnNameTranslateMappingStrategy<EffortDetail> strategy = new HeaderColumnNameTranslateMappingStrategy<EffortDetail>();
    strategy.setType(EffortDetail.class);
    strategy.setColumnMapping(columnMapping);

    MultipartFile file = request.getFile('file');

    if(file.empty) {
        flash.message = "File cannot be empty"
    } else {
        List<EffortDetail> effortDetails = null;
        CSVReader reader = new CSVReader(new InputStreamReader(file.getInputStream()));
        effortDetails = csvToBean.parse(strategy, reader);

        int count = 0;

        //iterate for errors
        for(EffortDetail effortDetail : effortDetails) {
            println "loop 1 " + count++

            def recoveryDetailInstance = recoveryDetailService.populate(effortDetail)
            // Test code to try and throw a list of flash messages
            flash.message = count++;
        }

        count = 0;

        //Iterate for commit
        for(EffortDetail effortDetail : effortDetails) {
            println "loop 2 " + count++

            def recoveryDetailInstance = recoveryDetailService.populate(effortDetail)
            recoveryDetailInstance.save(flush:true,failOnError:true)
        }
    }

    redirect (action:'upload')
}

.gsp

        <div class="col-md-12">
            <g:if test="${flash.message}">
                <div class="message" role="status">
                    ${flash.message}
                </div>
            </g:if>
            <g:eachError bean="${recoveryDetailInstance}">
                <li>${it}</li>
            </g:eachError>
            <g:uploadForm action="uploadFile">
                <span class="button"> <input type="file" name="file" /> <input
                    type="submit" class="upload" value="upload" />
                </span>
            </g:uploadForm>
        </div>

【问题讨论】:

    标签: grails groovy


    【解决方案1】:

    您需要调查交易。这是另一个 Stackoverflow 线程,我相信它完全符合您的要求。

    Grails - Saving multiple object, Rollback all object if one fails to save

    TLDR 是将您的处理逻辑从控制器移动到服务类方法。然后将您的循环组合成一个循环,该循环同时进行验证和域保存。如果出现任何错误,您可以在调用回滚后返回失败的域对象列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-12
      • 1970-01-01
      相关资源
      最近更新 更多