主頁 > 後端開發 > SpringMVC01_入門案例

SpringMVC01_入門案例

2020-10-07 16:09:19 後端開發

本教程原始碼請訪問:tutorial_demo

一、MVC模型和三層架構

1.1、MVC模型

MVC的全程是Model View Controller,是模型(Model)-視圖(View)-控制器(Controller)的縮寫,是一種用于設計創建Web應用程式的模式 ,每個部分有專門的功能:

Model(模型):指的就是我們的資料模型,一般情況下用于封裝資料,

View(視圖):用于展示資料,包括我們之前學習的JSP和HTML,也就是用戶“看得到”的內容,

Controller(控制器):處理用戶互動的部分,可以認為是我們之前學習的Servlet,用來控制頁面跳轉,把特定的頁面展示給用戶,

這是傳統的開發方式,在此基礎上通過迭代,出現了JavaWeb經典的三層架構,

1.2、三層架構

我們的開發架構一般都是基于兩種形式,一種是C/S(客戶端/服務器)架構,另一種是B/S(瀏覽器/服務器)架構,在JavaWeb開發中,幾乎全都是基于B/S架構的開發,那么在B/S架構中,通過不斷迭代,出現了經典的三層架構,包括:表現層、業務層、持久層,三層架構在實際開發中使用的非常多,接下來我們看一下每一層都負責哪些方面:

表現層

  • 也被稱為Web層;
  • 負責接收客戶端請求,向客戶端回應結果,通常客戶端使用http協議請求web層, web需要接收http請求,完成http回應;
  • 表現層包括展示層和控制層:控制層負責接收請求,展示層負責結果的展示;
  • 表現層依賴業務層,接收到客戶端請求一般會呼叫業務層進行業務處理,并將處理結果回應給客戶端;
  • 表現層的設計一般都使用MVC模型,MVC是表現層的設計模型,和其他層沒有關系,

業務層

  • 也被稱為Service層;
  • 負責業務邏輯處理,和我們開發專案的需求息息相關 ;
  • web層依賴業務層,但是業務層不依賴web層;
  • 業務層在業務處理時可能會依賴持久層,如果要對資料持久化需要保證事務一致性,

持久層

  • 也被稱為Dao層;
  • 包括資料庫和資料訪問層,資料庫是對資料進行持久化的載體,資料訪問層是業務層和持久層互動的介面;
  • 業務層需要通過資料訪問層將資料持久化到資料庫中;
  • 通俗的講,持久層就是和資料庫互動,對資料庫表進行增刪改查的,

二、SpringMVC概述

2.1、SpringMVC是什么

SpringMVC是一種基于Java的實作MVC設計模型的請求驅動型別的輕量級Web框架,屬于Spring FrameWork的后續產品,已經融合在 Spring里面,Spring框架提供了構建Web應用程式的全功能MVC模塊,使用Spring可插入的MVC架構,從而在使用Spring進行WEB開發時,可以選擇使用Spring的Spring MVC框架,

SpringMVC已經成為目前最主流的MVC框架之一,并且隨著Spring3.0的發布,全面超越Struts2,成為最優秀的MVC框架,它通過一套注解,讓一個簡單的Java類成為處理請求的控制器,而無須實作任何介面,同時它還支持RESTful編程風格的請求,

2.2、SpringMVC在三層架構的位置

SpringMVC框架處于表現層,負責接收請求,向瀏覽器回應,以及和業務層互動;

Spring框架貫穿整個三層架構,通過IOC和DI對Bean及其屬性進行管理,同時進行事務控制;

MyBatis處于持久層,與資料庫進行互動,

2.3、SpringMVC和Struts2比較

共同點

  • 都是表現層框架,基于MVC模型撰寫;
  • 底層都是基于ServletAPI;
  • 處理請求都要通過一個核心的控制器,

區別

  • Spring MVC的入口是Servlet,Struts2是Filter;
  • Spring MVC是基于方法設計的,而Struts2是基于類,Struts2每次執行都會創建一個動作類,所以Spring MVC會稍微比Struts2快些;
  • Spring MVC 使用更加簡潔,同時還支持JSR303,處理ajax的請求更方便;
  • Struts2的OGNL運算式使頁面的開發效率相比Spring MVC更高些,但執行效率并沒有比JSTL提升,尤其是Struts2的表單標簽,遠沒有html執行效率高,

三、SpringMVC入門

3.1、入門案例

3.1.1、創建工程

在idea中從原型創建Maven工程,選擇org.apache.maven.archetypes:maven-archetype-webapp,在pom.xml中添加如下的坐標:

