day64_SpringMVC學習筆記_02

一、springmvc對多視圖的支持

(1)導入xml格式視圖支持的jar包html

  注意:springmvc自己就支持xml格式,因此不用導入其餘支持的jar包了。前端

(2)在springmvc.xml中配置支持多視圖java

    <!-- 配置支持多視圖 -->
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <!-- 配置支持的媒體類型 -->
        <!-- spring3.2後改爲以下配置 -->
        <property name="contentNegotiationManager">
            <bean class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
                <!-- 指定多個媒體類型 -->
                <property name="mediaTypes">
                    <map>
                        <entry key="json" value="application/json"></entry>
                        <entry key="xml" value="application/xml"></entry>
                        <!-- <entry key="pdf" value="application/pdf"></entry> 須要額外的jar包 -->
                    </map>
                </property>
            </bean>
        </property>

        <!-- 指定默認的視圖 -->
        <property name="defaultViews">
            <!-- 支持多個視圖 -->
            <list>
                <!-- 對json格式視圖的支持 -->
                <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"></bean>
                <!-- 對xml格式視圖的支持,須要注入構造函數,須要一個jar包:spring-oxm-3.2.0.RELEASE.jar -->
                <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                    <constructor-arg>
                        <bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
                            <!-- 配置對哪些類進行xml轉換的支持,即綁定多個類,演示代碼中咱們只綁定了一個類 -->
                            <property name="classesToBeBound">
                                <list>
                                    <!-- 注意:須要在綁定的類中加入對xml格式視圖轉換的註解:@XmlRootElement -->
                                    <value>com.itheima.domain.User</value>
                                </list>
                            </property>
                        </bean>
                    </constructor-arg>
                </bean>
            </list>
        </property>
    </bean>

  小結:經過以上配置,模擬了WebService對多視圖的支持的功能。
(3)配置javabean,即在綁定的類User中加入對xml格式視圖轉換的註解:@XmlRootElementmysql


(4)在web.xml中配置約定訪問的url
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

(5)定義Controllerjquery

    // 多視圖支持
    // 返回的是對象,把返回的對象轉換成json格式視圖和xml格式的視圖
    @RequestMapping("multiView")
    public User multiView() {
        User user1 = new User();
        user1.setId(1);
        user1.setUsername("曉藝");
        user1.setAge("26");
        user1.setAddress("物資學院");
        user1.setBirthday(new Date());

        return user1;
    }

(6)訪問
  根據官方文檔約定:訪問的時候須要加上響應的擴展名。
  即:訪問json格式的數據,須要加上json擴展名;訪問html格式的數據,須要加上html的擴展名;訪問xml格式的數據,須要加上xml的擴展名。
  根據咱們web.xml文件的訪問約定:擴展名.do是訪問jsp頁面的。
  咱們約定rest目錄下全部以json和xml擴展名都支持相應的視圖。web

咱們訪問json格式數據的訪問形式以下:ajax


咱們訪問xml格式數據的訪問形式以下:

(7)<mvc:annotation-driven/>redis

    <mvc:annotation-driven/> 默認建立:註解處理器映射器、註解處理器適配器、並提供對json格式數據的支持。

在springmvc.xml中進行配置:spring

    <!-- 表示默認建立:處理器映射器對象、處理器映射器對象,還表示默認啓動json格式數據的支持 -->
    <mvc:annotation-driven />

可是注意:此時javaBean不能添加註解@XmlRootElement了。@XmlRootElement表示提供對xml視圖支持。sql

二、SSM整合小案例

2.0、需求

  • 實現商品查詢列表,從mysql數據庫中查詢商品信息。

