springMVC框架學習-1

springMVC框架學習安排

第一天

1. MVC基本概念

在這裏插入圖片描述
由圖可見MVC架構和我們之前所學的spring和MyBatis可以完美銜接,也是web應用開發必不可少的一部分,springMVC是一個MVC設計模型的一個框架。
三層框架的執行流程:
controller接受瀏覽器的請求,調用model可以將其封裝成JavaBean對象,發送給業務層處理,業務層又可以調用持久層與數據庫交互,將返回結果發送給表現層,封裝成JSP或者其它的視圖,響應給瀏覽器。

1.springMVC的基本概述

1.什麼是springMVC
springMVC 是一種基於Java的實現MVC設計模型的請求驅動類型的輕量級Web框架,
屬於Spring FrameWork的後續產品,已經融合在Spring Web Flow裏面。
Spring框架提供了構建Web應用程序的全功能MVC模塊。使用Spring 可插入的MVC
架構,從而在使用Spring 進行WEB開發時,可以選擇使用Spring的Spring MVC 
框架或集成其他MVC開發框架,如Struts1(現在一般不用),Struts2等。

springMVC 已經成爲了主流的MVC框架之一,並且隨着spring3.0的發佈,
全面超越了struts2,成爲了最優秀的MVC框架。
它通過一套註解,讓一個簡單的Java類成爲處理請求的控制器,
並且無需實現任何接口,同時它還支持RESTful編程風格。
2. springMVC的優勢
  1. 清晰的角色劃分:
    前端控制器(DispatcherServlet)
    請求到處理器映射(HandlerMapping)
    處理器適配器(HandlerAdapter)
    視圖解析器(ViewResolver)
    處理器或頁面控制器(Controller)
    驗證器( Validator)
    命令對象(Command 請求參數綁定到的對象就叫命令對象)
    表單對象(Form Object 提供給表單展示和提交到的對象就叫表單對象)。
  2. 分工明確,而且擴展點相當靈活,可以很容易擴展,雖然幾乎不需要。
  3. 由於命令對象就是一個 POJO,無需繼承框架特定 API,可以使用命令對象直接作爲業務對象。
  4. 和 Spring 其他框架無縫集成,是其它 Web 框架所不具備的。
  5. 可適配,通過 HandlerAdapter 可以支持任意的類作爲處理器。
  6. 可定製性,HandlerMapping、ViewResolver 等能夠非常簡單的定製。
  7. 功能強大的數據驗證、格式化、綁定機制。
  8. 利用 Spring 提供的 Mock 對象能夠非常簡單的進行 Web 層單元測試。
  9. 本地化、主題的解析的支持,使我們更容易進行國際化和主題的切換。
  10. 強大的 JSP 標籤庫,使 JSP 編寫更容易。
    ………………還有比如RESTful風格的支持、簡單的文件上傳、約定大於配置的契約式編程支持、基於註解的零配
    置支持等等。
3. springMVC和struts2的區別(面試問題)
共同點:
	它們都是表現層框架,都是基於 MVC 模型編寫的。
	它們的底層都離不開原始 ServletAPI。
	它們處理請求的機制都是一個核心控制器。
區別:
	Spring MVC 的入口是 Servlet, 而 Struts2 是 Filter
	Spring MVC 是基於方法設計的,而 Struts2 是基於類,Struts2 每次執行都會創建一個動作類。所
	以 Spring MVC 會稍微比 Struts2 快些。
	Spring MVC 使用更加簡潔,同時還支持 JSR303, 處理 ajax 的請求更方便
	(JSR303 是一套 JavaBean 參數校驗的標準,它定義了很多常用的校驗註解,我們可以直接將這些注
	解加在我們 JavaBean 的屬性上面,就可以在需要校驗的時候進行校驗了。)
	Struts2 的 OGNL 表達式使頁面的開發效率相比 Spring MVC 更高些,但執行效率並沒有比 JSTL 提
	升,尤其是 struts2 的表單標籤,遠沒有 html 執行效率高。