<dependency>
	<groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.2.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.6.RELEASE</version>
</dependency>
<!-- Servlet -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>
<!-- JSP -->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.0</version>
    <scope>provided</scope>
</dependency>

這里注意,由于我們這個是JavaWeb專案,一定要添加Servlet和JSP的坐標,

3.1.2、在專案中創建存放原始碼和組態檔的目錄

在src/main目錄下創建java和resources兩個目錄,java目錄用來存放Java原始碼,resources用來存放組態檔,這樣創建的目錄是普通目錄,編譯時不能被正確識別,此時還需要進行如下操作:

  1. 在java目錄上右鍵-->Make Directory as-->Sources root;
  2. 在resources目錄上右鍵-->Make Directory as-->Resources Root;

以后的教程里面,只要涉及到Maven的Java Web工程,都要這樣做,

3.1.3、撰寫SpringMVC的組態檔

在resources目錄下新建springmvc.xml,

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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">
    <!-- 配置spring創建容器時要掃描的包 -->
    <context:component-scan base-package="org.codeaction"></context:component-scan>
    <!-- 配置視圖決議器 -->
    <bean id="viewResolver"
          >
        <property name="prefix" value="https://www.cnblogs.com/WEB-INF/pages/"></property>
        <property name="suffix" value="https://www.cnblogs.com/codeaction/p/.jsp"></property>
    </bean>
    <!-- 配置spring開啟注解mvc的支持-->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>

3.1.4、配置核心控制器

在web.xml中配置

<!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>
  <!-- SpringMVC的核心控制器 -->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 配置Servlet的初始化引數,讀取springmvc的組態檔,創建spring容器 -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!-- 配置servlet啟動時加載物件 -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

3.1.5、撰寫控制器類

package org.codeaction.controller;

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

@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String hello() {
        System.out.println("hello...");
        return "success";
    }
}

3.1.6、撰寫相關頁面

index.jsp,在webapp目錄下

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<body>
	<h2>Hello World!</h2>
	<a href="https://www.cnblogs.com/codeaction/p/${pageContext.request.contextPath}/hello">to hello</a>
</body>
</html>

這里有一個超鏈接,用來訪問控制器類,

在WEB-INF目錄下創建pages目錄,撰寫success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>success</title>
</head>
<body>
    Hello World!
</body>
</html>

3.1.7、啟動tomcat服務器測驗

在idea中配置tomcat服務器,運行,

在地址欄輸入http://localhost:8080/start/index.jsp,點擊彈出頁面中的超鏈接,頁面顯示Hello World!

3.2、SpringMVC運行流程及原理分析

3.2.1、入門案例執行流程

  1. 當啟動Tomcat服務器的時候,因為配置了load-on-startup標簽,所以會創建DispatcherServlet物件,就會加載springmvc.xml組態檔;
  2. 開啟了注解掃描,那么HelloController物件就會被創建 ;
  3. 從index.jsp發送請求,請求會先到達核心控制器DispatcherServlet,根據配置@RequestMapping注解找到執行的具體方法;
  4. 根據執行方法的回傳值,再根據配置的視圖決議器,去指定的目錄下查找指定名稱的JSP檔案;
  5. Tomcat服務器渲染頁面,做出回應,

3.2.2、SpringMVC請求回應流程(掌握)

由入門案例執行流程,這里詳細的說一下SpringMVC請求回應流程:

  1. 用戶發送請求至核心控制器DispatcherServlet;
  2. .核心控制器DispatcherServlet收到請求呼叫處理器映射器HandlerMapping;
  3. 處理器映射器根據請求url找到具體的處理器,生成處理器執行鏈HandlerExecutionChain(包括處理器物件和處理器攔截器)一并回傳給DispatcherServlet;
  4. DispatcherServlet根據處理器Handler獲取處理器配接器HandlerAdapter執行HandlerAdapter處理一系列的操作,如:引數封裝,資料格式轉換,資料驗證等操作;
  5. 執行處理器Handler(Controller,也叫頁面控制器);
  6. Handler執行完成回傳ModelAndView;
  7. HandlerAdapter將Handler執行結果ModelAndView回傳到DispatcherServlet;
  8. DispatcherServlet將ModelAndView傳給ViewReslover視圖決議器;
  9. ViewReslover決議后回傳具體View;
  10. DispatcherServlet對View進行渲染視圖(即將模型資料model填充至視圖中);
  11. DispatcherServlet回應用戶,

3.3、RequestMapping注解

