天天看點

JavaMVC架構之SpringMVC

Java語言現在應用比較多的MVC架構有SpringMVC,Struts2兩種。本章我們就來講解SpringMVC,對于本篇SpringMVC本篇不會介紹其詳細知識點及具體應用,Spring系列詳細使用和進階應用相關知識都在第四章:Spring專欄進行講解,本篇将會介紹SpringMVC的基礎相關概念,這些基礎概念是很重要的,它就如同蓋房子的基石。

歡迎檢視Java開發之上帝之眼系列教程,如果您正在為Java後端龐大的體系所困擾,如果您正在為各種繁出不窮的技術和各種架構所迷茫,那麼本系列文章将帶您窺探Java龐大的體系。本系列教程希望您能站在上帝的角度去觀察(了解)Java體系。使Java的各種後端技術在你心中子產品化;讓你在工作中能将Java各個技術了然于心;能夠即插即用。本章我們來一起了解Java的MVC架構之SpringMVC。

Java語言現在應用比較多的MVC架構有SpringMVC,Struts2兩種。本章我們就來講解SpringMVC,對于本篇SpringMVC本篇不會介紹其詳細知識點及具體應用,Spring系列詳細使用和進階應用相關知識都在第四章:Spring專欄進行講解,本篇将會介紹SpringMVC的基礎相關概念,這些基礎概念是很重要的,它就如同蓋房子的基石。本章示例源碼下載下傳

什麼是MVC?

不可免俗地我還是想在本章開始與大家一起回顧一下什麼是MVC?MVC其實就是一種軟體的設計模式。在開發中并沒有強制我們必須去遵循這種設計模式,但是遵循MVC模式會使我們系統層次更清晰;職責更明确;擴充性更強;耦合度降低。

JavaMVC架構之SpringMVC

什麼是SpringMVC?

SpringMVC就是一個嚴格遵循MVC設計模式的架構。說其是一個架構,那麼SpringMVC架構中就應該有與Model,View,Controller相對應的元件;分别是Model模型對象,視圖解析器,Controller控制器。

Spring MVC屬于SpringFrameWork的後續産品,SpringMVC對于建構WEB項目而言是可選的,如果你使用Spring架構,你可以選擇使用SpringMVC或者內建其他MVC架構。同時Spring MVC分離了控制器、模型對象、過濾器以及處理程式對象的角色,這種分離讓它們更容易進行定制。

JavaMVC架構之SpringMVC
為什麼使用SpringMVC?

  1. 學習門檻低,容易上手
  2. SpringMVC繼承了Spring架構的靈活性,容易擴充
  3. Spring将控制器,模型對象,過濾器等分離,使元件之間松耦合
  4. 支援多種視圖
  5. 輕松使用Spring生态下的其他元件

SpringMVC請求流程

JavaMVC架構之SpringMVC
  1. 使用者發起請求到DispatchServlet
  2. Handler Mapping比對請求資訊的Handler(比對條件:請求路徑,方法,header資訊)
  3. HandlerMapping向DispatchServlet傳回handler,傳回過程執行攔截器鍊(一系列攔截器Interceptor)
  4. 請求HandlerAdapter執行Handler
  5. HandlerAdapter根據Handler類型執行不同的Handler(處理器)
  6. Handler執行完畢傳回給HandlerAdapter(處理器擴充卡)ModelAndView對象
  7. HandlerAdapter将ModelAndView傳回給DispatchServlet
  8. DispatchServlet請求ViewResolver解析ModelAndView
  9. ViewResolver向DispatchServlet傳回View
  10. DispatchServlet将View和模型資料進行視圖渲染
  11. DispatchServlet向使用者響應結果

SpringMVC常用元件

前端控制器DispatcherServlet 接受請求,響應結果,相當于轉發器,中央處理器,減少了與其他元件之間的耦合度
處理器映射器HandlerMapping 根據規則查找需要執行的Handler
處理器擴充卡HandlerAdapter 根據Handler類型,尋找相應處理器執行Handler
處理器 Handler 可以實際處理請求的方法,如被@RequestMapping标注的方法
視圖解析器 ViewResolver 進行視圖解析,根據邏輯視圖名解析成真正的視圖(view)
視圖View View是一個接口,實作類支援不同的view類型(jsp,framemark,pdf…)
檔案上傳解析器MultipartResolver  用于處理上傳請求

配置SpringMVC

典型的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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">


    <!--加載資料字典-->
    <context:property-placeholder location="classpath:resource.properties"/>

    <!--配置預設的Servlet作為靜态資源的Handler-->
    <mvc:default-servlet-handler/>

    <!-- 注解驅動:作用:替我們自動配置最新版的注解的處理器映射器和處理器擴充卡-->
    <mvc:annotation-driven/>

    <!-- 配置@Controller注解掃描 -->
    <context:component-scan base-package="com.jimisun.controller"></context:component-scan>

    <!--配置InternalResourceViewResolver視圖解析器解析傳回資料-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="cache" value="false"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
        <property name="contentType" value="text/html;charset=UTF-8"/>
    </bean>

    <!--配置自定義exceptionResolver異常解析器處理異常-->
    <bean id="exceptionResolver" class="com.jimisun.exception.MyExceptionResolver"/>

    <!--配置檔案上傳-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="104857600"/>
        <property name="maxInMemorySize" value="4096"/>
        <property name="defaultEncoding" value="UTF-8"></property>
    </bean>

    <!--配置攔截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--攔截路徑規則-->
            <mvc:mapping path="/user/**"/>
            <!--排除路徑-->
            <mvc:exclude-mapping path="/user/login.html"></mvc:exclude-mapping>
            <mvc:exclude-mapping path="/user/register.html"></mvc:exclude-mapping>
            <bean id="viewLoginInterceptor" class="com.jimisun.interceptor.ViewLoginInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