2. springMVC的入門

  1. 入門案例需求分析
    在這裏插入圖片描述

  2. 編寫代碼

    1. 創建maven工程,選擇webapp項目
    2. pom.xml
    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.liuzeyu</groupId>
      <artifactId>day03_springMVC01_start</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
    
      <name>day03_springMVC01_start Maven Webapp</name>
      <!-- FIXME change it to the project's website -->
      <url>http://www.example.com</url>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <!--spring版本綁定-->
        <spring.version>5.0.2.RELEASE</spring.version>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>${spring.version}</version>
        </dependency>
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>servlet-api</artifactId>
          <version>2.5</version>
        </dependency>
        <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>jsp-api</artifactId>
          <version>2.0</version>
          <scope>provided</scope>
        </dependency>
    
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    
      <build>
        <finalName>day03_springMVC01_start</finalName>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
          <plugins>
            <plugin>
              <artifactId>maven-clean-plugin</artifactId>
              <version>3.1.0</version>
            </plugin>
            <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
            <plugin>
              <artifactId>maven-resources-plugin</artifactId>
              <version>3.0.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.8.0</version>
            </plugin>
            <plugin>
              <artifactId>maven-surefire-plugin</artifactId>
              <version>2.22.1</version>
            </plugin>
            <plugin>
              <artifactId>maven-war-plugin</artifactId>
              <version>3.2.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-install-plugin</artifactId>
              <version>2.5.2</version>
            </plugin>
            <plugin>
              <artifactId>maven-deploy-plugin</artifactId>
              <version>2.8.2</version>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    </project>
    
    
    1. controller控制器處理
      在這裏插入圖片描述
      添加Java和resource文件完善maven項目的目錄結構
      @RequestMapping註解的作用是用於建立請求URL處理請求方法之間的對應關係。
    2. spring配置文件
    <?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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">
    
        <!--配置創建springIOC容器時要掃描的包-->
        <context:component-scan base-package="com.liuzeyu"></context:component-scan>
    
        <!--配置視圖解析器-->
        <bean id="viewResolver"
              class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/pages/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
    
        <!--配置spring開啓註解mvc的支持-->
        <mvc:annotation-driven></mvc:annotation-driven>
    
    </beans>
    
    1. 配置servlet
    <!DOCTYPE web-app PUBLIC
     "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
     "http://java.sun.com/dtd/web-app_2_3.dtd" >
    
    <web-app>
      <display-name>Archetype Created Web Application</display-name>
    
      <!--配置servlet-->
      <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    
        <!--servlet啓動後需要加載的spring配置文件-->
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    </web-app>
    
    1. index.jsp與success.jsp
    <%@page contentType="text/html; charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>springmvc入門</title>
    </head>
    <body>
    
    <h3>入門程序</h3>
    <a href="hello">請求</a>
    </body>
    </html>
    
    <%@page contentType="text/html; charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>入門成功</title>
    </head>
    <body>
    
    <h2>springmvc入門成功</h2>
    </body>
    </html>
    
    1. springMVC執行流程
      在這裏插入圖片描述
      注意:@RequestMapping的path屬性和方法執行的return 可以不以 / 開頭,內部已經對其進行配置。
      springMVC內部執行的詳細信息
      在這裏插入圖片描述

    服務器一經啓動,DisPatcherServlet對象(前端控制器)被創建,springMVC.xml被加載,HelloMVC對象也被創建。
    當我們點擊a標籤後,帶有uri = /hello的請求被髮到了前端控制器,它會帶引這個請求去尋找處理器映射器,找到要執行的方法sayHello並返回(等下才要執行),當然前端控制器是不會執行這個方法,它會再次將這個結果發送到處理器適配器。
    處理器適配器會適配controller下任何的方法,處理器適配器又會發送到處理器這個組件進行方法的執行與返回,執行後返回ModelAndView給處理器適配器,處理器適配器又會將其返回到前端控制器,前端控制器將這個結果發送到視圖解析器ViewResolver。
    視圖解析器解析完之後又會將結果返回View前端控制器,前端控制器將View發送給View視圖組件解析,視圖將其解析成瀏覽器可以識別的出來的文件進行展示。

1. 涉及到組件

1. DispatcherServlet:前端控制器

用戶的請求到達前端控制器器後,DispatcherServlet對象它就相當於mvc模式執行流程的控制中心,它調用其它組件處理用戶的請求,前端控制器的存在降低了組件之間的耦合性。

2. HandlerMapping:處理器映射器

HandlerMapping負責根據用戶請求找到Handler,即處理器,springMVC提供了不同的映射器實現不同的映射方式。例如配置文件方式,實現接口方式,註解方式等。

3. Handler:處理器