作用:建立請求URL和處理方法之間的對應關系;

出現位置

  • 類上,設定第一級訪問目錄
  • 方法上,第二級訪問目錄
  • 路徑可以不撰寫/表示應用的根目錄開始
package org.codeaction.controller;

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

@Controller
@RequestMapping("/hello")
public class HelloController {
    //@RequestMapping("/hello")
    @RequestMapping("/hello")
    public String hello() {
        System.out.println("hello...");
        return "success";
    }
}

此時頁面上訪問hello方法時,超鏈接需要這樣寫href="https://www.cnblogs.com/codeaction/p/${pageContext.request.contextPaht}/hello/hello"

屬性

  • path,指定請求路徑的url;
  • value,和path作用相同;
  • method,指定請求方式(get,post,put,delete);
  • params,指定限制請求引數的條件;
  • headers,發送請求中必須包含的請求頭,

四、請求引數系結

4.1、什么是請求引數系結

表單提交的資料都是key=value格式,SpringMVC的引數系結程序是把表單提交的請求引數,作為控制器中方法的引數進行系結,

4.2、支持的資料型別及使用要求

基本型別引數:包括基本資料型別和String型別,要求我們的引數名稱必須和控制器中方法的形參名稱保持一致(嚴格區分大小寫,也可以不一致,后面RequestParam注解會講到不一樣的情況),

POJO型別引數:包括各種物體類,以及物體類中的物體類,要求表單中引數名稱和 POJO 類的屬性名稱保持一致,并且控制器方法的引數型別是 POJO 型別,

陣列和集合型別引數:包括 List 結構和 Map 結構的集合(包括陣列),這里涉及兩種方式:1.要求集合型別的請求引數必須在POJO中,在表單中請求引數名稱要和POJO中集合屬性名稱相同,給List集合中的元素賦值,使用下標,給Map集合中的元素賦值,使用鍵值對,2.接收的請求引數是json格式資料,需要借助一個注解實作,

4.3、請求引數系結示例

4.3.1、新建控制器類

package org.codeaction.controller;

import org.codeaction.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ParamController {
    //測驗系結基本型別引數
    @RequestMapping("/testParam")
    public String testParam(String username, Float money) {
        System.out.println(username);
        System.out.println(money);
        return "success";
    }

    //測驗系結POJO型別引數
    @RequestMapping("/testParamPOJO")
    public String testParamPOJO(User user) {
        System.out.println(user.getName());
        System.out.println(user.getAge());
        System.out.println(user.getBirthday());
        System.out.println(user.getList());
        System.out.println(user.getMap());
        return "success";
    }
}

4.3.2、新建頁面

param.jsp,在webapp目錄下

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<body>
    <h2>Param test</h2>

    <p>測驗系結基本型別引數</p>
    <form action="${pageContext.request.contextPath}/testParam" method="post">
        用戶名:<input type="text" name="username" /><br/>
        余額:<input type="text" name="money" /><br/>
        <button type="submit">提交</button>
    </form>

    <p>測驗系結POJO型別引數</p>
    <form action="${pageContext.request.contextPath}/testParamPOJO" method="post">
        姓名:<input type="text" name="name" /><br/>
        年齡:<input type="text" name="age" /><br/>
        生日:<input type="text" name="birthday" /><br/>
        用戶名:<input type="text" name="account.username" /><br/>
        余額:<input type="text" name="account.money" /><br/>
        用戶名:<input type="text" name="list[0].username" /><br/>
        余額:<input type="text" name="list[0].money" /><br/>
        用戶名:<input type="text" name="list[1].username" /><br/>
        余額:<input type="text" name="list[1].money" /><br/>
        用戶名:<input type="text" name="map['one'].username" /><br/>
        余額:<input type="text" name="map['one'].money" /><br/>
        <button type="submit">提交</button>
    </form>
</body>
</html>

4.3.3、啟動tomcat服務器測驗

注意:輸入生日的時候一定要輸入yyyy/MM/dd格式的生日,否則提交會報錯,如果我想輸入yyyy-MM-dd格式的日期怎么辦呢?這里需要自定義型別轉換器,

4.4、自定義型別轉換器

表單提交的任何資料型別全部是字串型別,但后臺資料定義成其他型別也可以封裝上,說明Spring框架內部會進行資料型別轉換,我們也可以自己進行資料型別轉換,這就需要自定義型別轉換器,

自定義型別轉換器,需要實作Converter介面,

4.4.1、自定義型別轉換器

package org.codeaction.converter;

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 自定義型別轉換器
 */