2.一、使用eclipse,建立一個動態web工程並導入jar包

  • 其中Dynamic web module version版本選擇 2.5,這樣兼容性好一些;
  • Default output folder設置爲 WebRoot\WEB-INF\classes
  • Content directory設置爲 WebRoot
  • 更改JRE System Library[J2SE-1.5]爲 JRE System Library[jre1.7.0_80]
  • 刪掉沒用的庫:EAR Libraries
  • 增長服務器運行環境庫 Server Runtime,否則jsp文件會報錯。
  • 建立完項目後,將整個項目的編碼改成UTF-8。
  • 操做步驟:選中項目右鍵 --> Properties --> Resource --> Text file encoding --> Other中選擇UTF-8。
  • 對於動態的java web項目,爲了工程目錄結構的清爽,咱們將引入的jar包放到「Web App Libraries」中,能夠經過「小三角」選擇是否「Show 'Referenced Libraries' Node 」進行調節。
  • 對於普通的java項目,爲了工程目錄結構的清爽,咱們將引入的jar包放到「Referenced Libraries」中,能夠經過「小三角」選擇是否「Show 'Referenced Libraries' Node 」進行調節。

導入jar包
  包括:spring(包括springmvc)、mybatis、mybatis-spring整合包、數據庫驅動、第三方鏈接池、jstl、c3p0管理數據源、log4j、junit。
  參考:「mybatis與springmvc整合所有jar包」目錄。

本次案例共導入28個jar包。以下圖所示:

2.二、web.xml配置文件(入口)

web.xml

<?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_2_5.xsd"
    id="WebApp_ID" version="2.5">

    <display-name>day63_SpringMVC_01</display-name>

    <!-- 配置spring編碼過濾器 -->
    <filter>
        <filter-name>characterEcoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEcoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 配置前端控制器:DispatcherServlet -->
    <servlet >
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 顯示配置加載springmvc.xml文件,即配置springmvc.xml文件的初始化參數 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
    </servlet>
    <!-- 配置servlet攔截擴展名 -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    <!-- 配置servlet攔截目錄 -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

    <!-- 配置加載spring的配置文件:beans.xml -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:beans.xml</param-value> <!-- 這兩種方式都可 -->
        <!-- <param-value>/WEB-INF/classes/beans.xml</param-value> -->
    </context-param>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
</web-app>

2.三、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:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd 
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "
>

    <!-- 配置掃描,把Controller交給spring管理 -->
    <context:component-scan base-package="com.itheima"></context:component-scan>

    <!-- 表示默認建立處理器映射器對象、處理器映射器對象,還表示默認啓動json格式數據的支持 -->
    <mvc:annotation-driven />

    <!-- 配置jsp視圖解析器,InternalResourceViewResolver負責解析出真正的邏輯視圖 -->
    <!-- 後臺返回邏輯視圖:index,jsp視圖解析器解析出真正的物理視圖:前綴+邏輯視圖+後綴 ==>/WEB-INF/jsps/index.jsp -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsps/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

2.四、bean.xml配置文件(至關於applicationContext.xml)

bean.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:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd 
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "
>

    <context:component-scan base-package=""></context:component-scan>

    <!-- 一、配置數據源 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

    <!-- 二、配置sqlSessionFactory,用於生產sqlSession -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
    </bean>
    <!-- 配置mybatis的Mapper接口代理開發,須要遵循的幾點規範 -->
    <!-- 
        一、mapper接口的全限定名要和mapper映射文件的namespace的值相同。
        二、mapper接口的方法名稱要和mapper映射文件中的statement的id相同。
        三、mapper接口的方法參數只能有一個,且類型要和mapper映射文件中statement的parameterType的值保持一致。
        四、mapper接口的返回值類型要和mapper映射文件中statement的resultType的值或resultMap中的type的值保持一致。
        五、mapper接口和mapper映射文件必須在同一目錄下。
    -->

    <!-- mapper代理開發方式之批量mapper配置,默認bean的id爲類名首字母小寫 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 指定批量mapper配置的包名 -->
        <property name="basePackage" value="com.itheima.dao"></property>
        <!-- 當只有一個SqlSessionFactory時,默認是不須要配置SqlSessionFactory的 -->
        <!-- 當有多個SqlSessionFactory時,能夠指定使用的SqlSessionFactory -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>

    <!-- 三、配置事務管理 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 配置通知:管理事務的策略 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="insert*" propagation="REQUIRED"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <!-- 配置攔截service:切面編程 -->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.*.*(..))"/>
    </aop:config>
</beans>

2.六、編寫代碼

mapper層(dao層):
  mapper接口代碼使用Mybatis的逆向工程生成的。
service層:
  ItemsService.java

