1. 程式人生 > >Spring MVC程式碼例項系列-03:@PathVariable、@RequestHeader、@RequestParam、@RequestBody、@ModelAttribute等

Spring MVC程式碼例項系列-03:@PathVariable、@RequestHeader、@RequestParam、@RequestBody、@ModelAttribute等

超級通道 :Spring MVC程式碼例項系列-緒論
本章主要進行請求引數相關注解的例項編碼,涉及到的技術有:
- @PathVariable:用於構建Restful風格的GET請求URL
- @RequestHeader:用於獲取http請求的header部分資訊
- @RequestParam:用於獲取簡單資料型別的引數如StringList<Integer>
- @RequestBody:將傳入的JSON字串獲取XML轉化成POJO,如MyUser等。
- @ResponseBody:將返回的POJO物件轉化成JSON字串或者XML。一般與@RequestBody搭配。
- @SessionAttribute:用於設定和獲取session作用域的資料
- @ModelAttribute:用於設定類作用域的資料和傳參
- Spring MVC 靜態資原始檔載入方式

1.目錄結構

src
\---main
    \---java
    |   \---pers
    |       \---hanchao
    |           \---hespringmvc
    |               \---requestannotation
    |                   \---RequestAnnotationController.java
    |                   \---User.java
    \---webapp
        \---requestannotation
        |
\---pathvariable.jsp | \---requestheader.jsp | \---requestparam.jsp | \---sessionattribute.jsp | \---modelattribute.jsp \---static | \---query-3.2.1.min.js \---WEB-INF | \---spring-mvc-servlet.xml | \---web.xml \
---index.jsp

2.Spring MVC載入靜態資原始檔

兩種方式:
1. 使用mvc:default-servlet-handler
2. 通過mvc:resources指定靜態資源

具體看程式碼:spring-mvc-servlet.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/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
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--開啟component註解自動掃描-->
    <context:component-scan base-package="pers.hanchao.*"/>

    <!-- Spring MVC預設的註解對映的支援 :提供Controller請求轉發,json自動轉換等功能-->
    <mvc:annotation-driven />

    <!--開啟註解:提供spring容器的一些註解-->
    <context:annotation-config/>

    <!--靜態資源處理方式一:使用mvc:default-servlet-handler,
    default-servlet-name="所使用的Web伺服器預設使用的Servlet名稱",一般情況下為"default" -->
    <!--<mvc:default-servlet-handler default-servlet-name="default"/>-->

    <!--靜態資源處理方式二:通過mvc:resources指定靜態資源-->
    <!--所有URI為"/static/**"的資源都從"/static/"裡查詢,這些靜態資源快取1年(即 : 31536000秒)-->
    <mvc:resources mapping="/static/**" location="/static/" cache-period="31536000"/>

    <!--檢視解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

[email protected]例項

@PathVariable例項:用來構成restful風格的URL請求的一種方式,只適合GET請求

3.1.RequestAnnotationController.java

package pers.hanchao.hespringmvc.requestannotation;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;

/**
 * <p>引數請求相關注解例項</p>
 * @author hanchao 2018/1/14 18:09
 **/
@Controller
@RequestMapping("/requestannotation")
public class RequestAnnotationController {
    /**
     * <p>@PathVariable例項:用來構成restful風格的URL請求的一種方式,只適合GET請求</p>
     * @author hanchao 2018/1/14 0:43
     **/
    @GetMapping("/getpathvariable/{name}/time/{time}")
    public String getPathVariable(@PathVariable String name,@PathVariable String time,Model model){
        model.addAttribute("name",name);
        model.addAttribute("time",time);
        return "/requestannotation/pathvariable";
    }
}

3.2.requestheader.jsp

<%--
  Created by IntelliJ IDEA.
  User: hanchao
  Date: 2018/1/14
  Time: 0:54
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>@RequestHeader</title>
</head>
<body>
    <h4>Accept:${accept}</h4>
    <h4>Accept-Encoding:${encoding}</h4>
    <h4>Accept-Language:${language}</h4>
    <h4>Connection:${alive}</h4>
    <h4>Cookie:${cookie}</h4>
    <h4>Host:${host}</h4>
    <h4>Referer:${referer}</h4>
    <h4>Upgrade-Insecure-Requests:${upgrade}</h4>
    <h4>User-Agent:${agent}</h4>
</body>
</html>

3.3.index.jsp

<%--@PathVariable例項--%>
<a href="/requestannotation/getpathvariable/張三/time/昨天">@PathVariable例項 : /requestannotation/getpathvariable/張三/time/昨天</a><hr/>