public class StringToDateConverter implements Converter<String, Date> {
    private SimpleDateFormat sft;

    public StringToDateConverter() {
        sft = new SimpleDateFormat("yyyy-MM-dd");
    }

    @Override
    public Date convert(String s) {
        Date date = null;
        try {
            date = sft.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

Converter<S, T>介面有兩個泛型,S表示接受的型別,T表示目標型別,

4.4.2、配置型別轉換器

在springmvc.xml中添加如下內容

<!-- 配置型別轉換器工廠 -->
<bean id="conversionServiceFactoryBean" >
    <!-- 給工廠注入一個新的型別轉換器 -->
    <property name="converters">
        <set>
            <!-- 配置自定義型別轉換器 -->
            <bean  />
        </set>
    </property>
</bean>

4.4.3、在annotation-driven標簽中參考配置的型別轉換服務

<!-- 配置spring開啟注解mvc的支持-->
<!-- 參考自定義型別轉換器 -->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"></mvc:annotation-driven>

4.4.4、啟動tomcat服務器測驗

輸入yyyy-MM-dd格式的日期,控制臺能夠列印出來,

4.5、系結ServletAPI物件作為方法引數

只需要把ServletAPI定義為控制器方法的引數就可以使用ServletAPI,

在控制器類ParamController中添加方法如下:

//測驗使用ServletAPI
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
    System.out.println(request);
    System.out.println(response);
    System.out.println(session);
    return "success";
}

4.6、請求引數亂碼問題

4.6.1、post請求亂碼

在web.xml添加一個Filter

<!-- 解決GET請求亂碼 -->
<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>

4.6.2、get請求亂碼

修改tomcat的server.xml,如下

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
修改為:
<Connector connectionTimeout="20000"
           port="8080"
           protocol="HTTP/1.1"
           redirectPort="8443"
           useBodyEncodingForURI="true" />
如果遇到ajax請求亂碼,修改為:
<Connector connectionTimeout="20000"
           port="8080"
           protocol="HTTP/1.1"
           redirectPort="8443"
           URIEncoding="UTF-8" />

4.7、配置靜態資源不過濾

<!--
    配置靜態資源不過濾
    location:表示路徑
    mapping:表示檔案
    **表示該目錄下的檔案以及子目錄檔案
 -->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
<mvc:resources location="/scripts/" mapping="/javascript/**"/>

五、常用注解

5.1、RequestParam

作用:將請求中指定名稱的引數給控制器中的形參賦值,

屬性

  • value:請求引數中的名稱,默認屬性,通過設定這個引數可以讓瀏覽器傳過來的引數名稱和控制器類方法形參名稱不同
  • name:和value作用相同,默認屬性;
  • required:請求引數中是否必須提供此引數,默認值:true,表示必須提供,如果不提供將報錯,

5.1.1、新建控制器類

package org.codeaction.controller;

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

@Controller
public class AnnotiationController {
    /**
     * 測驗RequestParam注解,有兩個請求引數
     * username從瀏覽器傳過來的名稱為name
     * 可以沒有age引數
     * @param username
     * @param age
     * @return
     */
    @RequestMapping("/testRequestParam")
    public String testRequestParam(@RequestParam(value = "https://www.cnblogs.com/codeaction/p/name") String username, @RequestParam(value = "https://www.cnblogs.com/codeaction/p/age", required = false) Integer age) {
        System.out.println(username);
        System.out.println(age);
        return "success";
    }
}

5.1.2、新建頁面

annotiation.jsp,在webapp目錄下

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <p>測驗RequestParam注解,有兩個請求引數</p>
    <a href="https://www.cnblogs.com/codeaction/p/${pageContext.request.contextPath}/testRequestParam?name=Tom&age=10">testRequestParam</a><br/>
    <p>測驗RequestParam注解,有一個請求引數</p>
    <a href="https://www.cnblogs.com/codeaction/p/${pageContext.request.contextPath}/testRequestParam?name=Bob">testRequestParam</a>
</body>
</html>

這一這里請求引數的名字是name,不是username,

從這個例子我們可以發現,在引數系結時,可以通過RequestParam注解的value屬性設定引數名稱,從而讓引數名稱和控制器類方法形參名稱不同,

5.1.3、啟動tomcat服務器測驗

分別點擊兩個超鏈接,控制臺輸出如下:

Tom
10
Bob
null

5.2、RequestBody

作用:用來決議請求體(GET請求不適用),如果發送的資料是form表單中的資料,得到的是key=value&key=value...結構的資料;如果是JSON型別的資料,利用訊息轉換器可將其轉換為Java物件,

屬性:required,是否必須有請求體,默認值是:true,當取值為 true 時,get 請求方式會報錯,如果取值為false, get請求得到是null,

5.2.1、form表單資料

5.2.1.1、在控制器類中添加方法

在AnnotiationController中添加如下內容

@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String accountStr) {
    System.out.println(accountStr);
    return "success";
}
5.2.1.2、在頁面中增加form表單

在annotiation.jsp中增加如下內容

<p>測驗RequestBody, post方式提交form表單</p>
<form action="${pageContext.request.contextPath}/testRequestBody" method="post">
    用戶名:<input type="text" name="username" /><br/>
    余額:<input type="text" name="money" /><br/>
    <button type="submit">提交</button>
</form>
5.2.1.3、啟動tomcat服務器測驗

啟動tomcat服務器,在表單中輸入資料,提交,控制臺輸出如下:

username=111&money=111

5.2.2、JSON資料

5.2.2.1、增加jquery檔案

在webapp目錄下新建js目錄,拷貝jquery檔案到該目錄下,

5.2.2.2、在pom.xml中添加坐標
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
</dependency>

這三個坐標為JSON處理提供支持,

5.2.2.3、在控制器類中添加方法

在AnnotiationController中添加如下內容

@RequestMapping("/testRequestBody1")
public String testRequestBody1(@RequestBody Account account) {
    System.out.println(account);
    return "success";
}
5.2.2.4、在頁面中添加如下內容

在annotiation.jsp中增加如下內容

發送JSON資料的按鈕

<button id="btn" type="button">測驗RequestBody,發送json資料</button>

發送Ajax請求的js代碼

<script src="https://www.cnblogs.com/codeaction/p/${pageContext.request.contextPath}/js/jquery.min.js"></script>
<script>
    $(function () {
        $("#btn").click(function(){
            // 發送ajax請求
            $.ajax({
                // 撰寫json格式,設定屬性和值
                url:"${pageContext.request.contextPath}/testRequestBody1",
                contentType:"application/json;charset=UTF-8",
                data:'{"username":"Tom","money":30}',
                dataType:"json",
                type:"post",
                success:function(data){
                }
            });

        });
    });
</script>
5.2.2.5、啟動tomcat服務器測驗

啟動tomcat服務器,點擊button,控制臺輸出如下:

Account{username='Tom', money=30.0}

5.3、PathVariable

學習PathVariable注解之前,我們要先學習一下REST風格的URL,

5.3.1、什么是REST風格的URL

簡單說就是:用URL表示要操作的資源,用不同的HTTP請求(GET、POST、PUT、DELETE)描述對資源的操作,通過HTTP的狀態碼來判斷此次對資源操作的結果,

REST風格的URL是對請求的一次解耦,提高了URL的重用性,