public interface ItemsService {

    public List<Items> findAll();

    public Items findById(Integer id);

    public void saveOrUpdate(Items items);

    public void deleteById(Integer id);

}

  ItemsServiceImpl.java

@Service
public class ItemsServiceImpl implements ItemsService {

    // 注入接口對象(Mapper接口使用代理類)
    @Resource
    private ItemsMapper itemsMapper;

    public List<Items> findAll() {
        List<Items> list = itemsMapper.findAll();
        return list;
    }

    public Items findById(Integer id) {
        Items items = itemsMapper.selectByPrimaryKey(id);
        return items;
    }

    public void saveOrUpdate(Items items) {
        itemsMapper.updateByPrimaryKey(items); // 商品id經過頁面隱藏域傳過來的
    }

    public void deleteById(Integer id) {
        itemsMapper.deleteByPrimaryKey(id);
    }

}

controller層(web層/Action層):
  ItemsController.java

@Controller
@RequestMapping("/items")
public class ItemsController {

    // 注入service對象
    @Resource
    private ItemsService itemsService;

    // 查詢全部商品方法
    @RequestMapping("list")
    // springmvc使用Model對象進行頁面數據回顯,Model對象至關於javaweb時所學的application對象(應用域對象),因此Model對象中的數據,在頁面上能夠經過EL表達式進行獲取。
    // 有了Model對象,才能夠向對象中放值,那麼Model對象該如何建立呢?
    // 答:「因爲springmvc中放到方法裏面的對象會自動被建立」,那麼咱們就把Model對象放到方法裏面。
    public String list(Model model) { 
        List<Items> itemsList = itemsService.findAll();
        model.addAttribute("itemsList", itemsList);
        return "itemsList";
    }

    // 修改商品方法
    @RequestMapping("editById")
    public String editById(Integer id, Model model) {
        // 跟據id查詢商品
        Items items = itemsService.findById(id);
        model.addAttribute("items", items);
        return "editItems";
    }

    // 修改後保存方法
    @RequestMapping("saveOrUpdate")
    public String saveOrUpdate(Items items) {
        itemsService.saveOrUpdate(items); // 商品id經過頁面隱藏域傳過來的
        return "redirect:list.do";
    }

    // 跟據id進行刪除
    @RequestMapping("deleteById")
    public String deleteById(Integer id) {
        itemsService.deleteById(id); 
        return "redirect:list.do";
    }

    // 跟據ids進行批量刪除
    @RequestMapping("deleteByIds")
    public String deleteByIds(Integer[] ids) { // 特別注意:標籤input的name的屬性值id要與方法的形式參數名稱id相同。形參名稱也能夠起別名!但須要其餘註解配合哦!
        for (Integer id : ids) {
            itemsService.deleteById(id); 
        }
        return "redirect:list.do";
    }
}

2.七、springmvc文件上傳

需求分析:
  使用ajax,響應json格式數據的形式上傳圖片並馬上回顯。頁面不刷新圖片回顯馬上。

ajax能不能提交表單?
答:ajax本身不能提交表單。要想ajax提交表單,須要藉助一個插件。

爲何咱們要提交表單?
答:由於咱們要提交一個文件對象,須要將文件對象關聯到表單裏面。
當咱們點擊一個按鈕的時候,這個被關聯到表單裏的對象,纔會被提交。

僞代碼示例以下:
    // 圖片回顯
    <img src=「圖片路徑」/>
    // 把文件關聯表單,觸發ajax事件
    <input type="file" onchange="ajax事件"/>
    <input type="hidden" value="圖片相對路徑"/>

    // 本示例開始,咱們不使用 enctype="multipart/form-data" 提交文件對象了
    // 咱們直接使用ajax提交文件對象,咱們添加隱藏域,向後臺提交圖片相對路徑

(1)導入跨服務器上傳文件的jar包、IO、fileupload

(2)模擬2臺服務器
  建立一個動態的java web項目:圖片服務器項目,圖片服務器項目的服務器和上傳圖片項目的服務器端口不一致便可。以下圖所示:

(3)springmvc支持文件上傳,須要先在springmvc.xml配置文件中開啓文件上傳
  在springmvc.xml配置文件中新加入的內容以下:

    <!-- 配置開啓文件上傳,由於咱們要跨服務器上傳,須要寫上id,該id名稱固定 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 配置文件上傳大小 -->
        <property name="maxUploadSize" value="1024000"></property>
    </bean>

(4)前臺頁面ajax
  功能:發送請求,請求上傳圖片,圖片須要被關聯在表單裏。


使用ajax提交form表單的插件:jquery.form.js

(5)後臺代碼

@Controller
@RequestMapping("/upload")
public class UploadController {

    @RequestMapping("uploadPic")
    public void uploadPic(HttpServletRequest request, String fileName, PrintWriter out) {
        // 一、準備文件上傳流
        // 因爲上傳的圖片在請求裏面,它是流類型的,直接經過Request對象不能操做
        // 因此先要把Request對象強轉成多部件請求對象
        MultipartHttpServletRequest mhr = (MultipartHttpServletRequest) request;
        // 根據文件名稱獲取普通多部件文件對象
        CommonsMultipartFile cmFile = (CommonsMultipartFile) mhr.getFile(fileName);
        // 獲取文件上傳流
        byte[] fbytes = cmFile.getBytes();

        // 二、準備文件名稱
        // 文件名稱在服務器有可能重複,咱們使用時間來區分他們
        String newFileName = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        newFileName = sdf.format(new Date());
        // 在毫秒的時候文件名也可能重複,咱們再加點鹽
        Random r = new Random(); // [0,1)
        for (int i = 0; i < 3; i++) {
            newFileName = newFileName + r.nextInt(10);
        }

        // 三、獲取文件擴展名
        String originalFilename = cmFile.getOriginalFilename();
        // int x = a.lastIndexOf(b); // 表示b字符串在a字符串中最後出現的位置,從0開始
        String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")); 

        // 四、建立jesy服務器,進行跨服務器上傳
        Client client = Client.create();
        // 把文件關聯到遠程服務器
        // 圖片文件的完整路徑爲:http://127.0.0.1:9005/day64_SSMImageServer/upload/20181027174523998.png
        WebResource resource = client.resource(Commons.PIC_HOST + "/upload/" + newFileName + suffix);
        // 上傳圖片文件
        resource.put(String.class, fbytes);

        // 五、ajax回調函數須要回顯什麼東西呢?
        // 圖片須要回顯:須要圖片的完整路徑
        // 數據庫保存圖片:須要圖片的相對路徑
        String fullPath = Commons.PIC_HOST + "/upload/" + newFileName + suffix;
        String relativePath = "/upload/" + newFileName + suffix;
        // json格式的數據:{"":"","":""}
        String result = "{\"fullPath\":\"" + fullPath + "\",\"relativePath\":\"" + relativePath + "\"}";
        out.print(result);
    }
}

(6)修改圖片服務器文件上傳權限

(7)圖片上傳位置

(8)圖片列表回顯
  回顯圖片須要使用<img/>標籤
itemsList.jsp

    <c:set var="picPath" value="http://127.0.0.1:9090/day64_SSMImageServer"></c:set>
......
    <td>
        <img id='imgSize1ImgSrc' src='${picPath}${items.pic}' height="100" width="100"/>
    </td>

editItems.jsp

    <c:set var="picPath" value="http://127.0.0.1:9090/day64_SSMImageServer"></c:set>
......
    <img id='imgSize1ImgSrc' src='${picPath}${items.pic}' height="100" width="100"/>
......

三、頁面緩存

  需求:使用頁面緩存來提升用戶體驗度。

3.一、簡單理解緩存原理

簡單理解緩存原理圖解以下:


優勢:提高性能。
缺點:不訪問數據庫,不是實時數據。
思考:怎麼樣能中和一下優缺點呢?
  • 頁面靜態化:
    • 靜態化技術連緩存都不走了,直接給你一個HTML頁面,缺點更大。
  • 分佈式緩存:
    • 分佈式緩存能控制`顆粒的大小`,分佈式緩存使用的是redis,memcached等等
    • 這至關因而數據庫,由於咱們在任何一層均可以進行操做數據庫。因此能夠進行顆粒大小的控制。

