使用Spring 3 MVC處理表單驗證

本文是有關Spring 3的系列文章的一部分。該系列的早期文章是使用Spring 3 MVC的Hello World和使用Spring 3 MVC的 Handling Forms 。

現在讓我們更深入地研究Spring。 在本文中,我們將學習驗證從表單中獲取的數據。 讓我們更仔細地看一下驗證任務。

場景1 :我們可能需要驗證,例如,所提供的電子郵件確實確實看起來像一封電子郵件(以簡化的x @ xx格式顯示)。 這可以通過僅在電子郵件字段本身上運行一些腳本來完成。 那應該很簡單。 我們可以編寫一些可在瀏覽器本身上運行JavaScript。 并且還要在服務器端寫相同的驗證[為什么? 在這里閱讀 ]。 對于所有隔離的驗證都是如此,例如,檢查數據是否不為空,檢查數據是否為一定長度等。

場景2 :希望生活如此簡單。 由于我們正在討論電子郵件驗證,因此可以說其中一項驗證要求我們檢查電子郵件是否屬于某些域(例如合作伙伴組織),以便系統也可以通過電子郵件發送某些特權信息。 假設我們需要檢查電子郵件的格式為x @ partner1.com,x @ partner2.com或x@partner3.com。 可能很瑣碎,這是無法僅對表單本身的數據進行驗證的類型的示例。 無論驗證代碼是什么,它都需要知道哪些域有效。 并且此數據不存在于最終用戶以表格形式提供的數據中。 如果您稍微發揮想象力,則可以輕松地創建用例,其中可能需要業務規則引擎(例如,規則過于靈活)和/或可以引入國際化元素(例如,所有國家/地區的成年人年齡都未滿18歲) )或其他復雜性。 這些是非隔離的驗證,需要訪問同步可用的其他信息。 這些驗證可以在服務器端和客戶端都進行編碼,盡管可以說它將更多地依賴于服務器端。

場景3 :同樣,希望生活如此簡單。 如果我們處于驗證電子郵件的主題上,我們可能還需要檢查電子郵件是否有效,即它不是thisemail@doesnot.exist(我不確定該電子郵件是否存在-或在其中不存在未來-但您希望我能想到)。 我們將需要向該電子郵件ID發送一封電子郵件,并可能要求用戶單擊并確認。 我們需要通過SMTP與其他系統進行異步交互。 同樣,稍微依靠您的想象力,整個潘多拉盒子就會破裂。 很快,您將通過REST,SOAP,JMS,文件服務器進行集成,并通過分布式系統處理安全性和身份驗證問題。 我敢打賭,大多數系統都將在該領域中進行服務器端驗證,并且客戶端驗證(盡管在技術上是可行的)不會經常使用。

方案4 :而且我們還沒有違反相同的領域對象的問題,這些領域對象不僅從基于Web的表單填充,而且還從Feed文件,JMS消息等填充,因此需要將相同的驗證邏輯應用于多個渠道。 在本討論開始時,它最初是一個微不足道的小形式,帶有少量無辜的文本框,如今已演變為一個怪物。

幸運的是,JSR 303或Bean驗證[ 此處 ]可以拯救。 它立即解決了上述情況1和4。 它支持您解決方案2和3。我建議您閱讀標有“此標準對用戶有何好處?”的部分。 它會解決什么問題?” 在此鏈接 。

該Java規范于2006年提出要求,并于2009年底發布。 換句話說,可用的實現已經有機會在一年中成熟。 作為一流的開源公民,Spring 3使您可以使用此標準解決方案,而不必重新發明輪子。 而且,如果您絕對需要重新發明輪子(所有專業應用程序都需要編寫myAppSpecificKickAssValidator()),Spring也會允許這樣做。 讓我們一一看看這兩種情況。

將JSR 303支持添加到任何基于Maven的項目