處理器是我們開發中要編寫的具體業務控制器,由前端控制器把用戶請求發送到處理器,由處理器將用戶的請求進行業務處理。

4. HandlAdapter:處理器適配器

通過處理器適配器對處理器進行執行,這是適配器模式的應用,通過擴展適配器可以對更多類型的處理器進行執行
在這裏插入圖片描述
上圖是電腦外接顯示器的適配器,可以實現電腦連接不同的顯示屏。

5. View Resolver:視圖解析器

View Resolver解析器將處理結果生成視圖View,View Resolver首先根據邏輯視圖名解析成物理視圖名,即具體的頁面地址,再生成view視圖對象,最後對view進行渲染將處理結果以頁面展示給前端

6. View視圖器

作用就是將頁面標籤或模型數據通過頁面展示給前端,SpringMVC 框架提供了很多的 View 視圖類型的支持,包括:jstlView、freemarkerView、pdfView等。我們最常用的視圖就是 jsp。

2.< mvc:annotation-driven>說明

在springMVC的各個組件中,處理器映射器,處理器適配器,視圖解析器被稱爲springMVC的三大組件。
當在spring的配置文件中添加

    <!--配置spring開啓註解mvc的支持-->
    <mvc:annotation-driven></mvc:annotation-driven>

即默認開啓使 用RequestMappingHandlerMapping (處理映射器) 和
RequestMappingHandlerAdapter ( 處 理 適 配 器 )。

3.RequestMapping註解

查看源碼:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
    String name() default "";

    @AliasFor("path")
    String[] value() default {};

    @AliasFor("value")
    String[] path() default {};

    RequestMethod[] method() default {};

    String[] params() default {};

    String[] headers() default {};

    String[] consumes() default {};

    String[] produces() default {};
}

作用:用於建立請求 URL 和處理請求方法之間的對應關係。
作用的位置:方法上,類上。

  1. path或value屬性擁有相同的作用
    通常在實際開發中我們是類上和方法上配合使用,將xxx類模塊話,方法是細分的小模塊,賦值爲path或value屬性
    如:
    • 賬戶模塊:
      /account/add
      /account/update
      /account/delete
    • 訂單模塊:
      /order/add
      /order/update
      /order/delete
      紅色的部分就是把 RequsetMappding 寫在類上,使我們的 URL 更加精細。
      方法上:
      請求 URL 的第二級訪問目錄。

示例:

@Controller
@RequestMapping("/user")
public class HelloMVC {

    @RequestMapping(path = "hello")
    public String sayHello(){
        System.out.println("helloMVC........");
        return "success";
    }

    @RequestMapping(path = "/good")
    public String sayGood(){
        System.out.println("goodMVC........");
        return "success";
    }
}

請求的url

<a href="user/hello">請求hello</a>
<a href="user/good">請求good</a>

經測試,在 @RequestMapping不管作用在哪裏,它的path路徑,都可以不用寫 / ,但是又時候爲了閱讀方便會寫上。

  1. method:用於指定請求的方式
//	這樣配置後通過a標籤發送的get請求的將不能執行到該方法
    @RequestMapping(path = "hello",method = {RequestMethod.POST})
    public String sayHello(){
        System.out.println("helloMVC........");
        return "success";
    }
  1. params:用於指定限制請求參數的條件。它支持簡單的表達式。要求請求參數的 key 和 value 必須和配置的一模一樣。
    @RequestMapping(path = "/good",params = {"username=liuzeyu"})
    public String sayGood(){
        System.out.println("goodMVC........");
        return "success";
    }
<a href="user/good?username=liuzeyu">請求good</a>

a標籤必須配置相應的key value的請求參數和請求值,方法纔可以被執行。

  1. header:用於指定限制請求消息頭的條件,瀏覽器消息頭的請求參數必須和配置一樣方法纔可以被執行。

問題:爲什麼註解屬性只傳一個時,屬性名可以不寫

- 如果註解只有一個屬性,那麼肯定是賦值給該屬性。
- 如果註解有多個屬性,而且前提是這多個屬性都有默認值,那麼你不寫註解名賦值,會賦值給名字爲“value”這屬性。
- 如果註解有多個屬性,其中有沒有設置默認值的屬性,那麼當你不寫屬性名答進行賦值的時候,是會報錯的。

3. 請求參數的綁定

1. 請求參數綁定入門

  1. 新建控制器
