如何使用BindingResult检查特定行是否在Spring中进行多行验证时出现验证错误

当前逻辑将检查BindingResult是否有错误并在jsp中显示数据和错误.

所需的逻辑是检查每行的错误并仅显示包含验证错误的行,并更新没有验证错误的行.

    @Autowired

     private IncidentExtractStgService incidentExtractStgService;

@RequestMapping(value = "/validatingIncidentList", method = RequestMethod.POST)
public String ValidateIncidentList( @Valid @ModelAttribute("incidentsForm") IncidentsForm incidentsForm,
        BindingResult bindingResult,RedirectAttributes redirectAttributes) {
    if (bindingResult.hasErrors()) {


        for(ObjectError error: bindingResult.getAllErrors()){

            System.out.println(error);
        }

        redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.incidentsForm", bindingResult);
        redirectAttributes.addFlashAttribute("incidentsForm", incidentsForm);

        return "redirect:/validateIncidentList";
    }
    else
    {
        for(IncidentExtractStg ie : incidentsForm.getIncidents()) {

            ie.setValidated(1);
            incidentExtractStgService.update(ie);

            System.out.println(ie.getNumber()+"     "+ie.getWaitTime());
        }


    return  "redirect:/validateIncidentList";

    }

下面的代码片段将检查模型是否包含属性“incidetsForm”,如果是,则将相同的内容发送到example.jsp,而example.jsp将显示数据和验证错误.

@RequestMapping(value = "/validateIncidentList", method = RequestMethod.GET)
 public String incidentList(Model model) {
    if (!model.containsAttribute("incidentsForm")) {
            List<IncidentExtractStg> incidents = incidentExtractStgDao.validateList();
            incidentsForm.setIncidents(incidents);
            model.addAttribute("incidentsForm", incidentsForm);
            return "example";
    }

     model.addAttribute("errormessage","Please Check the Validation Errors column for Errors");
     return "example";
}

Example.jsp代码段

<c:forEach var="ie" items="${incidentsForm.incidents}" varStatus="status">
             <tr>
                  <td><form:input path="incidents[${status.index}].id" value="${ie.id}" readonly ="true"/></td>
                 <td><form:errors path="incidents[${status.index}].id" cssClass="error" /></td> 

                <td><form:input path="incidents[${status.index}].number" value="${ie.number}"/></td>
                <td><form:errors path="incidents[${status.index}].number" cssClass="error" /></td> 
            </tr>

IncidentsForm.java:

import java.util.List;
import javax.validation.Valid;

import com.infosys.sla.model.IncidentExtractStg;

public class IncidentsForm {

@Valid
private List<IncidentExtractStg> incidents;



public List<IncidentExtractStg> getIncidents() {
    return incidents;
}


public void setIncidents(List<IncidentExtractStg> incidents) {

    this.incidents = incidents;
}
}

IncidentExtractStg.java片段

@Entity
@Table(name="incident_extract_stg")
public class IncidentExtractStg {

@Id
@Column(name="ies_id")
private int id;

@NotBlank(message="number cannot be empty")
@Pattern(regexp="[A-Za-z0-9]*",message="number can contain only alphabets and numbers")
@Column(name="ies_number")
private String number;

最佳答案 首先,如果我是你,我将提取服务层内的所有逻辑.要继续,您可以创建一个接口IncidentService及其自己的具体实现IncidentServiceImpl,您可以在其中安全地处理您的需求.控制器绝对不是做任何事情.

那你有什么需求呢?
“检查每行的错误并仅显示包含验证错误的行并更新没有验证错误的行”

服务层内的方法可能是这样的:

public void handleErrors(IncidentsForm incidentsForm, BindingResult bindingResult){ 

    List<String> fieldsInErrorState = new ArrayList<String>(10);

    if (bindingResult.hasErrors()) { //
        Map<String, Object> bindingModel = bindingResult.getModel();

        for (Map.Entry<String, Object> entry : bindingModel.entrySet()) {
            String key = entry.getKey();
            //Object value = entry.getValue(); you don't need to parse that unless you want specific domain model handlers to run

            //you need to store the key as a form field which is in error state
            fieldsInErrorState.add(key);

            //you already have all the stuff to parse and display errors in your JSP
            //thanksfully to bindingResult and JSTL tags.
        }

        ContactMessageForm cmForm2 = new ContactMessageForm();
        // get the list of the fields inside your form
        Field[] declaredFields = ContactMessageForm.class.getDeclaredFields();
        for (Field field : declaredFields) {
            if (!fieldsInErrorState.contains(field.getName())) {
                if (field.getName().equalsIgnoreCase("firstname")) {
                    cmForm2.setFirstname(contactMessageForm.getFirstname());
                }
                if (field.getName().equalsIgnoreCase("lastname")) {
                    cmForm2.setLastname(contactMessageForm.getLastname());
                }

                //etc for each properties of your form object.
            }

            // then store your dbmodel object
            // BUT i think you must be carefull to your data integrity... It is maybe not safe to save an object like that with bypassing some stuff... 
            // Your form was built like that maybe for a good reason looking at your objects graph.
            // If your form is too big, then split it in small parts, it will be much easy to handle, to update, and to work with daily.
        }

    }


}

当然,您需要自定义该代码,不要忘记将抛出的IntrospectionException添加到您的服务方法中,并且您处于良好的状态.

干杯!

点赞