3.4.result

這裡寫圖片描述

[email protected]

@RequestHeader例項:用來獲取Header資訊,GET和POST都可以

4.1.RequestAnnotationController.java

package pers.hanchao.hespringmvc.requestannotation;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;

/**
 * <p>引數請求相關注解例項</p>
 * @author hanchao 2018/1/14 18:09
 **/
@Controller
@RequestMapping("/requestannotation")
public class RequestAnnotationController {
    /**
     * <p>@RequestHeader例項:用來獲取Header資訊,GET和POST都可以</p>
     * @author hanchao 2018/1/14 0:52
     **/
    @GetMapping("/requestheader")
    public String getRequestHeader(@RequestHeader("Accept") String accept,
                                   @RequestHeader("Accept-Encoding") String encoding,
                                   @RequestHeader("Accept-Language") String language,
                                   @RequestHeader("Connection") String alive,
                                   @RequestHeader("Cookie") String cookie,
                                   @RequestHeader("Host") String host,
                                   @RequestHeader("Referer") String referer,
                                   @RequestHeader("Upgrade-Insecure-Requests") String upgrade,
                                   @RequestHeader("User-Agent") String agent,
                                   Model model){
        model.addAttribute("accept",accept);
        model.addAttribute("encoding",encoding);
        model.addAttribute("language",language);
        model.addAttribute("alive",alive);
        model.addAttribute("cookie",cookie);
        model.addAttribute("host",host);
        model.addAttribute("referer",referer);
        model.addAttribute("upgrade",upgrade);
        model.addAttribute("agent",agent);
        return "/requestannotation/requestheader";
    }
}

4.2.requestheader.jsp

<%--
  Created by IntelliJ IDEA.
  User: hanchao
  Date: 2018/1/14
  Time: 0:54
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>@RequestHeader</title>
</head>
<body>
    <h4>Accept:${accept}</h4>
    <h4>Accept-Encoding:${encoding}</h4>
    <h4>Accept-Language:${language}</h4>
    <h4>Connection:${alive}</h4>
    <h4>Cookie:${cookie}</h4>
    <h4>Host:${host}</h4>
    <h4>Referer:${referer}</h4>
    <h4>Upgrade-Insecure-Requests:${upgrade}</h4>
    <h4>User-Agent:${agent}</h4>
</body>
</html>

4.3.index.jsp

<%--@RequestHeader例項--%>
<a href="/requestannotation/requestheader">@RequestHeader例項</a><hr/>

4.4.result

這裡寫圖片描述

[email protected]例項

  • @RequestParam只能用來處理Content-Type: 為 application/x-www-form-urlencoded編碼的內容。
  • @RequestParam可以理解為Request.getParameter()。
  • 由於GET請求的queryString的值和POST請求中的body data的值都會被轉化到Request.getParameter()中,所以#RequestParam可以獲取到這些值。
  • @RequestParam常用於獲取簡單型別的資料,如StringList<String>等。

5.1.RequestAnnotationController.java

package pers.hanchao.hespringmvc.requestannotation;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;

/**
 * <p>引數請求相關注解例項</p>
 * @author hanchao 2018/1/14 18:09
 **/
@Controller
@RequestMapping("/requestannotation")
public class RequestAnnotationController {
/**
     * <p>@RequestParam例項。@RequestParam可以理解為獲取Request.getParameter()的引數。
     * 由於get方式中queryString的值,和post方式中body data的值都會被Servlet接受到並轉化到
     * Request.getParameter()中,所以@RequestParam可以獲取到。</p>
     * <p>@RequestParam只能用來處理Content-Type: 為 application/x-www-form-urlencoded編碼的內容。</p>
     * @author hanchao 2018/1/14 1:07
     **/
    @GetMapping("/getrequestparam")
    public String getRequestParam(@RequestParam String getname,Model model){
        model.addAttribute("getname",getname);
        return "/requestannotation/requestparam";
    }

    /**
     * <p>@RequestParam例項:GET和POST都可以,常用來處理簡單型別,如String,List<String>等</>。</p>
     * <p>@RequestParam只能用來處理Content-Type: 為 application/x-www-form-urlencoded編碼的內容。</p>
     * @author hanchao 2018/1/14 1:11
     **/
    @PostMapping("/postrequestparam")
    public String postRequestParam(@RequestParam String postname,Model model){
        model.addAttribute("postname",postname);
        return "/requestannotation/requestparam";
    }
}

5.2.requestparam.jsp