@Controller
@RequestMapping("/params")
public class ParamsMVC {

    /**
     * 請求參數綁定入門
     * @return
     */
    @RequestMapping("basic")
    public String basic(String username,String password){
        System.out.println("basic..."+username+"---" +password);
        return "success";
    }
}
  1. 請求鏈接
<a href="params/basic?username=liuzeyu&password=123">請求參數綁定入門</a>

注意:請求參數一定要和方法的參數一致。

  1. 訪問127.0.0.1:8080/params/basic測試輸出
    在這裏插入圖片描述

2. 請求參數綁定實體類型

  1. 準備實體類
public class Account {

    private Integer id;
    private String name;
    private Double money;

    private User user;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                ", user=" + user +
                '}';
    }
}

public class User {
    private String uname;
    private Integer age;

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "uname='" + uname + '\'' +
                ", age=" + age +
                '}';
    }
}

  1. 編寫controller
@Controller
@RequestMapping("/params")
public class ParamsMVC {

    /**
     * 請求參數綁定實體類
     * @return
     */
    @RequestMapping("domain")
    public String domain(Account account){
        System.out.println(account);
        return "success";
    }
}
  1. jsp請求頁面
<form action="/params/domain" method="post">
    賬戶id:<input type="text" name="id"><br>
    賬戶公司:<input type="text" name="name"><br>
    賬戶金額:<input type="text" name="money"><br>
    用戶名:<input type="text" name="user.uname"><br>
    年齡:<input type="text" name="user.age"><br>
    <input type="submit" value="提交">
</form>
  1. 測試發現post方式存在參數值的中文問題
    在這裏插入圖片描述

3. 請求參數中文問題

上述的中文問題可以通過配置攔截器來解決編碼問題,在web.xml中配置

 <!--處理post請求的中文亂碼問題-->
  <filter>
    <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

就可以解決post請求的中文問題。

4. 請求參數爲集合類型

  1. 爲Account添加集合屬性,並生成getXXX和setXXX方法
    private List<User> list;
    private Map<String,User> map;
  1. jsp文件
<form action="/params/domain" method="post">
    賬戶id:<input type="text" name="id"><br>
    賬戶公司:<input type="text" name="name"><br>
    賬戶金額:<input type="text" name="money"><br>
    用戶名:<input type="text" name="list[0].uname"><br>
    年齡:<input type="text" name="list[0].age"><br>
    <br>
    用戶名:<input type="text" name="map['one'].uname"><br>
    年齡:<input type="text" name="map['one'].age"><br>
    <input type="submit" value="提交">
</form>

重點注意name屬性的寫法。

  1. 測試
    @RequestMapping("collections")
    public String collections(Account account){
        System.out.println(account);
        return "success";
    }

在這裏插入圖片描述

5. 自定義類型轉換器

  1. 爲User類添加Date birthday屬性
    private Date birthday;

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
  1. jsp文件
<form action="/params/date" method="post">
    用戶名:<input type="text" name="uname"><br>
    年齡:<input type="text" name="age"><br>
    生日:<input type="text" name="birthday"><br>
    <input type="submit" value="提交">
</form>
  1. controller層代碼
    @RequestMapping("date")
    public String stringTodata(User user){
        System.out.println(user);
        return "success";
    }
  1. 測試發現如果輸入生日格式爲2020/4/27即可以將字符串封裝成Date對象,如果輸入字符串格式爲2017-4-27,則封裝失敗
    在這裏插入圖片描述

解決方案
通過自定義類型轉換器來解決

  1. 實現spring框架核心包爲我們提供的接口converter並且編寫工具類
    在這裏插入圖片描述

    /**
     * Created by liuzeyu on 2020/4/27.
     * 實現字符串轉日期格式工具類
     */
    public class StringToDate implements Converter<String,Date>{
        @Override
        public Date convert(String s) {
            if(s == null || s.length() == 0){
                throw new RuntimeException("字符串不能爲空...");
            }
            DateFormat df = new SimpleDateFormat("yyyy-mm-dd");
            try {
                Date date = df.parse(s);
                return date;
            } catch (ParseException e) {
                throw new RuntimeException("日期轉換失敗...");
            }
    
        }
    }
    
    
  2. spring配置文件中配置,爲核心包中添加一個工具類

     <!--配置自定義類型轉換器-->
        <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <set>
                    <bean class="com.liuzeyu.utils.StringToDate"></bean>
                </set>
            </property>
        </bean>
    
    
        <!--配置spring開啓註解mvc的支持-->
        <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
    
    1. 重新測試日期格式爲2020-4-27
      在這裏插入圖片描述

