我正在使用for循环在我的控制器中迭代上传的CSV文件。如果我的任何记录包含错误,我需要能够在GSP中显示整个错误列表而不保存任何记录。如果没有错误,请保存整批记录。
我正在努力学习如何做到这一点。您是否迭代CSV文件两次,第一次查找错误,第二次处理数据库提交?我是否创建了错误列表并将其作为flash.message发回?
我的代码
public class MainActivity extends Activity {
Button b_bleu;
PrgressBar bar1;
@Override
public void onWindowFocusChanged(boolean hasFocus) {
b_bleu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ObjectAnimator animation = ObjectAnimator.ofInt(bar1, "progress", 100, 0);
animation.setDuration(5000);
animation.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
//application se termine
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
animation.cancel();
animation.start();
}
});
}
.gsp
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')
}
答案 0 :(得分:2)
您需要查看交易。这是另一个Stackoverflow线程,我相信它正是您正在寻找的。 p>
Grails - Saving multiple object, Rollback all object if one fails to save
TLDR是将处理逻辑从控制器移动到Service类方法。然后将您的循环组合成一个循环,同时执行验证和域保存。如果出现任何错误,您可以在调用回滚后返回失败的域对象列表。