<%--
  Created by IntelliJ IDEA.
  User: hanchao
  Date: 2018/1/14
  Time: 1:16
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>@RequestParam</title>
</head>
<body>
<h3>getRequestParam:${getname}</h3>
<h3>postRequestParam:${postname}</h3>
</body>
</html>

5.3.index.jsp

<%[email protected]例項--%>
<a href="/requestannotation/getrequestparam?getname=張三">@RequestParam[GET]例項 : /requestannotation/getrequestparam?getname=張三</a><br>
<form action="/requestannotation/postrequestparam" method="post">
    <input value="李四" name="postname">
    <input type="submit" value="@RequestParam[POST]例項"/>
</form><hr/>

5.4.result

這裡寫圖片描述

[email protected]例項

  • @RequestBody例項常用來處理Content-Type不是application/x-www-form-urlencoded編碼的內容,例如application/json, application/xml等。
  • @RequestBody適合處理POJO型別的資料傳參
  • @RequestBody,在傳參時會將JSON字串轉化為POJO物件
  • 在返回值時,會將POJO物件轉化成JSON字串,這個實現需要@ResponseBody註解的幫助。
  • 所以pom.xml中需要加入jackson相關jar包。

6.1.RequestAnnotationController.java

package pers.hanchao.hespringmvc.requestannotation;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;

/**
 * <p>引數請求相關注解例項</p>
 * @author hanchao 2018/1/14 18:09
 **/
@Controller
@RequestMapping("/requestannotation")
public class RequestAnnotationController {
    /**
     * <p>@RequestBody例項:只能POST,常用來處理bean型別,該註解常用來處理Content-Type:
     * 不是application/x-www-form-urlencoded編碼的內容,例如application/json, application/xml等。
     * @RequestBody 適合處理Json型別的傳參,@ResponseBody將物件以Json的形式返回給前臺
     * </p>
     * @author hanchao 2018/1/14 1:25
     **/
    @PostMapping("/requestbody")
    @ResponseBody
    public User postRequestBody(@RequestBody User user){
        return user;
    }
}

6.2.index.jsp

<%[email protected]例項--%>
<input type="button" onclick="requestbody()" value="@RequestBody[POST]例項"/>
<input type="text" id="requestbody" class="text"/>
<hr/>
</body>
<script type="text/javascript" src="static/jquery-3.2.1.min.js"></script>

<script type="text/javascript">
    //@RequestBody例項:必須指定contentType:application/json
    function requestbody() {
        $.ajax({
            type:"POST",
            url:"/requestannotation/requestbody",
            data:JSON.stringify(
                {name:"張三",sex:"男"}
            ),
            contentType:"application/json; charset=utf-8",
            success:function (data) {
                console.log(data);
                $("#requestbody").val(data.name + "是" + data.sex + "的");
            }
        });
    }
</script>
</html>

6.3.result

這裡寫圖片描述

[email protected]例項

@SessionAttributes,用於設定和獲取session基本的資料。

7.1.RequestAnnotationController.java

package pers.hanchao.hespringmvc.requestannotation;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;

/**
 * <p>引數請求相關注解例項</p>
 * @author hanchao 2018/1/14 18:09
 **/
@Controller
@RequestMapping("/requestannotation")
//@SessionAttributes,將"session"的作用於設定為session級別的
@SessionAttributes(value = {"session"})
public class RequestAnnotationController {
    /**
     * <p>設定session</p>
     * @author hanchao 2018/1/14 18:09
     **/
    @GetMapping("/setsession")
    public String setSession(Model model){
        System.out.println("set session");
        model.addAttribute("session","Here is a session!");
        model.addAttribute("request","Here is a request!");
        return "redirect:/index.jsp";
    }

    /**
     * <p>@SessionAttribute:指定獲取的資料為session級別</p>
     * @author hanchao 2018/1/14 18:10
     **/
    @GetMapping("/getsession")
    public String getSession(){
        return "/requestannotation/sessionattribute";
    }

    /**
     * <p>@SessionAttribute:通過SessionStatus.setComplete()清除session作用域的值</p>
     * @author hanchao 2018/1/15 22:10
     **/
    @GetMapping("/delsession")
    public String delSession(SessionStatus sessionStatus){
        sessionStatus.setComplete();
        return "redirect:/index.jsp";
    }
}

7.2.sessionattribute.jsp

<%--
  Created by IntelliJ IDEA.
  User: hanchao
  Date: 2018/1/14
  Time: 2:15
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>@SessionAttribute</title>
</head>
<body>
<h3>requestScope.request : ${requestScope.request}</h3>
<h3>sessionScope.session : ${sessionScope.session}</h3>
</body>
</html>

