@ModelAttribute詳解

標(biāo)簽(空格分隔): SpringMVC


@ModelAttribute使用大致有有兩種,一種是是直接標(biāo)記在方法上,一種是標(biāo)記在方法的參數(shù)中,兩種標(biāo)記方法產(chǎn)生的效果也各不相同,這里就列舉下兩種標(biāo)記所產(chǎn)生的效果

首先先做點簡單的準(zhǔn)備工作,寫一個只包含一個button的jsp頁面,這里可以看見,只是寫了個簡單按鈕事件,跳轉(zhuǎn)的modelTest.do這個路徑

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
    <script type="text/javascript" src="<%=basePath%>static/js/jquery.min.js"></script>
  </head>
  <script type="text/javascript">
        $(function(){
            $("#modelTest").on("click",function(){

                window.location.href="<%=basePath%>model/modelTest.do";
            })
        });
  </script>
  <body>

    <input type="button" id="modelTest" value="測試">


  </body>
</html>

注解標(biāo)記在方法上

下面,再讓我們寫一個controller控制器,這里我們再控制器中寫兩個方法,其中一個使用@RequestMapping方法路徑標(biāo)記為modelTest.do,另外一個方法不標(biāo)記路徑,使用@ModelAttribute標(biāo)記

package com.lovo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping(value="model")
public class ModelAttributeTest {

    @ModelAttribute
    public void init()
    {
        System.out.println("最先執(zhí)行的方法");
    }

    @ModelAttribute
    public void init02()
    {
        System.out.println("最先執(zhí)行的方法02");
    }

    @RequestMapping(value="modelTest.do")
    public String modelTest()
    {
        System.out.println("然后執(zhí)行的方法");
        return "modelTest";
    }

    @ModelAttribute
    public void init03()
    {
        System.out.println("最先執(zhí)行的方法03");
    }
}

部署后運(yùn)行,點擊頁面測試按鈕,查看控制臺輸出,這個時候你會發(fā)現(xiàn),后臺控制器并沒有直接進(jìn)入modelTest.do的路徑,而是先執(zhí)行了被@ModelAttribute標(biāo)記的init方法。應(yīng)該這么理解,當(dāng)同一個controller中有任意一個方法被@ModelAttribute注解標(biāo)記,頁面請求只要進(jìn)入這個控制器,不管請求那個方法,均會先執(zhí)行被@ModelAttribute標(biāo)記的方法,所以我們可以用@ModelAttribute注解的方法做一些初始化操作。當(dāng)同一個controller中有多個方法被@ModelAttribute注解標(biāo)記,所有被@ModelAttribute標(biāo)記的方法均會被執(zhí)行,按先后順序執(zhí)行,然后再進(jìn)入請求的方法。

此處輸入圖片的描述
此處輸入圖片的描述

下面方法做一些變形,變形為帶有參數(shù)的返回,這樣也是實際開發(fā)中經(jīng)常會操作的
首先像創(chuàng)建個pojo對象,對象包含userName,sex兩個屬性。并對JSP及控制器代碼做一些修改

頁面使用EL表達(dá)式接受返回參數(shù)

 <script type="text/javascript">
        $(function(){
            $("#modelTest").on("click",function(){

                window.location.href="<%=basePath%>model/modelTest.do";
            })
        });
  </script>
    <body>
    <input type="button" id="modelTest" value="測試">
    <input type="text" value="${pojo.userName }">
    <input type="text" value="${pojo.sex }">
  </body>

@ModelAtterbute方法無返回值情況

@Controller
@RequestMapping(value="model")
public class ModelAttributeTest {

    @ModelAttribute
    public void init(Model mode)
    {
        PojoTest pojo=new PojoTest(null, "小明", "男");
        mode.addAttribute("pojo", pojo);
    }

    @RequestMapping(value="modelTest.do")
    public String modelTest()
    {
        return "modelTest";
    }

}

