領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多我很高興地看到在最近一項來自zeroturnaround的調查中,Spring MVC被評為Java最受歡迎的Web框架。
這個框架非常靈活,有幾十種使用方法。與所有具有許多選項的靈活框架一樣,討論常見實踐非常重要。
我為這篇部落格文章建立的專案使用了許多Spring MVC應用程式中常見的特性。您會發現類似這樣的內容
在控制器中,您會發現典型的Spring MVC特性,用於對映請求、透過註解提取請求資料、資料繫結、檔案上傳……
另一方面,在JSP內部,大多數HTML是原生編寫的(而不是由Spring MVC標籤生成的)。此外,Spring MVC標籤庫不生成任何Javascript程式碼。
我們首先討論如何將Spring MVC與jQuery和Bean Validation整合。然後我們將看看如何使這些JSP不那麼冗長。
public class DiningForm {
@Pattern(regexp="\\d{16}")
private String creditCardNumber;
@Size(1)
private String merchantNumber;
@Min(0)
private double monetaryAmount;
@NotNull
private Date date;
...
}
當呼叫驗證時,將根據上述註解驗證DiningForm的一個例項。
從Spring 3.0開始,Spring MVC集成了Bean Validation的驗證規則(這不是使用Spring @MVC進行驗證的唯一方法,但它顯然正在成為最常見的方法)。
在控制器方法中,我們可以像這樣使用@Valid
@RequestMapping(value="/update", method=RequestMethod.POST)
public String update(@Valid DiningForm diningForm, BindingResult result) {
if (result.hasErrors()) {
return “rewards/edit”;
}
// continue on success...
}
}
在JSP級別,可以使用<form:errors />顯示錯誤訊息。
<form:form modelAttribute="diningForm">
<form:input path="firstName"/>
<form:errors path="firstName"/>
…
</form:form>
上面的程式碼相當簡單且執行良好。但它不生成任何Javascript。因此它不允許部分渲染或客戶端驗證。讓我們看看如何改進!
在前面的例子中,每次提交表單時都會重新整理整個頁面。這是HTML響應的摘錄
我們的目標是最小化響應大小。我們應該能夠得到這樣的響應(使用json語法)
{"status":"FAIL","result":[{"fieldName":"firstName","message":"firstName may not be empty"}]}
首先,我們將使用jQuery表單提交來驗證表單。當表單被認為是有效時,將使用常規HTML表單提交觸發表單提交(這樣我們就可以重定向到不同的頁面)。
讓我們首先建立一個簡單的ValidationResponse類,如下所示
public class ValidationResponse {
private String status;
private List errorMessageList;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public List getErrorMessageList() {
return this.errorMessageList;
}
public void setErrorMessageList(List errorMessageList) {
this.errorMessageList = errorMessageList;
}
}
在控制器類中,我們可以新增一個action方法
@RequestMapping(value="/user.json")
public @ResponseBody ValidationResponse processForm (Model model, @Valid User user, BindingResult result ) {
ValidationResponse res = new ValidationResponse();
if(!result.hasErrors()){
res.setStatus("SUCCESS");
}
// …
return res;
}
多虧了@ResponseBody註解,返回的物件將如以下圖所示轉換為JSON
在JSP內部,錯誤訊息被解析並在適當的時候顯示。您可以瀏覽Javascript程式碼以獲取更多詳細資訊。
根據漸進增強的最佳實踐,所有Javascript程式碼都已放置在HTML表單之外。如果客戶端瀏覽器停用了Javascript,表單將回退到全頁面重新整理。
現在我們已經為驗證規則實現了部分重新整理,還有2點需要改進
<html:form modelAttribute="user" id="add-user-form" formUrl="/userAjaxCustomTag.htm">
<html:inputField name="firstName" label="Enter your first name:" />
<html:inputField name="lastName" label="Enter your last name:" />
<div>
<button type="submit">Save changes</button>
<button type="reset">Cancel</button>
</div>
</html:form>
自定義標籤是Java EE的一部分,在Apache Tomcat上也執行良好。建立一個自定義標籤出奇地容易。讓我們以表單輸入欄位為例。我們目前使用這種語法(8行)
<div id="firstName">
<label>Enter your first name:</label>
<div>
<form:input path="firstName" />
<span>
<form:errors path="firstName" />
</span>
</div>
</div>
我們的目標是改用這個(1行)
<html:inputField name="firstName" label="Enter your first name:" />
在WEB-INF資料夾中,我可以像這樣建立一個新的標籤檔案
其內容如下
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ attribute name="name" required="true" rtexprvalue="true" %>
<%@ attribute name="label" required="true" rtexprvalue="true" %>
<div id="${name}">
<label>${label}</label>
<div>
<form:input path="${name}"/>
<span><form:errors path="${name}"/></span>
</div>
回到userForm.jsp中,我只需要宣告標籤資料夾
<%@ taglib prefix="html" tagdir="/WEB-INF/tags/html" %>
我可以使用這個新建立的標籤,如下所示
<html:inputField name="firstName" label="Enter your first name:" />
自定義標籤與Eclipse/STS完美整合,我甚至可以使用程式碼自動完成功能:
以類似的方式,我還可以將JavaScript程式碼外部化到一個標籤中,這樣我只需要一行程式碼即可呼叫
<ajax:formPartialRefresh validateUrl="/userAjaxBootstrap.json" formName="add-user-form"/>
歡迎您檢視github上的相應示例應用程式。
鳴謝:感謝我的朋友Nicholas Ding,他與我一起為這篇部落格文章構建了程式碼示例。