6. web層使用原生的servlet-api對象

  1. jsp文件
<form action="/params/servlet" method="post">
    用戶名:<input type="text" name="username"><br>
    密碼:<input type="text" name="password"><br>
    <input type="submit" value="提交">
</form>
  1. 編寫controller代碼,只需要在參數中定義請求和響應的對象即可
    /**
     * 測試使用原生的servlet對象
     * @return
     */
    @RequestMapping("servlet")
    public String servlet(HttpServletRequest request, HttpServletResponse response){
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username +":"+password);
        return "success";
    }
  1. 測試結果
    在這裏插入圖片描述

4. springMVC常用的註解

1. @RequestParam

作用:把請求中的指定參數名稱給控制器參數賦值
屬性

  1. value:請求參數名稱
  2. required:請求參數中是否提供該參數,默認是true表示必須提供,如果不提供將報錯。

使用實例:

<a href="anno/requestParam?username=liuzeyu">註解@RequestParam</a>
    @RequestMapping("requestParam")
    public String testRequestParam(@RequestParam(value = "username") String name,
                                   @RequestParam(value = "age",required = false) Integer age){
        System.out.println(name);
        return "success";
    }

其中age參數,發送請求時可以不用發送age,但必須發送?username=xxx

2. @RequestBody

**作用:**獲取請求體的內容,直接使用得到的時key=xxx&value=yyy。get請求方式不適用
屬性:
required:是否必須有請求體,默認爲true,當爲true時,get請求會報錯。當請求爲false時,get獲取到的爲null
使用實例:

<form action="anno/requestBody" method="post">
    用戶名:<input type="text" name="username"><br>
    密碼:<input type="text" name="password"><br>
    <input type="submit" value="提交">
</form>
<br>
<%--@RequestBody不適用於get請求--%>
<a href="anno/requestBody?username=liuzeyu&&password=80">註解@RequestBody</a>
    @RequestMapping("requestBody")
    public String testRequestBody(@RequestBody String body){
        System.out.println(body);
        return "success";
    }
3. @PathVariable

引出REST編碼風格

什麼是 rest:
REST(英文:Representational State Transfer,簡稱 REST)描述了一個架構樣式的網絡系統,
比如 web 應用程序。它首次出現在 2000 年 Roy Fielding 的博士論文中,他是 HTTP 規範的主要編寫者之
一。在目前主流的三種 Web 服務交互方案中,REST 相比於 SOAP(Simple Object Access protocol,簡單
對象訪問協議)以及 XML-RPC 更加簡單明瞭,無論是對 URL 的處理還是對 Payload 的編碼,REST 都傾向於用更
加簡單輕量的方法設計和實現。值得注意的是 REST 並沒有一個明確的標準,而更像是一種設計的風格。
它本身並沒有什麼實用性,其核心價值在於如何設計出符合 REST 風格的網絡接口。
restful 的優點
它結構清晰、符合標準、易於理解、擴展方便,所以正得到越來越多網站的採用。
restful 的特性:
資源(Resources):網絡上的一個實體,或者說是網絡上的一個具體信息。
它可以是一段文本、一張圖片、一首歌曲、一種服務,總之就是一個具體的存在。可以用一個 URI(統一
資源定位符)指向它,每種資源對應一個特定的 URI 。要
獲取這個資源,訪問它的 URI 就可以,因此 URI 即爲每一個資源的獨一無二的識別符。
表現層(Representation):把資源具體呈現出來的形式,叫做它的表現層 (Representation)。
比如,文本可以用 txt 格式表現,也可以用 HTML 格式、XML 格式、JSON 格式表現,甚至可以採用二
進制格式。
狀態轉化(State Transfer):每 發出一個請求,就代表了客戶端和服務器的一次交互過程。
HTTP 協議,是一個無狀態協議,即所有的狀態都保存在服務器端。因此,如果客戶端想要操作服務器,
必須通過某種手段,讓服務器端發生“狀態轉化”(State Transfer)。而這種轉化是建立在表現層之上的,所以
就是 “表現層狀態轉化”。具體說,就是 HTTP 協議裏面,四個表示操作方式的動詞:GET 、POST 、PUT、
DELETE。它們分別對應四種基本操作:GET 用來獲取資源,POST 用來新建資源,PUT 用來更新資源,DELETE 用來
刪除資源。
restful 的示例:
/account/1 HTTP GET : 得到 id = 1 的 account
/account/1 HTTP DELETE: 刪除 id = 1 的 account
/account/1 HTTP PUT: 更新 id = 1 的 account 
/account HTTP POST: 新增 account

