2014-01-27 46 views
1

這將會有點複雜,但請耐心等待。我有一個擁有多個屬性的bean學生,我註釋了所有需要使用Hibernate註釋驗證的屬性。當我想要爲學生進行搜索時,我只需要一些註釋/驗證的屬性,但是對所有這些屬性都進行了驗證,這些驗證不允許搜索正確執行。使用Hibernate進行Spring MVC和bean驗證

這是學生豆:

@Id 
    @GeneratedValue(strategy = IDENTITY) 
    @Column(name = "STUDENT_ID", unique = true, nullable = false) 
    private Integer studentId; 

    @NotNull(message = "First name is null!") 
    @NotBlank(message = "Please enter first name!") 
    @Column(name = "FIRST_NAME", nullable = false, length = 50) 
    private String firstName; 

    @NotNull(message = "Last name is null!") 
    @NotBlank(message = "Please enter last name!") 
    @Column(name = "LAST_NAME", nullable = false, length = 50) 
    private String lastName; 

    @NotNull(message = "MK is null!") 
    @NotBlank(message = "Please enter MK!") 
    @Column(name = "MK", nullable = false, length = 2) 
    private String mk; 

    @NotNull(message = "Roll number is null!") 
    @NotBlank(message = "Please enter roll number!") 
    @Column(name = "ROLL_NUMBER", nullable = false, length = 4) 
    private String rollNumber; 

    @NotNull(message = "Roll year is null!") 
    @NotBlank(message = "Please enter roll year!") 
    @Column(name = "ROLL_YEAR", nullable = false, length = 4) 
    private String rollYear; 

    //not populated by user, no validation needed 
    @Column(name = "INDEX_NUMBER", unique = true, nullable = false, length = 20) 
private String indexNumber; 

    //for populating MK field only, no validation needed 
    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER) 
    @JoinColumn(name = "PROGRAM_FK", nullable = false) 
    private Program program; 

這是控制器:

@RequestMapping(value="/search", method = RequestMethod.POST) 
    public String postSearchStudent(
      @RequestParam(value = "mk") String programId, 
      @RequestParam(value = "rollNumber") String rollNumber, 
      @RequestParam(value = "rollYear") String rollYear, 
      @RequestParam(value = "indexNumber") String indexNumber, 
      @Valid @ModelAttribute("searchStudentAttribute") Student student, 
      BindingResult result, 
      Model model) { 

     logger.debug("Received request to search for a student"); 

     if (result.hasErrors()) { 
      model.addAttribute("programList", programService.getAll()); 
      return "searchStudent"; 
     } 
     else { 
      student = studentService.search(indexNumber); 
      // if student isn't in the db show add student page, else redirect to student page 
      if (student == null) { 
       student = new Student(); 
       student.setRollNumber(rollNumber); 
       student.setRollYear(rollYear); 
       student.setIndexNumber(indexNumber); 
       Program program = programService.get(programId); 
       student.setProgram(program); 
       model.addAttribute("student", student); 
       return "addStudent"; 
      } 
      else { 
       Integer studentId = student.getStudentId(); 
       model.addAttribute("studentId", studentId); 
       return "redirect:/essays/main/student/{studentId}"; 
      } 
     } 
    } 

這是視圖:

<c:url var="searchUrl" value="/essays/main/student/search" /> 
<form:form modelAttribute="searchStudentAttribute" method="POST" action="${searchUrl}"> 
<form:errors path="*" cssClass="errorblock" element="div" /> 

<form:label path="program">Select program (MK):</form:label> 
<form:select path="program" id="programSelect" size="8"> 
    <form:options items="${programList}" itemValue="programId" itemLabel="programDescription" />    
</form:select> 

<form:label path="mk">MK</form:label> 
<form:input path="mk" id="mkInput" size="2" maxlength="2"/> 
<form:errors path="mk" cssClass="error"/> 

<form:label path="rollNumber">Roll number</form:label> 
<form:input path="rollNumber" id="rollNumberInput" size="4"/> 
<form:errors path="rollNumber" cssClass="error"/> 

<form:label path="rollYear">Roll year</form:label> 
<form:input path="rollYear" id="rollYearInput" size="4" maxlength="4"/> 
<form:errors path="rollYear" cssClass="error"/> 

<form:label path="indexNumber" /> 
<form:hidden path="indexNumber" id="indexNumberInput" /> 

<input type="submit" value="Submit" onclick="makeIndexNumber();"/> 
</form:form> 

正如你所看到的,名字和姓氏學生與搜索無關,因爲搜索是由幾個其他屬性組合成一個你唱javaScript。但是我需要後面第一個和最後一個名字進行驗證,比如說,添加新學生,所以我不能只刪除註釋並且根本不驗證這些字段。有人可以告訴我,我應該做一個單獨的bean進行驗證只是爲了用於搜索學生,還是有其他適當的解決方案呢?

讓我更圖文:

enter image description here

當我提交表單的所有字段爲空,我得到這些錯誤。我如何告訴它在搜索完成時不考慮名字和姓氏屬性,而不刪除用於驗證的註釋?

回答

2

這是使用驗證組的好方案。爲了得到一個想法有關驗證組檢查此鏈接 -

Validation Groups

標準@​​Valid註釋仍然不支持組。所以,你可以使用Spring特定的@Validated註釋和驗證組。

@Validated

0

@NotNull註釋表明您不能將null值賦值給帶註釋的變量。我看不到你在你提供的代碼中的任何位置執行此操作,但這裏是我的想法:

當你傳遞一個對象到Spring MVC時,它創建它自己的對象表示,可用於生成jsp - 類。當您提交表單時,轉換將以另一種方式進行,它將使用set-方法重新創建原始對象。因此,當您創建新的Student時,firstNamelastName變量將爲null,這很好。然後你將它傳遞給Spring MVC,它將兩個變量值轉換爲null。但是,在提交表格後,Spring MVC試圖翻譯回去,並且確實setFirstName(null),然後就有麻煩了。

有幾種方法可以解決這種情況。

  1. 最簡單的一個,只是將它傳遞給Spring MVC之前設置firstNamelastName變量「」(空字符串)。然後它將永遠不會嘗試給它們賦值一個null值,它將是空字符串。
  2. 優雅的一個,創建一個新類StudentSearchCommand或類似的東西,它將作爲搜索對話框的後盾對象。這個類應該具有執行搜索所需的字段,所以除了名字和姓氏,除了沒有驗證外,所有的東西都有Student,也沒有JPA註釋(只是Plain Ol'Java Object(POJO))。實例化此類並將其發送到Spring MVC,並在提交表單時,從中選取值並填充Student-對象。通過這種方式,您可以超越Spring MVC對您的域類(例如「必須擁有一個setter」)的要求,並按照您的意願和想要的方式保持它們。
+0

感謝您的回答@Tobb!關於第一個建議:我還使用@NotBlank註釋了我的bean屬性,因此不要將第一個和最後一個名稱設置爲空字符串,仍然會導致「請輸入第一個/姓氏!」錯誤?關於第二個建議 - 我會盡力回覆。 –

+0

是的,它可能會。第二種解決方案可能是要走的路。有可能沒有'@ NotNull'和'@ NotBlank'註解,我以前從未使用過它們。但是如果你必須包含它們,那麼最好是完全控制這個類,並且不要將它傳遞給第三方(Spring MVC)。 – Tobb

+0

此外,您可以嘗試將其設置爲一些任意字符串,以查看錯誤消息是否消失(然後知道它實際上是由Spring MVC與對象交互引起的)。 – Tobb

相關問題