JSR 303是一個開放的api。 您可以在此鏈接中找到它。 任何人都可以實現。 有hibernate和apache bval的實現。 讓我們一起進行Hibernate實現。 在此鏈接中,您可以在Maven Central看到他們的罐子。 在撰寫本文時,最新的穩定版本是4.3.0.Final。 您只需要在pom中添加此依賴項即可。 該實現也捆綁了api,因此您無需添加任何一個。

檔案:pom.xml

<properties>                                                                  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        [...]  
<hibernate.validation.version>4.3.0.Final</hibernate.validation.version>  [...]  
</properties>                                                            <!-- Hibernate validations -->  
<dependency>                                             <groupId>org.hibernate</groupId>                     <artifactId>hibernate-validator</artifactId>         <version>${hibernate.validation.version}</version>   
</dependency>

只需添加此依賴項,您就可以進入實體/表單類并聲明約束。 JSR 303有一些標準約束( 在此處列出 ),涵蓋了NotNull之類的標準檢查。 Hibernate添加了一些非標準的自定義約束[ 此處列出 ]。 它們不是標準的,但是非常方便,例如檢查有效的電子郵件。 讓我們在ContactFrm.java中介紹這兩項檢查。 如果您不知道那是從哪里來的,那么您很可能沒有閱讀本系列的上一篇文章,即使用Spring 3 MVC處理表單 。

文件:/org/academy/ui/spring3/forms/ContactFrm.java

package org.academy.ui.spring3.forms;  import javax.validation.constraints.NotNull;  import org.hibernate.validator.constraints.Email;  public class ContactFrm {  @NotNull  private String firstname;  private String lastname;  @Email  private String email;  private String telephone;  // Getter and setters omitted for brevity.   [...]  
}

單元測試

到目前為止,我們的ContactFrm bean沒有任何功能,因此我不費心進行單元測試(盡管TDD愛好者會對此表示懷疑)。 但是,現在僅通過添加幾個注釋,我們就為Bean添加了功能,并且可以進行單元測試(TDD愛好者可以從現在開始感到高興)。 讓我們添加一個單元測試。

文件:/src/test/java/org/academy/ui/spring3/forms/ContactFrmTest.java

