0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

go修行18日目 構造化されたWebサーバ

Last updated at Posted at 2020-07-09

構造化されたWebサーバ

メイン

main.go

package main

import (
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
)

type Page struct {
	Title string
	Body  []byte
}

func (p *Page) save() error {
	filename := p.Title + ".txt"
	return ioutil.WriteFile(filename, p.Body, 0600)
}

func loadPage(title string) (*Page, error) {
	filename := title + ".txt"
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return &Page{Title: title, Body: body}, nil
}

// htmlファイルのテンプレートを指定できる
// 直接書いてもいいけれどソースがわかりにくくなる
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
	// ローカルのhtmlファイルを指定
	t, _ := template.ParseFiles(tmpl + ".html")
	t.Execute(w, p)
}

func viewHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[len("/view/"):]
	p, err := loadPage(title)

	// もしエラー(ページがなかったら)editページへリダイレクトされる
	if err != nil {
		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
		return
	}
	renderTemplate(w, "view", p)
}

func editHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[len("/edit/"):]
	p, err := loadPage(title)
	if err != nil {
		p = &Page{Title: title}
	}
	renderTemplate(w, "edit", p)
}

func saveHandler(w http.ResponseWriter, r *http.Request) {
	title := r.URL.Path[len("/save/"):]
	body := r.FormValue("body")
	p := &Page{Title: title, Body: []byte(body)}
	err := p.save()
	// saveに失敗したら、500エラー
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, "/view/"+title, http.StatusFound)
}

func main() {
	http.HandleFunc("/view/", viewHandler)
	http.HandleFunc("/edit/", editHandler)
	http.HandleFunc("/save/", saveHandler)
	// /にアクセスしたり/view以外にアクセスすると404NOTFOUND
	log.Fatal(http.ListenAndServe(":8080", nil))
}


/editとなるhtmlファイル

edit.html

<h1>Editing {{.Title}}</h1>

<form action="/save/{{.Title}}" method="POST">
    <div>
        <textarea name="body" rows="20" cols="80">{{printf "%s" .Body}}</textarea>
    </div>
    <div>
        <input type="submit" value="Save">
    </div>
</form>

/viewとなるhmtlファイル

view.html
<h1>{{.Title}}</h1>

<p>[<a href="/edit/{{.Title}}">Edit</a>]</p>

<div>{{printf "%s" .Body}}</div>

動作確認

editページでhtmlファイル生成

image.png

/viewが一覧ページ

image.png

/view/test1などでアクセス

image.png

教材

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?