3.二、淺談互聯網架構

淺談互聯網架構圖解:

3.三、實現頁面緩存

  使用Oscache實現頁面緩存。
(1)建立一個動態的java web項目,導入所需的jar包


(2)測試:建立一個index.jsp頁面,使用時間來測試

(3)訪問測試
http://localhost:8080/day64_Oscache/index.jsp
http://localhost:8080/day64_Oscache/
  分析:上面2個地址都訪問同一個頁面,爲何緩存會變化呢?
緩存原理:
  緩存數據結構:是一個map集合。
  key存儲的是瀏覽器訪問的url,上面2個url不一致,緩存確定變化。
  value存儲的是緩存頁面的數據。
(4)緩存的存儲範圍
   緩存默認存儲在application域當中。在不一樣的瀏覽器之間訪問同一地址,緩存時間不會發生變化。
(5)改變緩存的存儲範圍
  改變緩存的存儲範圍爲session域中。在不一樣的瀏覽器之間訪問同一地址,緩存時間會發生變化。

(6)固定緩存的key

  因爲固定了緩存的key,因此如下2個地址訪問同一個頁面,緩存時間不會發生變化。
  http://localhost:8080/day64_Oscache/index.jsp
  http://localhost:8080/day64_Oscache/
(7)要求每隔4秒緩存同步(刷新)一次

(8)要求緩存持久化到磁盤或者保存到redis緩存服務器中
  建立oscache.properties,這個配置文件必須在classpath下面,文件內容以下:
oscache.properties
cache.memory=false      // 不使用緩存內存
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener    // 持久化類
cache.path=E:\\oscache  // 持久化到E盤oscache目錄下

  查看持久化文件

3.四、在SSM項目中使用Oscache

  約定:假如商品頁面訪問量特別大,咱們給商品頁面使用緩存。即:約定items路徑下全部請求都緩存。
(1)將oscache-2.4.1.jar拷貝至項目lib目錄下,並添加至構建路徑
(2)在web.xml中配置緩存過濾器


(3)測試緩存
  打一個斷點(給商品查詢列表),第一次斷點必須走,第二次斷點不走,走緩存頁面。
(4)配置緩存的持久化
  將配置文件oscache.properties拷貝至項目的config目錄下便可。

四、使用springmvc的其餘視圖

4.一、整合freemarker視圖

  • 需求:使用springmvc自己的視圖解析器來解析頁面靜態化。

(1)導入所須要的jar包
  com.springsource.freemarker-2.3.15.jar和spring-context-support-3.2.0.RELEASE.jar
(2)在springmvc.xml中配置對freemarker視圖的支持
  配置對freemarker視圖的支持後,咱們發現咱們能夠不使用jsp來開發了,咱們能夠直接使用freemarker視圖來開發。
  即:咱們能夠刪除掉在springmvc.xml中配置的jsp視圖解析器了。


(3)編寫freemarker的頁面
  WebRoot/WEB-INF/jsps/ftl.ftl

(4)編寫後臺代碼
@Controller
@RequestMapping("/ftl")
public class FtlController {

    @RequestMapping("hello")
    public String hello(Model model) {
        model.addAttribute("hello","頁面靜態化技術之freemarker");
        return "ftl";
    }
}

(5)修改itemsList.jsp頁面爲靜態化頁面itemsList.ftl
itemsList.ftl

<#assign picPath="http://127.0.0.1:9090/day64_SSMImageServer"/>
<#assign projectName="day64_SpringMVC_02"/>
<!DOCTYPE html 
    PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>查詢商品列表</title>