package org.academy.ui.spring3.forms;  import static org.junit.Assert.*;  import java.util.Set;  import javax.validation.ConstraintViolation;  
import javax.validation.Validation;  
import javax.validation.Validator;  import org.junit.BeforeClass;  
import org.junit.Test;  
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  public class ContactFrmTest {  private final static Logger logger = LoggerFactory  .getLogger(ContactFrmTest.class);  private static Validator validator;  @BeforeClass  public static void init() {  validator = Validation.buildDefaultValidatorFactory().getValidator();  }  @Test  public void test() {  Set<ConstraintViolation<ContactFrm>> errors;  ContactFrm contactFrm = new ContactFrm();  errors = validator.validate(contactFrm);  printErrors(errors);  // We are expecting 1 error here.  // Just the NotNull.  assertEquals(1, errors.size());  errors.clear();  contactFrm.setFirstname("partha");  errors = validator.validate(contactFrm);  printErrors(errors);  // We are not expecting any errors here.  assertEquals(0, errors.size());  errors.clear();  contactFrm.setEmail("this can not be a valid email");  errors = validator.validate(contactFrm);  printErrors(errors);  // We are expecting 1 errors here.  assertEquals(1, errors.size());  errors.clear();  contactFrm.setEmail("this@mightbevalid.email");  errors = validator.validate(contactFrm);  printErrors(errors);  // We are not expecting any errors here.  assertEquals(0, errors.size());  errors.clear();  }  // Utility function to print out errors from validation.   private void printErrors(Set<ConstraintViolation<ContactFrm>> errors) {  if (errors.size() > 0) {  for (ConstraintViolation<ContactFrm> error : errors) {  logger.debug(error.getMessage());  }  } else {  logger.debug("There were no errors to print.");  }  }  }

您會發現我不需要使用任何Hibernate,Spring或JSR特定代碼進行單元測試。 它只是一個簡單的JUnit。 在我看來,只需添加幾個批注就可以在POJO上添加驗證,然后我可以使用標準的單元測試框架進行單元測試,而無需進行任何調整,這一事實是一個巨大的進步。 我們才剛剛開始。

單元測試–使用Spring功能。

當然,可以放心的是,我們可以在不依賴Spring的情況下完成完整的驗證和單元測試。 但是,如果我們不探索在網站上使用Spring將這些功能整合在一起有多么容易,我們將完全錯過本練習的重點。

首先,將所有必需的Spring依賴項添加到我們的項目中,并按照上一篇文章中的說明從公共記錄中刪除它們。

文件:/pom.xml

<dependency>                                           <groupId>org.springframework</groupId>             <artifactId>spring-context</artifactId>            <version>${org.springframework.version}</version>  <exclusions>                                       <exclusion>                                    <groupId>commons-logging</groupId>         <artifactId>commons-logging</artifactId>   </exclusion>                                   </exclusions>                                      
</dependency>                                          [...]  <dependency>                                           <groupId>org.springframework</groupId>             <artifactId>spring-test</artifactId>               <version>${org.springframework.version}</version>  <scope>test</scope>                                <exclusions>                                       <exclusion>                                    <groupId>commons-logging</groupId>         <artifactId>commons-logging</artifactId>   </exclusion>                                   </exclusions>                                      
</dependency>

現在, 如上一篇文章中所述,在單元測試中添加@RunWith和@ContextConfiguration魔術。

文件:/src/test/java/org/academy/ui/spring3/forms/ContactFrmTest.java

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration  
public class ContactFrmTest {  private final static Logger logger = LoggerFactory  .getLogger(ContactFrmTest.class);  @Autowired  private Validator validator;  // This is no more required as Spring does it for us.   // @BeforeClass  // public static void init() {  // validator = Validation.buildDefaultValidatorFactory().getValidator();  // }
[省略了其余代碼,因為它仍然相同。]

現在,剩下的就是讓我們告訴Spring應該在驗證器中自動裝配什么。 我們使用配置而不是代碼來做到這一點。

文件:/src/test/resources/org/academy/ui/spring3/forms/ContactFrmTest-context.xml

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  xmlns:context="http://www.springframework.org/schema/context"  xsi:schemaLocation="http://www.springframework.org/schema/beans   
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
http://www.springframework.org/schema/context   
http://www.springframework.org/schema/context/spring-context-3.0.xsd">  <bean id="validator"  class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />  
</beans>

你們都準備好了。 您現在可以使用“ mvn -e clean install”來運行整個代碼并對其進行單元測試。 如果您覺得要求太高,可以使用“ mvn -e網站”創建一個不錯HTML網站,該網站將報告代碼覆蓋率。

  • JSR 303的主頁
  • Hibernate Validator主頁
  • Hibernate Validation首席開發人員訪談– Emmanuel Bernard
  • Spring關于驗證的官方文檔

參考:我們的JCG合作伙伴 Partho在Tech for Enterprise博客上使用Spring 3 MVC處理表單驗證


翻譯自: https://www.javacodegeeks.com/2012/08/handling-forms-with-spring-3-mvc.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371853.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371853.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371853.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

當事人角色 變更映射策略引起的問題

IBeamMDAA V2版本中&#xff0c;由于變更了 當事人角色 的繼承機制&#xff0c;在添加 當事人角色時&#xff0c;為了 構建 當事人-當事人角色之間的關系&#xff0c;代碼如下&#xff1a;//if (party.PartyRoles ! null && !party.PartyRoles.Contains(sysUser))//{//…

vs xxxxx nuget配置無效

重啟vs轉載于:https://www.cnblogs.com/zinan/p/7080668.html

巡回沙龍_美浮特全國巡回沙龍第一期結束撒花!

科技美膚&#xff0c;無齡煥變。美浮特2019全國美膚巡回沙龍第一期活動圓滿結束&#xff01;優秀的小伙伴&#xff0c;雅致的茶歇環境&#xff0c;精美的甜點小食&#xff0c;理論與體驗并行的膚感測試課堂……不知道是哪一個環節給大家留下了深刻的印象呢&#xff1f;首先讓我…

Spring與網關的集成

這是有關Spring Integration系列的第二篇文章。 本文以我們介紹Spring Integration的第一篇文章為基礎。 上下文設置 在第一篇文章中&#xff0c;我們創建了一個簡單的Java應用程序&#xff0c;其中 通過頻道發送了一條消息&#xff0c; 它被服務&#xff08;即POJO&#xf…

UIAutomation識別UI元素

MS UI Automation&#xff08;Microsoft User Interface Automation&#xff1a;UIA&#xff09;是隨.net framework3.0一起發布的&#xff0c;雖然在如今這個幾乎每天都有各種新名詞、新技術出來的所謂的21世紀&#xff0c;它顯得已經有些過時了。前些日子&#xff0c;正好一個…

【C++第一個Demo】---控制臺RPG游戲3【登陸菜單樹】

【登陸系統--樹結構】 1 首先我這里設計&#xff0c;由一個基類MainMenu構建樹結構&#xff0c;并實現控制臺上菜單之間的切換和返回操作 1 #ifndef _UI_BASE_H_2 #define _UI_BASE_H_3 4 #include <string>5 #include <vector>6 #include"..//Marco.h"7…

不存在_施文忠 | ”存在“與“不存在”——巴蜀文明概論

海德格爾有句名言&#xff1a;“存在者存在&#xff0c;不存在者不存在&#xff01;”四川&#xff0c;一個偉大的存在&#xff0c;偏偏存在于四川的口頭禪卻是“不存在”。在不存在中追求存在&#xff0c;在存在中擺脫存在。六月白鹿鎮&#xff0c;書院學習了《李白與海德格爾…

Spring和JSF集成:異常處理

大多數JSF開發人員都會熟悉“發生錯誤”頁面&#xff0c;當在他們的代碼某處引發意外異常時&#xff0c;該頁面就會顯示。 該頁面在開發時確實很有用&#xff0c;但對于生產應用程序通常不是您想要的。 通常&#xff0c;在用庫存JSF替換此頁面時&#xff0c;您有兩種選擇。 您可…

Altium 原理圖出現元件“Extra Pin…in Normal of part ”警告的解決方法

轉載于&#xff1a; http://blog.csdn.net/idoming/article/details/45575627 使用Altium Designer的時候編譯完后&#xff0c;只關注過錯誤沒有關注過警告&#xff0c;現在認真排查一下有哪些警告。 正在進行的項目原理圖編譯完成后提示標題中的警告信息。經過在網上搜索&…

XidianOJ 1087 浪漫的V8

題目描述 V8為了討女朋友開心&#xff0c;給lx承包大活后面那個水塘。為了籌集資金&#xff0c;V8偷偷地溜進了一座古墓&#xff0c;發現在他面前有金光閃閃的若干小箱子&#xff0c;里面全都是金粉&#xff0c;作為橫行于各種#&#xffe5;&場所的V8來說&#xff0c;辨別不…

curl php 模擬來源_php 使用curl模擬ip和來源進行訪問的實現方法

對于限制了ip和來源的網站&#xff0c;使用正常的訪問方式是無法訪問的。本文將介紹一種方法&#xff0c;使用php的curl類實現模擬ip和來源&#xff0c;訪問那些限制了ip和來源的網站。1.設置頁面限制ip和來源訪問server.php$client_ip getip();$referer getreferer();$allow…

堆棧C語言實現

堆棧的抽象數據類型描述&#xff1a; 類型名稱&#xff1a; 堆棧&#xff08;Stack&#xff09;。數據對象集&#xff1a; 一個有 0 個或多個元素的又窮表。操作集&#xff1a; 長度為 max_size 的堆棧 S ∈ Stack&#xff0c; 堆棧元素 item ∈ ElementType。stack creatc_sta…

woocommerce 分類到菜單_Woocommerce商店顯示分類

我是wordpress的新手, 所以如果我輸入的語言錯誤, 請仍然為我提供幫助。我想使用woocommerce顯示具有可變產品的商店, 我希望商店鏈接登錄頁面顯示具有該類別特征圖像的商店類別。我當前的商店頁面顯示所有產品, 并分頁到其他產品頁面, 我找不到所有產品的模板。當我進入wp-adm…

JBoss BRMS 5.3 –添加了業務活動監視(BAM)報告

自從JBoss BRMS 5.3產品發布以來&#xff0c;添加了jBPM 5 BPM組件的最常見問題之一是業務活動監視&#xff08;BAM&#xff09;和報告功能。 本文將引導您完成添加過程&#xff0c;但是請注意&#xff0c;在撰寫本文時&#xff0c;這不是產品的受支持功能。 在JBoss BRMS 5.3上…

Zookeeper開源客戶端框架Curator簡介

Curator是Netflix開源的一套ZooKeeper客戶端框架. Netflix在使用ZooKeeper的過程中發現ZooKeeper自帶的客戶端太底層, 應用方在使用的時候需要自己處理很多事情, 于是在它的基礎上包裝了一下, 提供了一套更好用的客戶端框架. Netflix在用ZooKeeper的過程中遇到的問題, 我們也遇…

【樹形DP】 HDU 2196 Computer

題意&#xff1a;求節點間的最大距離 先DFS一次 記錄下 每一節點的子樹下的最大距離&#xff08;DP[ u ] [ 0 ]&#xff09;和第二大距離&#xff08;DP[ u ] [ 1 ]&#xff09; 用DP[ v ] [ 2 ] 表示由v的父節點來的最大距離 再取DP[ u ] [ 0 ] 與 DP[ u ][ 2 ] 的最值 #inclu…

適當的Java堆大小的5個技巧

確定生產系統合適的Java堆大小不是一件容易的事。 在我的Java EE企業經驗中&#xff0c;我發現由于Java堆容量和調整不足而導致的多個性能問題。 本文將為您提供5個技巧&#xff0c;這些技巧可以幫助您確定當前或新生產環境的最佳Java堆大小。 這些技巧中的一些對于預防和解決j…

pythondocumentation是什么_怎樣閱讀Python官方文檔

如何閱讀官方Python文檔的初學者,因為他們沒有相關的經驗,學習語言通常是費時且勞動密集型和效果不是很好。下面簡要介紹如何閱讀官方文件。一旦你學會快速查詢官方文件,學習效率會提高很多文檔門戶。如何閱讀API文檔中內容標準庫,如何快速找到你想要的。第一種方法是先查找索引…

數據庫過大無法導入

導SQL數據庫結構數據時&#xff0c;如果數據是批量插入的話會報錯&#xff1a;2006 - MySQL server has gone away。 解決辦法&#xff1a;找到你的mysql目錄下的my.ini配置文件&#xff0c;加入以下代碼 max_allowed_packet500M wait_timeout288000 interactive_timeout 2880…

UVa 11475 - Extend to Palindrome

題目&#xff1a;給你一個字符串&#xff0c;在後面拼接一部分使得它變成回文串&#xff0c;使得串最短。輸出這個回文串。分析&#xff1a;KMP&#xff0c;dp。這裡利用KMP算法將串和它的轉置匹配&#xff0c;看結束時匹配的長度就可以。 因為串比較長。使用KMP比較合適&#…