在這裏插入圖片描述
作用:用於綁定url中的佔位符,例如url中的/delete/{id},這個{id}就是佔位符
屬性

  1. value:用於指定url的佔位符名稱
  2. required:是否必須提供佔位符

使用示例:

<a href="anno/pathVariable/10">註解@PathVariable</a>
    @RequestMapping("pathVariable/{id}")
    public String testPathVariable(@PathVariable Integer id){
        System.out.println(id);   //10
        return "success";
    }

在這裏插入圖片描述

4. @RequestHeader

作用:用戶獲取請求消息頭
屬性

  1. value:提供消息頭名稱
  2. required:是否必須有此消息頭

:實際開發中並不常用。

示例:

<a href="anno/requestHeader">註解@RequestHeader</a>
    @RequestMapping("requestHeader")
    public String testRequestHeader(@RequestHeader(value = "User-Agent") String header,
                                    @RequestHeader(value = "date",required = false) String date){
        System.out.println(header);
        System.out.println(date);
        return "success";
    }

輸出:(date並不包含在請求頭中)
在這裏插入圖片描述

5. @CookieValue

作用:用於把指定的cookie名稱值傳入控制器的方法參數
屬性

  1. value:提供指定的cookie名稱
  2. required:是否必須有此cookie
<a href="anno/cookieValue">註解@CookieValue</a>
    @RequestMapping("cookieValue")
    public String testCookieValue(@CookieValue(value = "JSESSIONID",required = false) String cookieValue){
        System.out.println(cookieValue);
        return "success";
    }

輸出:
在這裏插入圖片描述

6. @ModelAttribute

作用:該註解是springMVC 4.3之後加入的,它可以用於修飾方法和參數
屬性
value:用於獲取數據的key,key可以是POJO的屬性名稱,也可以是map結構的key。
應用場景:當表單提交數據不是完整的實體類數據時,保證沒有提交的數據可以使用數據庫原來的數據。
例如:
我們在更新一個用戶的數據時,用戶有一個字段是不允許被修改的,我們提交表單也沒有該字段。該字段從數據庫中獲取的,於是我們可以先從數據庫中獲取到,之後更新到新增的到用戶。
示例1:ModelAttribute 修飾方法不帶返回值

<form action="anno/modelAttribute2" method="post">
    用戶名:<input type="text" name="uname"><br>
    密碼:<input type="text" name="age"><br>
    <input type="submit" value="提交">
</form>
    @RequestMapping("modelAttribute2")
    public String testModelAttribute2(User user){
        System.out.println("testModelAttribute2.....");
        System.out.println(user);
        return "success";
    }
    @ModelAttribute
    public User showUser2(String username){
        System.out.println("showUser2.....");
        User user = new User();
        user.setUname(username);
        user.setAge(99999);
        user.setBirthday(new Date());
        return user;
    }

在這裏插入圖片描述
輸出:
在這裏插入圖片描述
示例2:ModelAttribute 修飾方法帶返回值
基於Map

<form action="anno/modelAttribute1" method="post">
    用戶名:<input type="text" name="uname"><br>
    密碼:<input type="text" name="age"><br>
    <input type="submit" value="提交">
</form>
  /**
     * 註解@ModelAttribute:基於map
     * @param user
     * @return
     */
    @RequestMapping("modelAttribute1")
    public String testModelAttribute1(@ModelAttribute(value = "one") User user){
        System.out.println("testModelAttribute1.....");
        System.out.println(user);
        return "success";
    }
    //會比testModelAttribute先執行
    @ModelAttribute
    public void showUser1(String username,Map<String,User> map){
        System.out.println("showUser1.....");
        User user = new User();
        user.setUname(username);
        user.setAge(9999);
        user.setBirthday(new Date());
        map.put("one",user);
    }

在這裏插入圖片描述
輸出:
在這裏插入圖片描述

7. @SessionAttribute
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章