</head>
<body>
    <form action="${projectName}/items/deleteByIds.do" method="post">
        查詢條件:
        <table width="100%" border=1>
            <tr>
                <td><input type="submit" value="查詢"/></td>
                <td><input type="submit" value="批量刪除"/></td>
            </tr>
        </table>

        商品列表:
        <table width="100%" border=1>
            <tr>
                <td>商品ID</td>
                <td>商品名稱</td>
                <td>商品圖片</td>
                <td>商品價格</td>
                <td>生產日期</td>
                <td>商品描述</td>
                <td>操做</td>
            </tr>
            <#list itemsList as items>
                <tr>
                    <!-- 添加複選框 -->
                    <td><!-- 特別注意:標籤input的name的屬性值id要與方法的形式參數名稱id相同。 -->
                        <input type="checkbox" name="ids" value="${items.id}"><!-- 複選框中的值須要提交表單才能傳遞給後臺 -->
                    </td>
                    <td>${items.name}</td>
                    <td>
                        <img id='imgSize1ImgSrc' src='${picPath}${items.pic}' height="100" width="100"/>
                    </td>
                    <td>${items.price}</td>
                    <td>${items.detail}</td>
                    <td>
                        <a href="${projectName}/items/editById.do?id=${items.id}">修改</a>
                        <a href="${projectName}/items/deleteById.do?id=${items.id}">刪除</a>
                    </td>
                </tr>
            </#list>
        </table>
    </form>
</body>

</html>

(6)訪問測試
  訪問地址:http://localhost:8080/day64_SpringMVC_02/items/list.do
  訪問測試沒有問題,以上演示就是springmvc對freemarker的支持。

五、攔截器

定義:
  Spring Web MVC 的處理器攔截器相似於Servlet開發中的過濾器Filter,用於對處理器進行預處理和後處理。

5.一、局部攔截器

  針對某個HandlerMapping進行配置,只對當前HandlerMapping有效。即針對單個處理器映射器,稱爲局部攔截器。
在springmvc.xml中的配置示例以下:

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
        <property name="interceptors">
            <list>
                <ref bean="handlerInterceptor1"/>
                <ref bean="handlerInterceptor2"/>
            </list>
        </property>
    </bean>
    <bean id="handlerInterceptor1" class="springmvc.intercapter.HandlerInterceptor1"/>
    <bean id="handlerInterceptor2" class="springmvc.intercapter.HandlerInterceptor2"/>

攔截器代碼編寫:須要實現HandlerInterceptor接口

public class HandlerInterceptor1 implements HandlerInterceptor {

    /**
     * controller執行前調用此方法
     * 返回true表示繼續執行,返回false停止執行
     * 這裏能夠加入登陸校驗、權限攔截等
     */

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
            Object handler)
 throws Exception 
{
        return false;
    }

    /**
     * controller執行後但未返回視圖前調用此方法
     * 這裏可在返回用戶前對模型數據進行加工處理,好比這裏加入公用信息以便頁面顯示
     */

    public void postHandle(HttpServletRequest request, HttpServletResponse response, 
            Object handler, ModelAndView modelAndView)
 throws Exception 
{
    }

    /**
     * controller執行後且視圖返回後調用此方法
     * 這裏可獲得執行controller時的異常信息
     * 這裏可記錄操做日誌,資源清理等
     */

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
            Object handler, Exception ex)
 throws Exception 
{    
    }
}

5.二、全局攔截器

  攔截全部請求。
在springmvc.xml中的配置示例以下:

    <!--配置全局攔截器 -->
    <mvc:interceptors>
        <!--配置多個攔截器,順序執行 -->
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.itheima.interceptor.HandlerInterceptor1"></bean>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.itheima.interceptor.HandlerInterceptor2"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

攔截器代碼編寫:須要實現HandlerInterceptor接口
HandlerInterceptor1.java

// 攔截器代碼編寫:須要實現HandlerInterceptor接口
public class HandlerInterceptor1 implements HandlerInterceptor {

    /**
     * controller執行前調用此方法,即在處理器映射器以前執行
     * 返回true表示繼續執行,返回false停止執行
     * 這裏能夠加入登陸校驗、權限攔截等
     */

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
            Object handler
) throws Exception 
{
        System.out.println("這是第1個攔截器的preHandle()方法");
        return false;
    }

    /**
     * controller執行後但未返回視圖前調用此方法,即調用Controller了,還沒返回ModelAndView執行
     * 這裏可在返回用戶前對模型數據進行加工處理,好比這裏加入公用信息以便頁面顯示
     */

    public void postHandle(HttpServletRequest request, HttpServletResponse response, 
            Object handler, ModelAndView modelAndView
) throws Exception 
{
        System.out.println("這是第1個攔截器的postHandle()方法");
    }

    /**
     * controller執行後且視圖返回後調用此方法,即返回ModelAndView以後執行
     * 這裏可獲得執行controller時的異常信息
     * 這裏可記錄操做日誌,資源清理等
     */

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
            Object handler, Exception ex
) throws Exception 
{
        System.out.println("這是第1個攔截器的afterCompletion()方法");
    }

