SpringMvc示例一:快速搭建springMVC應用

先來上一張SpringMVC處理請求全過程。

這裏寫圖片描述

該圖來自:http://jinnianshilongnian.iteye.com/blog/1594806
清晰的展示了從請求以響應spring在中間都做了些什麼事情,感覺畫得好就先放在這裏了。

1、新建項目:myframework;

2、添加spring框架依賴jar包,爲了簡單我這裏把所有依賴包都添加了到WEB-INF\lib目錄下,另外還要添加一個三方包commons-logging-api-1.1.jar。準備工作完成,

3、在web.xml中添加DispatchServlet,內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>myframework</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>dispatch</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 初始化參數 -->
        <init-param>
            <!-- 指明servlet配置文件位置,spring將從此位置載入spring容器 -->
            <param-name>contextConfigLocation</param-name>
            <param-value>  
                /WEB-INF/classes/dispatch-servlet*.*  
            </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- 配置DispatcherServlet所需要攔截的 url -->
    <servlet-mapping>
        <servlet-name>dispatch</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
</web-app>

load-on-startup:表示啓動容器時初始化該Servlet;
init-param:指明瞭dispatch這個servlet配置文件位置爲: /WEB-INF/classes/dispatch-servlet*.* ,非必須的配置。
url-pattern:表示哪些請求交給Spring Web MVC處理, “/” 是用來定義默認servlet映射的。也可以如“.html”表示攔截所有以html爲擴展名的請求,這裏將攔截所有以.do接尾的請求。

自此請求已交給Spring Web MVC框架處理,我們還需要配置Spring的配置文件,若不配置init-param指定配置文件位置,將從默認位置WEB-INF/[DispatcherServlet的Servlet名字]-servlet.xml,加載配置文件。這裏我指定了文件位置,所以將會從/WEB-INF/classes/dispatch-servlet*.* 加載。注意這裏多加了一層classess目錄

4、配置dispatch-servlet.xml,我的dispatch-servlet.xml源文件位置在src目錄下,編譯後文件位置在WEB-INF\classess目錄下。內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd  
                http://www.springframework.org/schema/aop  
                http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 配置SpringMVC的視圖渲染器, 讓其前綴爲:/ 後綴爲.jsp 將視圖渲染到/page/<method返回值>.jsp中 -->
    <beans:bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver"
        p:prefix="/pages/" p:suffix=".jsp">
    </beans:bean>
</beans:beans>  

5、創建Controller。

package com.ldz.demo.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class HelloController implements Controller {

    @Override
    public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
        // 創建模型跟視圖,用於渲染頁面。並且指定要返回的頁面爲hello頁面,結合dispatch-servlet.xml中的配置,可知道最終返回頁面爲:/pages/hello.jsp
        ModelAndView mav = new ModelAndView("hello");
        return mav;
    }
}

進入一下步,將Controller類註冊到dispatch-servlet.xml中,讓spring容器進行管理。
6、在dispatch-servlet.xml中添加配置

<!--這裏必須以.do接尾,否則報404錯誤,因爲web.xml中配置了spring只攔截.do接尾的請求-->
<beans:bean name="/hello.do" class="com.ldz.demo.controller.HelloController" />

至此,springMVC基本架子已經搭建好了。發佈到tomcat中,啓動應用,訪問:
http://localhost:8080/myframework/hello.do

應用目錄結構圖
這裏寫圖片描述

一點說明:
仔細點可以看到dispatch-servlet.xml中每個結點都有<beans前綴。這樣的寫法不太符合平時的習慣,如果改成下面寫法如何呢?

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd  
                http://www.springframework.org/schema/aop  
                http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- SpringMVC配置 -->

    <!-- 通過component-scan 讓Spring掃描org.swinglife.controller下的所有的類,讓Spring的代碼註解生效 -->
    <!-- <context:component-scan base-package="com.ldz.demo.controller"></context:component-scan> -->
    <!-- 配置SpringMVC的視圖渲染器, 讓其前綴爲:/ 後綴爲.jsp 將視圖渲染到/page/<method返回值>.jsp中 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver"
        p:prefix="/pages/" p:suffix=".jsp">
    </bean>
    <bean name="/hello.do" class="com.ldz.demo.controller.HelloController" />
</beans>  

去掉前綴後,啓動時就報錯了,提示找不到<beans的定義 ,那肯定就是引用的schema有問題,對比和以前項目文件後發現

<beans:beans xmlns="http://www.springframework.org/schema/mvc"