  • GET:用來獲取資源;
  • PUT:用來更新資源;
  • DELETE:用來洗掉資源;
  • POST:用來新增資源;

REST風格的URL舉例:

  • GET請求,/account/1,得到id=1的account;
  • PUT請求,/account/1,修改id=1的account;
  • DELETE請求,/account/1,洗掉id=1的account;
  • POST請求,/account/1,新增account,

由于我們的form表單只有GET和POST兩種方式,如何發送DELETE和PUT請求,關于這點,需要在SpringMVC中進行配置,這里就不展開了,

5.3.2、關于PathVariable

作用:用于系結url中的占位符,例如,請求url中/account/{id},這個{id}就是url占位符,

屬性

  • value:用于指定URL中占位符名稱;
  • name:作用和value相同,兩個可以互換;
  • required:是否必須提供占位符,
5.3.2.1、在控制器類中添加方法

在AnnotiationController中添加如下內容

@RequestMapping(value = "https://www.cnblogs.com/testPathVariable/account/{id}", method = RequestMethod.GET)
public String testPathVariable(@PathVariable("id") Integer id) {
    System.out.println(id);
    return "success";
}
5.3.2.2、在頁面中添加如下內容

在annotiation.jsp中增加如下內容

<a href="https://www.cnblogs.com/codeaction/p/${pageContext.request.contextPath}/testPathVariable/account/1">測驗PathVariable</a>
5.3.2.3、啟動tomcat服務器測驗

運行tomcat服務器,點擊超鏈接,控制臺輸出如下:

1

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/161499.html

標籤:Java

上一篇:7 種 JVM 垃圾收集器,看完我跪了。。

下一篇:多型

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more