SpringMVC 中的 redirect 和 forward 区别

SpringMVC HTTP About 3,879 words

代码

@Controller
public class RedirectForwardController {

    @GetMapping("/test1")
    public String test1() {
        return "redirect:http://127.0.0.1:8080/test2";
    }

    @GetMapping("/test2")
    public String test2() {
        return "redirect:http://127.0.0.1:8080/test3";
    }

    @GetMapping("/test3")
    @ResponseBody
    public String test3() {
        return "来自test3的结果";
    }

    @GetMapping("/test4")
    public String test4() {
        return "forward:/test3";
    }

}

说明

演示案例使用Git Bash中的curl命令(CMD命令窗口也可以),PowerShell下的curl命令会自动完成重定向后的请求不利于观察。

redirect

重定向redirect请求会返回前端302状态码,并且在Header中携带Location字段,表示重定向到指定URL,由前端完成再次发起重定向后的请求。

curl -v http://127.0.0.1:8080/test1

输出:

$ curl -v http://127.0.0.1:8080/test1
*   Trying 127.0.0.1:8080...
* TCP_NODELAY set
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /test1 HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.65.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 302
< Location: http://127.0.0.1:8080/test2
< Content-Language: zh-CN
< Content-Length: 0
< Date: Mon, 15 Mar 2021 02:06:48 GMT
<
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Connection #0 to host 127.0.0.1 left intact

抓包日志:

Frame 65: 181 bytes on wire (1448 bits), 181 bytes captured (1448 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 8080, Dst Port: 57185, Seq: 1, Ack: 84, Len: 137
Hypertext Transfer Protocol
    HTTP/1.1 302 \r\n
    Location: http://127.0.0.1:8080/test2\r\n
    Content-Language: zh-CN\r\n
    Content-Length: 0\r\n
    Date: Mon, 15 Mar 2021 01:49:31 GMT\r\n
    \r\n
    [HTTP response 1/1]
    [Time since request: 0.007317000 seconds]
    [Request in frame: 61]
    [Request URI: http://127.0.0.1:8080/test1]

forward

转发forward会由SpringMVC自动完成内部请求的转发并直接返回转发后的返回参数,只适用于内部的Controller转发,否则会报404错误,前端无感知。

$ curl -v http://127.0.0.1:8080/test4
*   Trying 127.0.0.1:8080...
* TCP_NODELAY set
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /test4 HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.65.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200
< Content-Type: text/plain;charset=UTF-8
< Content-Language: zh-CN
< Content-Length: 20
< Date: Mon, 15 Mar 2021 02:06:08 GMT
<
{ [20 bytes data]
100    20  100    20    0     0   6666      0 --:--:-- --:--:-- --:--:--  6666来自test3的结果
* Connection #0 to host 127.0.0.1 left intact

抓包日志:

Frame 33: 203 bytes on wire (1624 bits), 203 bytes captured (1624 bits) on interface \Device\NPF_Loopback, id 0
Null/Loopback
Internet Protocol Version 4, Src: 127.0.0.1, Dst: 127.0.0.1
Transmission Control Protocol, Src Port: 8080, Dst Port: 57171, Seq: 1, Ack: 84, Len: 159
Hypertext Transfer Protocol
    HTTP/1.1 200 \r\n
    Content-Type: text/plain;charset=UTF-8\r\n
    Content-Language: zh-CN\r\n
    Content-Length: 20\r\n
    Date: Mon, 15 Mar 2021 01:48:20 GMT\r\n
    \r\n
    [HTTP response 1/1]
    [Time since request: 0.072031000 seconds]
    [Request in frame: 29]
    [Request URI: http://127.0.0.1:8080/test4]
    File Data: 20 bytes
Line-based text data: text/plain (1 lines)
    来自test3的结果

本地数据包的抓取

Linux

tcpdump -i lo -w test.pcap

Windows

Wireshark需安装Npcap后选择Adapter for loopback traffic capture网卡进行抓包。

Views: 2,370 · Posted: 2021-07-13

————        END        ————

Give me a Star, Thanks:)

https://github.com/fendoudebb/LiteNote

扫描下方二维码关注公众号和小程序↓↓↓

扫描下方二维码关注公众号和小程序↓↓↓


Today On History
Browsing Refresh