7.3.index.jsp

<%[email protected]例項--%>
<a href="/requestannotation/setsession">@SessionAttribute例項[set]</a><br>
<a href="/requestannotation/getsession">@SessionAttribute例項[get]</a><br>
<a href="/requestannotation/delsession">@SessionAttribute例項[del]</a><br><hr/>

7.4.result

這裡寫圖片描述

[email protected]例項

@ModelAttribute主要有前兩種用法(對我來說):
1. 註解在方法上:在執行每個業務方法前,執行這些被@ModelAttribute註解的類,提取設定好ModelAndView裡的Model屬性。
2. 註解在方法引數上:輔助傳參,可以不加。
3. 註解在方法的返回值上…

8.1.RequestAnnotationController.java

package pers.hanchao.hespringmvc.requestannotation;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.support.SessionStatus;

/**
 * <p>引數請求相關注解例項</p>
 * @author hanchao 2018/1/14 18:09
 **/
@Controller
@RequestMapping("/requestannotation")
public class RequestAnnotationController {
    /**
     * <p>@ModelAttribute 註解在void返回值的方法時,將一些值注入到ModelAndView中。</p>
     * <p>@ModelAttribute 註解的方法,將會在當前類的其他方法執行前被執行。</p>
     * @author hanchao 2018/1/15 21:28
     */
    @ModelAttribute
    public void setSimpleAttribute(Model model){
        model.addAttribute("voidmethod","將一些值注入到ModelAndView中");
    }

    /**
     * <p>@ModelAttribute 以預設方式,註解在非void返回值的方法時,將通過返回值的型別的小寫格式,注入方法返回的值,
     * 如當前方法相當於model.addAttribute("user",user);</p>
     * <p>@ModelAttribute 註解的方法,將會在當前類的其他方法執行前被執行。</p>
     * @author hanchao 2018/1/15 21:28
     **/
    @ModelAttribute
    public User setDefaultBeanAttribute(){
        User user = new User("message","以返回型別的小寫格式為預設key,設定物件資料到Model中");
        return user;
    }

    /**
     * <p>@ModelAttribute 以指定方式,註解在非void返回值的方法時,將通過指定的key,注入方法返回的值,
     * 如當前方法相當於model.addAttribute("useruser",user);</p>
     * <p>@ModelAttribute 註解的方法,將會在當前類的其他方法執行前被執行。</p>
     * @author hanchao 2018/1/15 21:34
     **/
    @ModelAttribute("methoduser")
    public User setBeanAttribute(){
        User user = new User("message","以指定的key,設定物件資料到Model中");
        return user;
    }

    ///@ModelAttribute和@RequestMapping一起使用的方式未寫例項,因為不常用也不建議用
    //    @ModelAttribute
    //    @RequestMapping("/getxxx")
    //    public String getxxx(){}

    ///@ModelAttribute註釋返回型別的用法未寫例項,因為不常用也不建議用
    //    @RequestMapping
    //    public @ModelAttribute("uuuu") User getUser(){}

    /**
     * <p>@ModelAttribute例項:從請求中獲取資料(不傳也可以)</p>
     * @author hanchao 2018/1/15 21:53
     **/
    @GetMapping("/getmodelattribute")
    public String getUser(@ModelAttribute User user,@ModelAttribute("user2") User user2, Model model){
        model.addAttribute("parammeteruser",user);
        model.addAttribute("parammeteruser2",user2);
        return "/requestannotation/modelattribute";
    }
}

8.2.modelattribute.jsp

<%--
  Created by IntelliJ IDEA.
  User: hanchao
  Date: 2018/1/15
  Time: 21:46
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>@ModelAttribute</title>
</head>
<body>
    <h3>@ModelAttribute     註解在void f()上:   ${voidmethod}</h3>
    <h3>@ModelAttribute     註解在Object f()上: ${user.sex}</h3>
    <h3>@ModelAttribute(...)註解在Object f()上: ${methoduser.sex}</h3>
    <h3>@ModelAttribute     註解在方法引數上:    ${parammeteruser.sex}</h3>
    <h3>@ModelAttribute     註解在方法引數上:    ${parammeteruser2.sex}</h3>
</body>
</html>

8.3.index.jsp

<%--@ModelAttribute例項--%>
<a href="/requestannotation/getmodelattribute?name=張三&sex=傳參,會覆蓋預設的ModelAttribut">@ModelAttribute[GET]例項</a><br>

8.4.result

這裡寫圖片描述