修改爲下面schema後,就不需要beans前綴,而且也能正常啓動了。

<beans xmlns="http://www.springframework.org/schema/beans"

Controller實現方式

實現一個Controller有很多種方式,特別在spring2.5以後支持註解後,大大的減化了xml配置的繁所工作。
出於學習目的先來了解2.5之前實現Controller的方法。
第一種,上文中提到的,從Controller類繼承,只需要實現下面個方法就行了。

public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception;

實現代碼

@Override
public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
// 創建模型跟視圖,用於渲染頁面。並且指定要返回的頁面爲home頁面
ModelAndView mav = new ModelAndView(“hello”);
mav.addObject(“desc”, “HelloController!”);
return mav;
}

在dispatch-servlet.xml配置控件器

<bean name="/hello.do" class="com.ldz.demo.controller.HelloController" />

第二種,從AbstractController繼承
實現代碼

@Override
protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
// 創建模型跟視圖,用於渲染頁面。並且指定要返回的頁面爲home頁面
ModelAndView mav = new ModelAndView(“hello”);
mav.addObject(“message”, “HiAbstractController!,這是一個從AbstractController繼承的Controller”);
return mav;
}

在dispatch-servlet.xml配置控件器,

<bean name="/hi.do" class="com.ldz.demo.controller.HiAbstractController" />

響應方式

  • 返回ModelAndView或直接通過response寫響應。像ajax請求時,不需要返回頁面視圖時,就通過response寫響應,之後直接return null;告訴DispatchServlet已經自己返回數據,不需要進行視圖渲染。
    代碼實現:

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
    // 創建模型跟視圖,用於渲染頁面。並且指定要返回的頁面爲home頁面
    arg1.setHeader(“Content-type”, “text/html;charset=UTF-8”);
    //這句話的意思,是告訴servlet用UTF-8轉碼,而不是用默認的ISO8859
    arg1.setCharacterEncoding(“UTF-8”);
    arg1.getWriter().write(“這句話是直接在Controller裏面直接返回頁面的!!”);
    // 如果想直接在該處理器/控制器寫響應 可以通過返回null告訴DispatcherServlet自己已經寫出響應了,不需要它進行視圖解析
    return null;
    }

  • 在寫響應之前,設置了響應頭和字符編碼,如果不寫的話返回內容亂碼。而且要寫在方法最前面。對於編碼設置,肯定有比這個現簡單有效的辦法,編碼問題留到以後再來講。

繼承AbstractController其他可用參數設置

繼承至AbstractController的控件器有以下屬性可設置,繼承至Controller的控制器沒有這些屬性。

1.強制請求方法類型,強制指定客戶端請求時使用GET或POST請求類型,如登錄、註冊類請求強制使用POST方式提交數據。
在dispatch-servlet.xml中controller設置以下參數:

<bean name="/hi.do" class="com.ldz.demo.controller.HelloController">
<property name="supportedMethods" value="POST"></property>
</bean>

2.當前請求的session前置條件檢查,如果當前請求無session將拋出HttpSessionRequiredException異常:

<bean name="/hi.do" class="com.ldz.demo.controller.HelloController">
<property name="requireSession" value="true"/>
</bean>

3.客戶端端緩存控制

<bean name="/hi.do" class="com.ldz.demo.controller.HelloController">
<!-- value>0,數字表示緩存秒數 ,value=0:表示不緩存,value<0表示響應頭什麼緩存信息都不加。-->
<property name="cacheSeconds" value="5" />
</bean>

請求效果圖,第一次從服務器返回,緊接第二次Size列顯示(form cache)。說明是從緩存中獲取請求數據。
這裏寫圖片描述
這裏寫圖片描述
注:下面提到一些關於緩存控制的一些特殊情況:
- 1. 對於一般的頁面跳轉(如超鏈接點擊跳轉、通過js調用window.open打開新頁面都是會使用瀏覽器緩存的,在未過期情況下會直接使用瀏覽器緩存的副本,在未過期情況下一次請求也不發送);
- 2.對於刷新頁面(如按F5鍵刷新),會再次發送一次請求到服務器;

4.Last-Modified緩存機制
在繼承AbstractController類基礎上再實現LastModified接口即可。

public long getLastModified(HttpServletRequest request) {
if(lastModified == 0L) {
//TODO 此處更新的條件:如果內容有更新,應該重新返回內容最新修改的時間戳
lastModified = System.currentTimeMillis();
}
return lastModified;
}

發佈了37 篇原創文章 · 獲贊 0 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章