</beans>      

從Servlet3.0開始,可以完全脫離XML對SpringWeb項目進行配置

/**
 * @Author:jimisun
 * @Description:
 * @Date:Created in 19:42 2018-09-28
 * @Modified By:
 */
public class MyWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {


    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{RootConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}      

SpringMVC單元測試 單元測試示例源碼下載下傳 

/**
 * @Author:jimisun
 * @Description:
 * @Date:Created in 07:58 2018-09-25
 * @Modified By:
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:SpringMvc.xml",
})
public class TestControllerTest {

    @Autowired
    private TestService testService;

    @Test
    public void sayhello() {
        String test = testService.sayHelloService("test");
        System.out.println(test);
    }
}      

驗證Web請求參數

對于Controller接收到的參數,幾乎在所有情況下我們都需要驗證,SpringMVC開發中常用的驗證方法有兩種,Spring架構定義Validator校驗和JSP-303 Bean Validation校驗。

Spring Validator參數校驗Spring Validator參數示例源碼下載下傳

@RequestMapping("sayhello")
    public void sayhello(@Validated User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            System.out.println(bindingResult.getFieldError().getDefaultMessage());
        } else {
            String s = testService.sayHelloService(user.getUsername());
            System.out.println(s);
        }      

JSP-303 Bean Validation校驗 Bean Validation校驗源碼下載下傳

Spring在3.1的時候增加了對JSP-303 Bean Validation規範的支援,不僅可以對SpringMVC進行校驗,還可以對Hibernate的對象存儲進行校驗,是一個通用的校驗架構,在開發中我們都是用JSP-303 Bean Validation進行校驗,也是個人推薦使用的。

hibernate-validator依賴

<dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>6.0.4.Final</version>
</dependency>      

相關配置

<mvc:annotation-driven validator="validator"/>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
        <property name="validationMessageSource" ref="messageSource"/>
    </bean>
    <!-- 校驗錯誤資訊配置檔案 -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <!-- 資源檔案名 -->
        <property name="basename" value="classpath:validationMessages"/>
        <!-- 對資源檔案内容緩存時間,機關秒 -->
        <property name="fileEncodings" value="GBK"/>
        <property name="defaultEncoding" value="GBK"/>
        <property name="cacheSeconds" value="120"/>
    </bean>      

在接收參數時使用@Valid進行校驗

    @RequestMapping("sayhello")

    public void sayhello(@Valid User user, BindingResult bindingResult) {

        if (bindingResult.hasErrors()) {

            System.out.println(bindingResult.getFieldError().getDefaultMessage());

        } else {

            String s = testService.sayHelloService(user.getUsername());

            System.out.println(s);

        }

    }

使用下面注解對參數進行限制

Bean Validation 中内置的 constraint

注解 作用
@Valid 被注釋的元素是一個對象,需要檢查此對象的所有字段值
@Null 被注釋的元素必須為 null
@NotNull 被注釋的元素必須不為 null
@AssertTrue 被注釋的元素必須為 true
@AssertFalse 被注釋的元素必須為 false
@Min(value) 被注釋的元素必須是一個數字,其值必須大于等于指定的最小值
@Max(value) 被注釋的元素必須是一個數字,其值必須小于等于指定的最大值
@DecimalMin(value)
@DecimalMax(value)
@Size(max, min) 被注釋的元素的大小必須在指定的範圍内
@Digits (integer, fraction) 被注釋的元素必須是一個數字,其值必須在可接受的範圍内
@Past 被注釋的元素必須是一個過去的日期
@Future 被注釋的元素必須是一個将來的日期
@Pattern(value) 被注釋的元素必須符合指定的正規表達式

Hibernate Validator 附加的 constraint

@Email 被注釋的元素必須是電子郵箱位址
@Length(min=, max=) 被注釋的字元串的大小必須在指定的範圍内
@NotEmpty 被注釋的字元串的必須非空
@Range(min=, max=) 被注釋的元素必須在合适的範圍内
@NotBlank

@URL(protocol=,

host=,    port=, 

regexp=, flags=)

被注釋的字元串必須是一個有效的url
@CreditCardNumber

被注釋的字元串必須通過Luhn校驗算法,

銀行卡,信用卡等号碼一般都用Luhn

計算合法性

Java開發之上帝之眼系列教程其他文章

  • Java開發之上帝之眼系列教程前言和章節目錄彙總
    • JavaIOC架構之Spring Framework
    • JavaORM架構之Mybatis(Ibatis)

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

勘誤&感謝

  本系列文章資料來源很多出自于網際網路和在下本身的見解,受限于個人技術能力水準和其他相關知識的限制,相關見解錯誤或者資料引用錯誤請各位幫助留言校正!引用資料多來自于網際網路,在下在引用前會遵循各位前輩或者部落客的引用說明表示感謝,但網際網路資料多是轉發再轉發或存在遺漏請原作者内信聯系指正。

雜家不如專家,精益求精

繼續閱讀