英文:
How to write a simple custom HTTP server in Go?
问题
我是你的中文翻译助手,以下是你要翻译的内容:
我刚开始学习Go语言,尝试编写一个自定义的HTTP服务器。但是我遇到了一个编译错误。请问我该如何在代码中实现ServeHTTP
方法?
我的代码如下:
package main
import (
"net/http"
"fmt"
"io"
"time"
)
func myHandler(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "hello, world!\n")
}
func main() {
// 自定义http服务器
s := &http.Server{
Addr: ":8080",
Handler: myHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
err := s.ListenAndServe()
if err != nil {
fmt.Printf("服务器启动失败:%s", err.Error())
}
}
编译时出现的错误信息如下:
.\hello.go:21: cannot use myHandler (type func(http.ResponseWriter, *http.Request)) as type http.Handler in field value:
func(http.ResponseWriter, *http.Request) does not implement http.Handler (missing ServeHTTP method)
请问我该如何解决这个问题?
英文:
I am new to Go and trying to write a custom HTTP server. I'm getting a compilation error. How can I implement the ServeHTTP
method in my code?
My Code:
package main
import (
"net/http"
"fmt"
"io"
"time"
)
func myHandler(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "hello, world!\n")
}
func main() {
// Custom http server
s := &http.Server{
Addr: ":8080",
Handler: myHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
err := s.ListenAndServe()
if err != nil {
fmt.Printf("Server failed: ", err.Error())
}
}
Error while compiling:
<!-- language: lang-none -->
.\hello.go:21: cannot use myHandler (type func(http.ResponseWriter, *http.Request)) as type http.Handler in field value:
func(http.ResponseWriter, *http.Request) does not implement http.Handler (missing ServeHTTP method)
答案1
得分: 24
你可以使用结构体并在其上定义ServeHTTP
方法,或者简单地将你的函数包装在HandlerFunc
中。
s := &http.Server{
Addr: ":8080",
Handler: http.HandlerFunc(myHandler),
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
英文:
You either use a struct and define ServeHTTP
on it or simply wrap your function in a HandlerFunc
s := &http.Server{
Addr: ":8080",
Handler: http.HandlerFunc(myHandler),
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
答案2
得分: 6
为了使myHandler
正常工作,它应该是一个满足Handler接口的对象,换句话说,myHandler
应该有一个名为ServeHTTP
的方法。
例如,假设myHandler
是一个用于显示当前时间的自定义处理程序。代码应该如下所示:
package main
import (
"fmt"
"net/http"
"time"
)
type timeHandler struct {
zone *time.Location
}
func (th *timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
tm := time.Now().In(th.zone).Format(time.RFC1123)
w.Write([]byte("The time is: " + tm))
}
func newTimeHandler(name string) *timeHandler {
return &timeHandler{zone: time.FixedZone(name, 0)}
}
func main() {
myHandler := newTimeHandler("EST")
//自定义http服务器
s := &http.Server{
Addr: ":8080",
Handler: myHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
err := s.ListenAndServe()
if err != nil {
fmt.Printf("Server failed: ", err.Error())
}
}
运行此代码并在浏览器中访问http://localhost:8080/
。您应该看到如下格式化的文本:
The time is: Sat, 30 Aug 2014 18:19:46 EST
(您应该看到不同的时间。)
希望这可以帮到您。
更多阅读材料
英文:
in order to work properly, myHandler
should be an object that satisfy the Handler Interface, in other words myHandler
should have method called ServeHTTP
.
For example, let's say that myHandler
is custom handler for showing the current time. The code should be like this
package main
import (
"fmt"
"net/http"
"time"
)
type timeHandler struct {
zone *time.Location
}
func (th *timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
tm := time.Now().In(th.zone).Format(time.RFC1123)
w.Write([]byte("The time is: " + tm))
}
func newTimeHandler(name string) *timeHandler {
return &timeHandler{zone: time.FixedZone(name, 0)}
}
func main() {
myHandler := newTimeHandler("EST")
//Custom http server
s := &http.Server{
Addr: ":8080",
Handler: myHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
err := s.ListenAndServe()
if err != nil {
fmt.Printf("Server failed: ", err.Error())
}
}
run this code and access http://localhost:8080/
in your browser. you should see formatted text like this
The time is: Sat, 30 Aug 2014 18:19:46 EST
(you should see different time.)
hope this help,
Further more reading
答案3
得分: 4
你还可以在将mux分配给服务器之前,定义一个mux并为其添加处理程序,如下所示。
func myHandler(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "hello, world!\n")
}
func main(){
// 定义一个serveMux来处理路由
mux := http.NewServeMux()
// 将路由/todo分配给处理程序myHandler
mux.HandleFunc("/todo", myHandler)
// 将路由/todo/notes分配给匿名函数
mux.HandleFunc("/todo/notes", func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("Hello again."))
})
s := &http.Server{
Addr: ":8080",
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
if err := s.ListenAndServe(); err != nil {
log.Fatalf("server failed to start with error %v", err.Error())
}
}
英文:
You could also define a mux and add handlers to it before assigning it to the server like below.
func myHandler(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "hello, world!\n")
}
func main(){
// define a serveMux to handle routes
mux := http.NewServeMux()
// assign a route/todo to a handler myHandler
mux.HandleFunc("/todo", myHandler)
// assign a route/todo/notes to an anonymous func
mux.HandleFunc("/todo/notes", func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("Hello again."))
})
s := &http.Server{
Addr: ":8080",
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
if err := s.ListenAndServe(); err != nil {
log.Fatalf("server failed to start with error %v", err.Error())
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论