Система маршрутизации позволяет сопоставить определенные запросы с определенными ресурсами внутри веб-приложения. Для создания протейшей системы маршуртизации в приложении может применяться функция HandleFunc().
func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
Ее преимущество состоит в том, что она позволяет указать маршруты для обработки. Первый параметр функции представляет маршрут, который будет обрабатываться данной функцией. А второй - функция handler, которая будет обрабатывать запрос. Она также принимает два параметра: ResponseWriter - поток ответа и *Request - информацию о запросе.
Например, определим следующий код в файле сервера:
package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/about", func(w http.ResponseWriter, r *http.Request){ fmt.Fprint(w, "About Page") }) http.HandleFunc("/contact", func(w http.ResponseWriter, r *http.Request){ fmt.Fprint(w, "Contact Page") }) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ fmt.Fprint(w, "Index Page") }) fmt.Println("Server is listening...") http.ListenAndServe("localhost:8181", nil) }
Первый аргумент функции HandleFunc - "/about", указывает, что эта функция будет обрабатывать запросы по пути "/about", то есть по адресу http://localhost:8181/about. Второй параметр указывает, что в ответ на запрос по этому пути пользователю будет отправляться строка "About Page".
Соответственно запрос по пути "/contact" будет обрабатываться функцией http.HandleFunc("/contact",..
,
а запрос к корню веб-сайта будет обрабатываться функцией http.HandleFunc("/",..
.
Причем подобным образом мы можем сопоставлять маршруты не только с функциями, которые возвращают некоторое содержимое в виде строки, но также мы можем сопоставлять маршруты со статическими файлами. Например, определим в папке с файлом сервера html-страницу hello.html со следующим кодом:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Index</title> </head> <body> <h1>Index</h1> </body> </html>
Изменим файл сервера:
package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request){ http.ServeFile(w, r, "hello.html") }) http.HandleFunc("/about", func(w http.ResponseWriter, r *http.Request){ fmt.Fprint(w, "About Page") }) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ fmt.Fprint(w, "Index Page") }) fmt.Println("Server is listening...") http.ListenAndServe(":8181", nil) }
С помощью функции http.ServeFile() при запросе по пути "/hello" будет отправляться файл hello.html:
Еще один способ определения маршрутов и сопоставления их с обработчиками представляет функция http.Handle:
func Handle(pattern string, handler Handler)
Например, определеим у сервера следующий код:
package main import ( "fmt" "net/http" ) type httpHandler struct{ message string } func (h httpHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { fmt.Fprint(resp, h.message) } func main() { h1 := httpHandler{ message:"Index"} h2 := httpHandler{ message:"About"} http.Handle("/", h1) http.Handle("/about", h2) fmt.Println("Server is listening...") http.ListenAndServe(":8181", nil) }
В данном случае в роли интерфейса Handler, который обрабатывает запрос, выступает структура httpHandler: