How to set up web server to perform POST Request in Go?

huangapple go评论102阅读模式
英文:

How to set up web server to perform POST Request in Go?

问题

我想设置一个Web服务器来执行POST请求。由于主函数中只定义了HandleFunc和ListenAndServe,所以如何执行下面的代码中的POST请求呢?

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)

func post(w http.ResponseWriter, r *http.Request) {
	const myurl string = "http://localhost:8000/"
	request := strings.NewReader(`
	{
		"Name":"Tom",
		"Age":"20" 
	}
	`)
	response, err := http.Post(myurl, "application/json", request)
	content, err := ioutil.ReadAll(response.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(content))
	defer response.Body.Close()
}

func main() {
	http.HandleFunc("/", post)
	log.Fatal(http.ListenAndServe(":8000", nil))
}

这段代码中,通过http.HandleFunc("/", post)post函数与根路径"/"绑定,意味着当收到根路径的POST请求时,会执行post函数。然后通过http.ListenAndServe(":8000", nil)启动一个监听在本地8000端口的HTTP服务器。

当有POST请求到达根路径时,服务器会调用post函数。在post函数中,首先定义了一个URL字符串myurl,然后创建了一个包含JSON数据的strings.Reader对象作为请求体。接下来,使用http.Post函数发送POST请求,并将响应保存在response变量中。然后使用ioutil.ReadAll函数读取响应的内容,并将其打印出来。最后,通过defer response.Body.Close()关闭响应的主体。

所以,当你运行这段代码并向根路径发送POST请求时,服务器会执行post函数,并发送一个POST请求到http://localhost:8000/,然后将响应内容打印出来。

英文:

I want to set up a web server to perform a POST request. How does the post request get executed with the code below since only HandleFunc and ListenAndServe are defined in main function?

package main

import (
"fmt"
"io/ioutil"
"log"
"net/http"
"strings"
 )

func post(w http.ResponseWriter, r *http.Request) {
  const myurl string = "http://localhost:8000/"
  request := strings.NewReader(`
  {
	"Name":"Tom",
	"Age":"20" 
  }
`)
  response, err := http.Post(myurl, "application/json", request)
  content, err := ioutil.ReadAll(response.Body)
  if err != nil {
	 panic(err)
  }
  fmt.Println(string(content))
  defer response.Body.Close()
  }
func main() {
  http.HandleFunc("/", post)
  log.Fatal(http.ListenAndServe(":8000", nil))
}

答案1

得分: 2

这是一个基本示例,展示了如何进行操作。我使用相同的程序来运行服务器和客户端。这只是为了演示目的。当然,你也可以将它们作为独立的程序。

// 使用结构体表示接收和发送的数据
type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}
// 运行示例
func main() {
	// 在一个 goroutine 中启动服务器
	go server()

	// 等待1秒,给服务器启动的时间
	time.Sleep(time.Second)

	// 发送一个 POST 请求
	if err := client(); err != nil {
		fmt.Println(err)
	}
}
// 基本的 Web 服务器,接收请求并将请求体解码为一个用户结构体
func server() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
			return
		}

		user := &Person{}
		err := json.NewDecoder(r.Body).Decode(user)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		fmt.Println("got user:", user)
		w.WriteHeader(http.StatusCreated)
	})

	if err := http.ListenAndServe(":8080", nil); err != http.ErrServerClosed {
		panic(err)
	}
}
// 简单的客户端,向服务器发送一个用户对象
func client() error {
	user := &Person{
		Name: "John",
		Age:  30,
	}

	b := new(bytes.Buffer)
	err := json.NewEncoder(b).Encode(user)
	if err != nil {
		return err
	}

	resp, err := http.Post("http://localhost:8080/", "application/json", b)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	fmt.Println(resp.Status)
	return nil
}

这是一个可工作的示例:https://go.dev/play/p/34GT04jy_uA

英文:

Here is a basic example of how you could go about it. I am using the same program to run both, the server and the client. This is just for demonstration purposes. You can of course make them separate programs.

// use struct to represent the data 
// to recieve and send
type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}
// run the example
func main() {
	// start the server in a goroutine
	go server()

	// wait 1 second to give the server time to start
	time.Sleep(time.Second)

	// make a post request
	if err := client(); err != nil {
		fmt.Println(err)
	}
}
// basic web server to receive a request and 
// decode the body into a user struct
func server() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost  {
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
			return
		}

		user := &Person{}
		err := json.NewDecoder(r.Body).Decode(user)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		fmt.Println("got user:", user)
		w.WriteHeader(http.StatusCreated)
	})

	if err := http.ListenAndServe(":8080", nil); err != http.ErrServerClosed {
		panic(err)
	}
}
// a simple client that posts a user to the server
func client() error {
	user := &Person{
		Name: "John",
		Age:  30,
	}

	b := new(bytes.Buffer)
	err := json.NewEncoder(b).Encode(user)
	if err != nil {
		return err
	}

	resp, err := http.Post("http://localhost:8080/", "application/json", b)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	fmt.Println(resp.Status)
	return nil
}

Here is the working example: https://go.dev/play/p/34GT04jy_uA

huangapple
  • 本文由 发表于 2022年4月16日 17:19:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/71892636.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定