HandlerInterceptor2.java

// 攔截器代碼編寫:須要實現HandlerInterceptor接口
public class HandlerInterceptor2 implements HandlerInterceptor {

    /**
     * controller執行前調用此方法
     * 返回true表示繼續執行,返回false停止執行
     * 這裏能夠加入登陸校驗、權限攔截等
     */

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
            Object handler
) throws Exception 
{
        System.out.println("這是第2個攔截器的preHandle()方法");
        return false;
    }

    /**
     * controller執行後但未返回視圖前調用此方法
     * 這裏可在返回用戶前對模型數據進行加工處理,好比這裏加入公用信息以便頁面顯示
     */

    public void postHandle(HttpServletRequest request, HttpServletResponse response, 
            Object handler, ModelAndView modelAndView
) throws Exception 
{
        System.out.println("這是第2個攔截器的postHandle()方法");
    }

    /**
     * controller執行後且視圖返回後調用此方法
     * 這裏可獲得執行controller時的異常信息
     * 這裏可記錄操做日誌,資源清理等
     */

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
            Object handler, Exception ex
) throws Exception 
{
        System.out.println("這是第2個攔截器的afterCompletion()方法");
    }

5.三、測試

(1)第1個攔截器放行,第2個攔截器也放行。
  即兩個攔截器的preHandle()方法都返回true。
測試結果以下:

這是第1個攔截器的preHandle()方法
這是第2個攔截器的preHandle()方法
這是第2個攔截器的postHandle()方法
這是第1個攔截器的postHandle()方法
這是第2個攔截器的afterCompletion()方法
這是第1個攔截器的afterCompletion()方法

(2)第1個攔截器放行,第2個攔截器不放行。
  即第一個攔截器的preHandle()方法返回true,第二個攔截器的preHandle()方法返回false。
  springmvc規定:凡是方法preHandle()返回true,則方法afterCompletion()必須執行。
測試結果以下:

這是第1個攔截器的preHandle()方法
這是第2個攔截器的preHandle()方法
這是第1個攔截器的afterCompletion()方法

(3)第1個攔截器不放行,第2個攔截器不放行。
  即兩個攔截器的preHandle()方法都返回false。
測試結果以下:

這是第1個攔截器的preHandle()方法

5.四、攔截器應用:用戶身份認證

示例代碼以下:

public class LoginInterceptor implements HandlerInterceptor{

    /**
     * controller執行前調用此方法,即在處理器映射器以前執行
     * 返回true表示繼續執行,返回false停止執行
     * 這裏能夠加入登陸校驗、權限攔截等
     */

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
            Object handler)
 throws Exception 
{
        // 若是是登陸頁面則放行
        if (request.getRequestURI().indexOf("login.action") >= 0) {
            return true// 放行
        }
        HttpSession session = request.getSession();
        // 若是用戶已登陸也放行
        if (session.getAttribute("user") != null) {
            return true// 放行
        }

        // 用戶沒有登陸跳轉到登陸頁面
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
        return false// 不放行
    }

    /**
     * controller執行後但未返回視圖前調用此方法,即調用Controller了,還沒返回ModelAndView執行
     * 這裏可在返回用戶前對模型數據進行加工處理,好比這裏加入公用信息以便頁面顯示
     */

    public void postHandle(HttpServletRequest request, HttpServletResponse response, 
            Object handler, ModelAndView modelAndView)
 throws Exception 
{
    }

    /**
     * controller執行後且視圖返回後調用此方法,即返回ModelAndView以後執行
     * 這裏可獲得執行controller時的異常信息
     * 這裏可記錄操做日誌,資源清理等
     */

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
            Object handler, Exception ex)
 throws Exception 
{
    }
}

六、springmvc整合Hibernate

未完待續……

相關文章
相關標籤/搜索