主頁 > 後端開發 > Web請求與回應(SpringBoot)

Web請求與回應(SpringBoot)

2023-03-23 20:57:55 後端開發

Web請求與回應

 

Web的作業原理可以分為以下幾個步驟:

  1. 輸入URL:Web客戶端使用Web瀏覽器輸入所需訪問的URL(統一資源定位符),

  2. 建立連接:Web瀏覽器與Web服務器之間建立TCP/IP連接,以便傳輸資料,

  3. 發送HTTP請求:Web瀏覽器向Web服務器發送HTTP請求,請求所需的Web資源,

  4. 接收HTTP回應:Web服務器接收HTTP請求,并通過HTTP回應將Web資源發送給Web瀏覽器,

  5. 渲染Web頁面:Web瀏覽器接收HTTP回應,并根據所收到的資料渲染Web頁面,以便呈現給用戶,

  6. 關閉連接:Web瀏覽器和Web服務器之間的TCP/IP連接被關閉,

 

什么是 HTTP 請求?

HTTP(超文本傳輸協議)是一種用于 Web 服務器和客戶端(瀏覽器)之間通信以通過 Internet 傳輸資料的協議, HTTP 請求是客戶端向服務器發送的請求特定資源(如網頁、影像或視頻)的訊息, HTTP 請求方法決定了請求的型別,例如 GET、POST、PUT、DELETE、HEAD、OPTIONS、CONNECT、TRACE 等,

HTTP請求的結構:

HTTP 請求由請求行、標頭和可選的訊息正文組成,

請求行包括 HTTP 方法、所請求資源的 URL(統一資源定位符)以及所使用的 HTTP 版本,

標頭提供有關請求的其他資訊,例如用戶代理、請求的內容型別和可接受的編碼格式,

訊息正文是可選的,包含資料,例如表單資料或 JSON ,

HTTP請求方法:

HTTP 定義了各種請求方法,指示要對 URL 標識的資源執行的操作,最常見的 HTTP 請求方法是:

  1. GET:從服務器獲取資源,例如網頁或影像,

  2. POST:將資料提交給服務器進行處理,例如表單提交或檔案上傳,

  3. PUT:用新資料更新服務器上的現有資源,

  4. DELETE:從服務器中洗掉資源,

  5. HEAD:檢索資源的標頭,不帶訊息正文,

  6. OPTIONS:用于獲取當前URL所支持的方法,若請求成功,則它會在HTTP頭中包含一個名為“Allow”的頭,值是所支持的方法,如“GET, POST”,

  7. CONNECT:建立到資源的網路連接,例如代理服務器,

  8. TRACE:回顯接收到的請求訊息,用于除錯目的, HTTP 標頭:

 

HTTP 標頭用于提供有關 HTTP 請求或回應的附加資訊,它們是由冒號分隔的鍵值對,包含在請求或回應訊息中, Header有多種型別,例如通用Header、請求Header、回應Header和物體Header,一些常見的標頭包括:

  1. User-Agent:向訪問網站提供你所使用的瀏覽器型別、作業系統及版本、CPU 型別、瀏覽器渲染引擎、瀏覽器語言、瀏覽器插件等資訊的標識

  2. Accept:指定客戶端接受的內容型別,

  3. Content-Type:指定請求或回應訊息中內容的型別,

  4. Content-Length:指定訊息體的長度,以位元組為單位,

  5. Cache-Control:指定回應的快取指令,例如 max-age 和 must-revalidate,

  6. Authorization:指定請求的身份驗證憑據, HTTP 訊息體body:

 

HTTP 訊息正文是 HTTP 請求或回應的可選部分,包含各種格式的資料,例如 HTML、JSON、XML 或二進制資料,在請求中,訊息正文包含要發送到服務器的資料,例如表單資料或檔案上傳,在回應中,訊息正文包含所請求資源的實際內容,例如 HTML 頁面或影像,

總之,了解 http 請求和回應的基礎知識對于 Web 開發以及 Web 服務器和客戶端之間的通信至關重要,通過了解如何構建 HTTP 請求、各種請求方法、標頭的使用以及可選的訊息正文,開發人員可以有效地與服務器通信并創建健壯的 Web 應用程式,

什么是 HTTP 回應?

HTTP回應是由服務器向客戶發送的對請求的回應, HTTP 回應包含以下組件:

  1. HTTP版本

  2. 狀態碼

  3. 狀態訊息

  4. 回應頭

  5. 回應體

1、HTTP版本

回應中使用的 HTTP 版本在回應的第一行中指定,例如:

HTTP/1.1 200 OK

這指定使用 HTTP 版本 1.1 發送回應,

2、狀態碼

狀態代碼表示所請求操作的結果, HTTP 定義了五類狀態碼:

  1. 資訊提示 (100-199)

  2. 成功 (200-299)

  3. 重定向 (300-399)

  4. 客戶端錯誤 (400-499)

  5. 服務器錯誤 (500-599) 每個狀態碼都是一個三位數字,它包含在HTTP版本之后的回應的第一行中,例如:

HTTP/1.1 200 OK

這表明操作成功,請求的資源包含在回應正文中,

3、狀態資訊

狀態訊息是對狀態代碼的描述,它包含在狀態代碼之后的回應的第一行中,例如:

HTTP/1.1 404 Not Found

這表示未找到請求的資源,狀態訊息提供了問題的簡短描述,

4、回應頭

回應標頭包含有關回應的元資料,它們類似于請求標頭,但提供有關回應而不是請求的資訊,回應標頭可以包括有關服務器、快取策略、cookie 等的資訊,

回應標頭包含在第一行之后的回應中,每個標頭都是一個由冒號分隔的鍵值對,例如:

HTTP/1.1 200 OK

Content-Type: text/html

Content-Length: 1274

Server: Apache

在此示例中,回應包含三個標頭:Content-Type、Content-Length 和 Server,

5、回應體

回應正文包含請求的資源或錯誤訊息,如果找不到請求的資源,回應正文的格式取決于回應中包含的 Content-Type 標頭,例如,如果 Content-Type 標頭設定為“text/html”,則回應正文應包含 HTML 代碼,

回應主體包含在回應標頭之后的回應中,如果回應主體很大,它可能會被拆分成多個資料包,

HTTP 請求和回應的技術點

HTTP 請求和回應有幾個開發人員需要注意的技術點,這些技術點決定了請求和回應如何在客戶端和服務器之間構建和傳輸,

1、請求和回應標頭

HTTP 請求和回應包含提供有關請求或回應的附加資訊的標頭,標頭是在訊息標頭中發送的鍵值對,它們用于傳達有關請求或回應的元資料, Headers 有多種型別,包括通用 Headers、請求 Headers、回應 Headers 和物體 Headers,

通用標頭適用于請求和回應,并提供有關整個訊息的資訊,例如訊息格式、發送日期和時間以及訊息是否可以快取,

請求標頭用于提供有關發出請求的客戶端的資訊,例如用戶代理(用于訪問服務器的軟體)、接受的內容型別以及用于壓縮訊息正文的編碼,

回應頭提供了服務器對客戶端請求的回應資訊,如回應的內容型別、訊息體的長度、回應是否可以快取等,

物體標頭用于提供有關訊息正文的資訊,例如內容長度和內容編碼,

2、HTTP 方法

HTTP 請求使用一組方法來指定要對 URL 中標識的資源執行的所需操作,最常見的 HTTP 方法是 GET、POST、PUT、DELETE 和 HEAD,

  1. GET:用于從服務器檢索資料,

  2. POST:用于向服務器發送資料以創建或更新資源,

  3. PUT:用于更新服務器上的現有資源,

  4. DELETE:用于從服務器中洗掉資源,

  5. HEAD:用于檢索資源的標頭,而不是訊息正文, HTTP 狀態碼 HTTP 回應包括指示請求狀態的狀態代碼,有五類狀態代碼,每類都有自己的一組代碼:

? 1xx: 資訊 - 表示服務器已收到請求并正在繼續處理它, ? 2xx: 成功——表示請求被成功接收、理解和接受, ? 3xx: 重定向——表示客戶端需要采取進一步的行動來完成請求, ? 4xx: 客戶端錯誤 - 表示請求包含錯誤的語法或無法實作, ? 5xx: 服務器錯誤 - 表示服務器未能滿足有效請求, 最常見的狀態代碼是 200 OK(請求成功)、404 Not Found(未找到請求的資源)和 500 Internal Server Error(服務器在處理請求時遇到錯誤),

3、Cookies

HTTP 請求和回應還可以包括 cookie,它們是存盤在客戶端計算機上的小文本檔案, Cookie 用于存盤有關客戶端偏好或之前與服務器互動的資訊,服務器可以使用 cookie 來識別客戶端并提供定制的內容,

4、快取

HTTP 請求和回應還可以被快取,這意味著客戶端或中間服務器可以存盤回應的副本以備將來使用,快取有助于減少網路流量并提高性能,但如果快取的內容過時或陳舊,也會導致問題,

作者博客:

yhttps://blog.51cto.com/sdwml/6104070

1.基于SpringBoot請求

請求(HttpServletRequest):獲取請求資料

在瀏覽器地址輸入地址,點擊回車請求服務器,這個程序就是一個請求程序,

1.1簡單引數

1.1.1原始方式

在原始的Web程式當中,需要通過Servlet中提供的API:HttpServletRequest(請求物件),獲取請求的相關資訊,比如獲取請求引數:

Tomcat接受到Http請求時:把請求的相關資訊封裝到HttpServletRequest物件中,

在Controller中,我們要想獲取Request物件,可以直接在方法的形參中宣告HttpServletRequest物件,然后就可以通過該物件來獲取請求資訊:

//根據指定的引數名獲取請求引數的資料值
String  request.getParameter("引數名")
@RestController
public class RequestController {
    //原始方式
    @RequestMapping("/simpleParam")
    public String simpleParam(HttpServletRequest request){
        // http://localhost:8080/simpleParam?name=Tom&age=10
        // 請求引數: name=Tom&age=10   (有2個請求引數)
        // 第1個請求引數: name=Tom   引數名:name,引數值:Tom
        // 第2個請求引數: age=10     引數名:age , 引數值:10
?
        String name = request.getParameter("name");//name就是請求引數名
        String ageStr = request.getParameter("age");//age就是請求引數名
?
        int age = Integer.parseInt(ageStr);//需要手動進行型別轉換
        System.out.println(name+"  :  "+age);
        return "OK";
    }
}

1.1.2SpringBoot方式

在Springboot的環境中,對原始的API進行了封裝,接收引數的形式更加簡單, 如果是簡單引數,引數名與形參變數名相同,定義同名的形參即可接收引數,

@RestController
public class RequestController {
    // http://localhost:8080/simpleParam?name=Tom&age=10
    // 第1個請求引數: name=Tom   引數名:name,引數值:Tom
    // 第2個請求引數: age=10     引數名:age , 引數值:10
    
    //springboot方式
    @RequestMapping("/simpleParam")
    public String simpleParam(String name , Integer age ){//形參名和請求引數名保持一致
        System.out.println(name+"  :  "+age);
        return "OK";
    }
}

結論:不論是GET請求還是POST請求,對于簡單引數來講,只要保證==請求引數名和Controller方法中的形參名保持一致==,就可以獲取到請求引數中的資料值,

 

1.1.3引數名不一致

如果方法形參名稱與請求引數名稱不一致,controller方法中的形參還能接收到請求引數值嗎?

@RestController
public class RequestController {
    // http://localhost:8080/simpleParam?name=Tom&age=20
    // 請求引數名:name
?
    //springboot方式
    @RequestMapping("/simpleParam")
    public String simpleParam(String username , Integer age ){//請求引數名和形參名不相同
        System.out.println(username+"  :  "+age);
        return "OK";
    }
}

答案:運行沒有報錯, controller方法中的username值為:null,age值為20

  • 結論:對于簡單引數來講,請求引數名和controller方法中的形參名不一致時,無法接收到請求資料

 

那么如果我們開發中,遇到了這種請求引數名和controller方法中的形參名不相同,怎么辦?

 

解決方案:可以使用Spring提供的@RequestParam注解完成映射

 

在方法形參前面加上 @RequestParam 然后通過value屬性執行請求引數名,從而完成映射,代碼如下:

@RestController
public class RequestController {
    // http://localhost:8080/simpleParam?name=Tom&age=20
    // 請求引數名:name
?
    //springboot方式
    @RequestMapping("/simpleParam")
    public String simpleParam(@RequestParam("name") String username , Integer age ){
        System.out.println(username+"  :  "+age);
        return "OK";
    }
}

注意事項:

@RequestParam中的required屬性默認為true(默認值也是true),代表該請求引數必須傳遞,如果不傳遞將報錯

如果該引數是可選的,可以將required屬性設定為false

@RequestMapping("/simpleParam")
public String simpleParam(@RequestParam(name = "name", required = false) String username, Integer age){
System.out.println(username+ ":" + age);
return "OK";
}

1.2物體引數

在使用簡單引數做為資料傳遞方式時,前端傳遞了多少個請求引數,后端controller方法中的形參就要書寫多少個,如果請求引數比較多,通過上述的方式一個引數一個引數的接收,會比較繁瑣,

此時,我們可以考慮將請求引數封裝到一個物體類物件中, 要想完成資料封裝,需要遵守如下規則:請求引數名與物體類的屬性名相同

1.2.1簡單物體類物件

定義POJO物體類:

public class User {
    private String name;
    private Integer age;
?
    public String getName() {
        return name;
    }
?
    public void setName(String name) {
        this.name = name;
    }
?
    public Integer getAge() {
        return age;
    }
?
    public void setAge(Integer age) {
        this.age = age;
    }
?
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
?

Controller方法

@RestController
public class RequestController {
    //物體引數:簡單物體物件
    @RequestMapping("/simplePojo")
    public String simplePojo(User user){
        System.out.println(user);
        return "OK";
    }
}

1.2.2復雜物體類物件

上面我們講的呢是簡單的物體物件,下面我們在來學習下復雜的物體物件,

復雜物體物件指的是,在物體類中有一個或多個屬性,也是物體物件型別的,如下:

  • User類中有一個Address型別的屬性(Address是一個物體類)

復雜物體物件的封裝,需要遵守如下規則:

  • 請求引數名與形參物件屬性名相同,按照物件層次結構關系即可接收嵌套物體類屬性引數,

定義POJO物體類:

  • Address物體類

public class Address {
    private String province;
    private String city;
?
    public String getProvince() {
        return province;
    }
?
    public void setProvince(String province) {
        this.province = province;
    }
?
    public String getCity() {
        return city;
    }
?
    public void setCity(String city) {
        this.city = city;
    }
?
    @Override
    public String toString() {
        return "Address{" +
                "province='" + province + '\'' +
                ", city='" + city + '\'' +
                '}';
    }
}
  • User物體類

public class User {
    private String name;
    private Integer age;
    private Address address; //地址物件
?
    public String getName() {
        return name;
    }
?
    public void setName(String name) {
        this.name = name;
    }
?
    public Integer getAge() {
        return age;
    }
?
    public void setAge(Integer age) {
        this.age = age;
    }
?
    public Address getAddress() {
        return address;
    }
?
    public void setAddress(Address address) {
        this.address = address;
    }
?
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
}

Controller方法:

@RestController
public class RequestController {
    //物體引數:復雜物體物件
    @RequestMapping("/complexPojo")
    public String complexPojo(User user){
        System.out.println(user);
        return "OK";
    }
}

Postman測驗:

1.3陣列集合引數

陣列集合引數的使用場景:在HTML的表單中,有一個表單項是支持多選的(復選框),可以提交選擇的多個值,

后端程式接收上述多個值的方式有兩種:

  1. 陣列

  2. 集合

     

1.3.1陣列

陣列引數:請求引數名與形引陣列名稱相同且請求引數為多個,定義陣列型別形參即可接收引數

Controller方法:

@RestController
public class RequestController {
    //陣列集合引數
    @RequestMapping("/arrayParam")
    public String arrayParam(String[] hobby){
        System.out.println(Arrays.toString(hobby));
        return "OK";
    }
}

Postman測驗:

在前端請求時,有兩種傳遞形式:

方式一:http://localhost:8080/arrayParam?hobby=game&hobby=java

方式二:http://localhost:8080/arrayParam?hobby=game,java

1.3.2集合

集合引數:請求引數名與形參集合物件名相同且請求引數為多個,@RequestParam 系結引數關系

默認情況下,請求中引數名相同的多個值,是封裝到陣列,如果要封裝到集合,要使用@RequestParam系結引數關系

Controller方法:

@RestController
public class RequestController {
    //陣列集合引數
    @RequestMapping("/listParam")
    public String listParam(@RequestParam List<String> hobby){
        System.out.println(hobby);
        return "OK";
    }
}

Postman測驗:

方式一:http://localhost:8080/listParam?hobby=game&hobby=java

方式二:http://localhost:8080/listParam?hobby=game,java

1.4日期函式

上述演示的都是一些普通的引數,在一些特殊的需求中,可能會涉及到日期型別資料的封裝,比如,如下需求:

因為日期的格式多種多樣(如:2022-12-12 10:05:45 、2022/12/12 10:05:45),那么對于日期型別的引數在進行封裝的時候,需要通過@DateTimeFormat注解,以及其pattern屬性來設定日期的格式,

  • @DateTimeFormat注解的pattern屬性中指定了哪種日期格式,前端的日期引數就必須按照指定的格式傳遞,

  • 后端controller方法中,需要使用Date型別或LocalDateTime型別,來封裝傳遞的引數,

Controller方法:

@RestController
public class RequestController {
    //日期時間引數
   @RequestMapping("/dateParam")
    public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime){
        System.out.println(updateTime);
        return "OK";
    }
}

1.5JSON引數

如果是比較復雜的引數,前后端通過會使用JSON格式的資料進行傳輸, (JSON是開發中最常用的前后端資料互動方式)

我們學習JSON格式引數,主要從以下兩個方面著手:

  1. Postman在發送請求時,如何傳遞json格式的請求引數

  2. 在服務端的controller方法中,如何接收json格式的請求引數

Postman發送JSON格式資料:

服務端Controller方法接收JSON格式資料:

  • 傳遞json格式的引數,在Controller中會使用物體類進行封裝,

  • 封裝規則:JSON資料鍵名與形參物件屬性名相同,定義POJO型別形參即可接收引數,需要使用 @RequestBody標識,

  • @RequestBody注解:將JSON資料映射到形參的物體類物件中(JSON中的key和物體類中的屬性名保持一致)

物體類:Address

public class Address {
    private String province;
    private String city;
    
    //省略GET , SET 方法
}

物體類:User

public class User {
    private String name;
    private Integer age;
    private Address address;
    
    //省略GET , SET 方法
}    

Controller方法:

@RestController
public class RequestController {
    //JSON引數
    @RequestMapping("/jsonParam")
    public String jsonParam(@RequestBody User user){
        System.out.println(user);
        return "OK";
    }
}

Postman測驗:

1.6路徑引數

傳統的開發中請求引數是放在請求體(POST請求)傳遞或跟在URL后面通過?key=value的形式傳遞(GET請求),

在現在的開發中,經常還會直接在請求的URL中傳遞引數,例如:

http://localhost:8080/user/1        
http://localhost:880/user/1/0

上述的這種傳遞請求引數的形式呢,我們稱之為:路徑引數,

學習路徑引數呢,主要掌握在后端的controller方法中,如何接收路徑引數,

路徑引數:

  • 前端:通過請求URL直接傳遞引數

  • 后端:使用{…}來標識該路徑引數,需要使用@PathVariable獲取路徑引數

Controller方法:

@RestController
public class RequestController {
    //路徑引數
    @RequestMapping("/path/{id}")
    public String pathParam(@PathVariable Integer id){
        System.out.println(id);
        return "OK";
    }
}

傳遞多個路徑引數:

Controller方法:

@RestController
public class RequestController {
    //路徑引數
    @RequestMapping("/path/{id}/{name}")
    public String pathParam2(@PathVariable Integer id, @PathVariable String name){
        System.out.println(id+ " : " +name);
        return "OK";
    }
}

2.基于SpringBoot回應

回應(HttpServletReponse):設定回應資料

服務器根據瀏覽器發送的請求,放回資料到瀏覽器在網頁上進行顯示的程序就叫回應,

2.1@ResponseBody

controller方法中的return的結果,怎么就可以回應給瀏覽器呢?

答案:使用@ResponseBody注解

@ResponseBody注解:

  • 型別:方法注解、類注解

  • 位置:書寫在Controller方法上或類上

  • 作用:將方法回傳值直接回應給瀏覽器

    • 如果回傳值型別是物體物件/集合,將會轉換為JSON格式后在回應給瀏覽器

但是在我們所書寫的Controller中,只在類上添加了@RestController注解、方法添加了@RequestMapping注解,并沒有使用@ResponseBody注解,怎么給瀏覽器回應呢?

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello(){
        System.out.println("Hello World ~");
        return "Hello World ~";
    }
}

原因:在類上添加的@RestController注解,是一個組合注解,

  • @RestController = @Controller + @ResponseBody

@RestController原始碼:

@Target({ElementType.TYPE})   //元注解(修飾注解的注解)
@Retention(RetentionPolicy.RUNTIME)  //元注解
@Documented    //元注解
@Controller   
@ResponseBody 
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}

結論:在類上添加@RestController就相當于添加了@ResponseBody注解,

  • 類上有@RestController注解或@ResponseBody注解時:表示當前類下所有的方法回傳值做為回應資料

    • 方法的回傳值,如果是一個POJO物件或集合時,會先轉換為JSON格式,在回應給瀏覽器

下面我們來測驗下回應資料:

@RestController
public class ResponseController {
    //回應字串
    @RequestMapping("/hello")
    public String hello(){
        System.out.println("Hello World ~");
        return "Hello World ~";
    }
    //回應物體物件
    @RequestMapping("/getAddr")
    public Address getAddr(){
        Address addr = new Address();//創建物體類物件
        addr.setProvince("廣東");
        addr.setCity("深圳");
        return addr;
    }
    //回應集合資料
    @RequestMapping("/listAddr")
    public List<Address> listAddr(){
        List<Address> list = new ArrayList<>();//集合物件
        
        Address addr = new Address();
        addr.setProvince("廣東");
        addr.setCity("深圳");
?
        Address addr2 = new Address();
        addr2.setProvince("陜西");
        addr2.setCity("西安");
?
        list.add(addr);
        list.add(addr2);
        return list;
    }
}

在服務端回應了一個物件或者集合,那私前端獲取到的資料是什么樣子的呢?我們使用postman發送請求來測驗下,測驗效果如下:

 

2.2統一回應結果

大家有沒有發現一個問題,我們在前面所撰寫的這些Controller方法中,回傳值各種各樣,沒有任何的規范,

如果我們開發一個大型專案,專案中controller方法將成千上萬,使用上述方式將造成整個專案難以維護,那在真實的專案開發中是什么樣子的呢?

在真實的專案開發中,無論是哪種方法,我們都會定義一個統一的回傳結果,方案如下:

前端:只需要按照統一格式的回傳結果進行決議(僅一種決議方案),就可以拿到資料,

統一的回傳結果使用類來描述,在這個結果中包含:

  • 回應狀態碼:當前請求是成功,還是失敗

  • 狀態碼資訊:給頁面的提示資訊

  • 回傳的資料:給前端回應的資料(字串、物件、集合)

定義在一個物體類Result來包含以上資訊,代碼如下:

public class Result {
    private Integer code;//回應碼,1 代表成功; 0 代表失敗
    private String msg;  //回應碼 描述字串
    private Object data; //回傳的資料
public Result() { }
public Result(Integer code, String msg, Object data) {
    this.code = code;
    this.msg = msg;
    this.data = https://www.cnblogs.com/yaomagician/archive/2023/03/23/data;
}
?
public Integer getCode() {
    return code;
}
?
public void setCode(Integer code) {
    this.code = code;
}
?
public String getMsg() {
    return msg;
}
?
public void setMsg(String msg) {
    this.msg = msg;
}
?
public Object getData() {
    return data;
}
?
public void setData(Object data) {
    this.data = data;
}
?
//增刪改 成功回應(不需要給前端回傳資料)
public static Result success(){
    return new Result(1,"success",null);
}
//查詢 成功回應(把查詢結果做為回傳資料回應給前端)
public static Result success(Object data){
    return new Result(1,"success",data);
}
//失敗回應
public static Result error(String msg){
    return new Result(0,msg,null);
}
}

改造Controller:

@RestController
public class ResponseController { 
    //回應統一格式的結果
    @RequestMapping("/hello")
    public Result hello(){
        System.out.println("Hello World ~");
        //return new Result(1,"success","Hello World ~");
        return Result.success("Hello World ~");
    }
?
    //回應統一格式的結果
    @RequestMapping("/getAddr")
    public Result getAddr(){
        Address addr = new Address();
        addr.setProvince("廣東");
        addr.setCity("深圳");
        return Result.success(addr);
    }
?
    //回應統一格式的結果
    @RequestMapping("/listAddr")
    public Result listAddr(){
        List<Address> list = new ArrayList<>();
?
        Address addr = new Address();
        addr.setProvince("廣東");
        addr.setCity("深圳");
?
        Address addr2 = new Address();
        addr2.setProvince("陜西");
        addr2.setCity("西安");
?
        list.add(addr);
        list.add(addr2);
        return Result.success(list);
    }
}

使用Postman測驗:

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

標籤:其他

上一篇:劍指 Offer 17. 列印從 1 到最大的 n 位數(java解題)

下一篇:阿里又開源一款資料同步工具 DataX,穩定又高效,好用到爆!

標籤雲
其他(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