訪問ModelTest.jsp頁面并點擊測試

此處輸入圖片的描述
此處輸入圖片的描述

出現(xiàn)如下結(jié)果

此處輸入圖片的描述
此處輸入圖片的描述

從執(zhí)行結(jié)果看出,當(dāng)訪問請求時,會首先訪問init方法,然后再對test方法進(jìn)行訪問,并且是同一個請求,因為model模型數(shù)據(jù)的作用域與request相同,所以可以用此標(biāo)記直接標(biāo)記在方法上對實際要訪問的方法進(jìn)行一些初始化操作

@ModelAttribute標(biāo)記方法有返回值

@Controller
@RequestMapping(value="model")
public class ModelAttributeTest {

    @ModelAttribute
    public String init(Model mode)
    {
        System.out.println("進(jìn)入init方法");
        PojoTest pojo=new PojoTest(null, "小明", "男");
        mode.addAttribute("pojo", pojo);
        return "model/befor.do";
    }

    @RequestMapping(value="befor.do")
    public String befor(){

        System.out.println("進(jìn)入befor方法");
        return "index";

    }

    @RequestMapping(value="modelTest.do")
    public String modelTest()
    {
        System.out.println("進(jìn)入modelTest方法");
        return "modelTest";
    }

}

這里稍微做了點變形,可以看到在被@ModelAttribute方法中設(shè)值了返回路徑為befor方法,但是在在代碼運(yùn)行的過程中并不會跳轉(zhuǎn)befor方法,而是在代碼執(zhí)行完成return之前直接跳轉(zhuǎn)了實際請求的方法。

@ModelAttribute標(biāo)記在參數(shù)前

從from表單或url地址中取值,這里就以url地址為例,為了避免url地址中文亂碼問題,這里調(diào)用了encodeURL函數(shù)

<script type="text/javascript">
        $(function(){
            $("#modelTest").on("click",function(){

                window.location.href="<%=basePath%>model/modelTest.do?userName="+encodeURI('小明')+"&sex="+encodeURI('男');
            })
        });
  </script>
  <body>

    <input type="button" id="modelTest" value="測試">
    <input type="text" value="${pojo.userName }">
    <input type="text" value="${pojo.sex }">

  </body>
@Controller
@RequestMapping(value="model")
public class ModelAttributeTest {

    @RequestMapping(value="modelTest.do")
    public String modelTest(@ModelAttribute("pojo") PojoTest pojo) 
    {
        try {
            pojo.setUserName(new String(pojo.getUserName().getBytes("iso-8859-1"),"utf-8"));
            pojo.setSex(new String(pojo.getSex().getBytes("iso-8859-1"),"utf-8"));
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(pojo);
        return "modelTest";
    }

}

點擊頁面測試,頁面文本框會顯示URL地址傳遞過來的參數(shù),因為SpringMVC會自動匹匹配頁面?zhèn)鬟f過來的參數(shù)的name屬性和后臺控制器中的方法中的參數(shù)名,如果參數(shù)名相同,會自動匹配,如果控制器中方法是封裝的bean,會自動匹配bean中的屬性,其實這種取值方式不需要用@ModelAttribute注解,只要滿足匹配要求,也能拿得到值

此處輸入圖片的描述
此處輸入圖片的描述

從model對象中取值

@Controller
@RequestMapping(value="model")
public class ModelAttributeTest {

    @ModelAttribute("pojo")
    public PojoTest init( PojoTest pojo)
    {
        pojo.setSex("男");
        return pojo;

    }

    @RequestMapping(value="modelTest.do")
    public String modelTest(@ModelAttribute("pojo") PojoTest pojo) 
    {
        pojo.setUserName("小明");
        return "modelTest";
    }

}

點擊測試發(fā)現(xiàn),modelTest拿到inint方法中的pojo對象,合并兩次set的參數(shù)后返回頁面

此處輸入圖片的描述
此處輸入圖片的描述
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容