1
0
mirror of https://github.com/labstack/echo.git synced 2025-01-16 02:33:26 +02:00

Added XML encoding/decoding API.

Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
Nicolas Pouvesle 2015-07-11 15:20:59 -04:00 committed by Vishal Rana
parent 62bc8575ce
commit 1757d1f8c7
6 changed files with 53 additions and 27 deletions

View File

@ -24,8 +24,9 @@ A fast and unfancy micro web framework for Golang.
- Handy functions to send variety of HTTP response: - Handy functions to send variety of HTTP response:
- HTML - HTML
- HTML via templates - HTML via templates
- JSON
- String - String
- JSON
- XML
- NoContent - NoContent
- Redirect - Redirect
- Error - Error

View File

@ -2,6 +2,7 @@ package echo
import ( import (
"encoding/json" "encoding/json"
"encoding/xml"
"net/http" "net/http"
"fmt" "fmt"
@ -111,7 +112,6 @@ func (c *Context) Render(code int, name string, data interface{}) (err error) {
c.response.Header().Set(ContentType, TextHTML) c.response.Header().Set(ContentType, TextHTML)
c.response.WriteHeader(code) c.response.WriteHeader(code)
if err = c.echo.renderer.Render(c.response, name, data); err != nil { if err = c.echo.renderer.Render(c.response, name, data); err != nil {
println(err.Error())
c.response.clear() c.response.clear()
} }
return return
@ -128,6 +128,17 @@ func (c *Context) HTML(code int, format string, a ...interface{}) (err error) {
return return
} }
// String formats according to a format specifier and sends text/plain response
// with status code.
func (c *Context) String(code int, format string, a ...interface{}) (err error) {
c.response.Header().Set(ContentType, TextPlain)
c.response.WriteHeader(code)
if _, err = fmt.Fprintf(c.response, format, a...); err != nil {
c.response.clear()
}
return
}
// JSON sends an application/json response with status code. // JSON sends an application/json response with status code.
func (c *Context) JSON(code int, i interface{}) (err error) { func (c *Context) JSON(code int, i interface{}) (err error) {
c.response.Header().Set(ContentType, ApplicationJSON) c.response.Header().Set(ContentType, ApplicationJSON)
@ -138,12 +149,12 @@ func (c *Context) JSON(code int, i interface{}) (err error) {
return return
} }
// String formats according to a format specifier and sends text/plain response // XML sends an application/xml response with status code.
// with status code. func (c *Context) XML(code int, i interface{}) (err error) {
func (c *Context) String(code int, format string, a ...interface{}) (err error) { c.response.Header().Set(ContentType, ApplicationXML)
c.response.Header().Set(ContentType, TextPlain)
c.response.WriteHeader(code) c.response.WriteHeader(code)
if _, err = fmt.Fprintf(c.response, format, a...); err != nil { c.response.Write([]byte(xml.Header))
if err = xml.NewEncoder(c.response).Encode(i); err != nil {
c.response.clear() c.response.clear()
} }
return return

View File

@ -10,6 +10,7 @@ import (
"strings" "strings"
"encoding/xml"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"net/url" "net/url"
) )
@ -25,8 +26,10 @@ func (t *Template) Render(w io.Writer, name string, data interface{}) error {
} }
func TestContext(t *testing.T) { func TestContext(t *testing.T) {
usr := `{"id":"1","name":"Joe"}` userJSON := `{"id":"1","name":"Joe"}`
req, _ := http.NewRequest(POST, "/", strings.NewReader(usr)) userXML := `<user><id>1</id><name>Joe</name></user>`
req, _ := http.NewRequest(POST, "/", strings.NewReader(userJSON))
rec := httptest.NewRecorder() rec := httptest.NewRecorder()
c := NewContext(req, NewResponse(rec), New()) c := NewContext(req, NewResponse(rec), New())
@ -58,17 +61,12 @@ func TestContext(t *testing.T) {
// JSON // JSON
testBind(t, c, ApplicationJSON) testBind(t, c, ApplicationJSON)
// TODO: Form // XML
c.request.Header.Set(ContentType, ApplicationForm) c.request, _ = http.NewRequest(POST, "/", strings.NewReader(userXML))
u := new(user) testBind(t, c, ApplicationXML)
err := c.Bind(u)
assert.NoError(t, err)
// Unsupported // Unsupported
c.request.Header.Set(ContentType, "") testBind(t, c, "")
u = new(user)
err = c.Bind(u)
assert.Error(t, err)
//-------- //--------
// Render // Render
@ -78,7 +76,7 @@ func TestContext(t *testing.T) {
templates: template.Must(template.New("hello").Parse("Hello, {{.}}!")), templates: template.Must(template.New("hello").Parse("Hello, {{.}}!")),
} }
c.echo.SetRenderer(tpl) c.echo.SetRenderer(tpl)
err = c.Render(http.StatusOK, "hello", "Joe") err := c.Render(http.StatusOK, "hello", "Joe")
if assert.NoError(t, err) { if assert.NoError(t, err) {
assert.Equal(t, http.StatusOK, rec.Code) assert.Equal(t, http.StatusOK, rec.Code)
assert.Equal(t, "Hello, Joe!", rec.Body.String()) assert.Equal(t, "Hello, Joe!", rec.Body.String())
@ -96,7 +94,18 @@ func TestContext(t *testing.T) {
if assert.NoError(t, err) { if assert.NoError(t, err) {
assert.Equal(t, http.StatusOK, rec.Code) assert.Equal(t, http.StatusOK, rec.Code)
assert.Equal(t, ApplicationJSON, rec.Header().Get(ContentType)) assert.Equal(t, ApplicationJSON, rec.Header().Get(ContentType))
assert.Equal(t, usr, strings.TrimSpace(rec.Body.String())) assert.Equal(t, userJSON, strings.TrimSpace(rec.Body.String()))
}
// XML
req.Header.Set(Accept, ApplicationXML)
rec = httptest.NewRecorder()
c = NewContext(req, NewResponse(rec), New())
err = c.XML(http.StatusOK, user{"1", "Joe"})
if assert.NoError(t, err) {
assert.Equal(t, http.StatusOK, rec.Code)
assert.Equal(t, ApplicationXML, rec.Header().Get(ContentType))
assert.Equal(t, xml.Header, xml.Header, rec.Body.String())
} }
// String // String
@ -175,7 +184,9 @@ func testBind(t *testing.T, c *Context, ct string) {
c.request.Header.Set(ContentType, ct) c.request.Header.Set(ContentType, ct)
u := new(user) u := new(user)
err := c.Bind(u) err := c.Bind(u)
if assert.NoError(t, err) { if ct == "" {
assert.Error(t, UnsupportedMediaType)
} else if assert.NoError(t, err) {
assert.Equal(t, "1", u.ID) assert.Equal(t, "1", u.ID)
assert.Equal(t, "Joe", u.Name) assert.Equal(t, "Joe", u.Name)
} }

View File

@ -14,6 +14,7 @@ import (
"strings" "strings"
"sync" "sync"
"encoding/xml"
"github.com/bradfitz/http2" "github.com/bradfitz/http2"
"github.com/mattn/go-colorable" "github.com/mattn/go-colorable"
"golang.org/x/net/websocket" "golang.org/x/net/websocket"
@ -90,11 +91,12 @@ const (
//------------- //-------------
ApplicationJSON = "application/json" ApplicationJSON = "application/json"
ApplicationXML = "application/xml"
ApplicationForm = "application/x-www-form-urlencoded"
ApplicationProtobuf = "application/protobuf" ApplicationProtobuf = "application/protobuf"
ApplicationMsgpack = "application/msgpack" ApplicationMsgpack = "application/msgpack"
TextPlain = "text/plain" TextPlain = "text/plain"
TextHTML = "text/html" TextHTML = "text/html"
ApplicationForm = "application/x-www-form-urlencoded"
MultipartForm = "multipart/form-data" MultipartForm = "multipart/form-data"
//--------- //---------
@ -176,8 +178,8 @@ func New() (e *Echo) {
err := UnsupportedMediaType err := UnsupportedMediaType
if strings.HasPrefix(ct, ApplicationJSON) { if strings.HasPrefix(ct, ApplicationJSON) {
err = json.NewDecoder(r.Body).Decode(v) err = json.NewDecoder(r.Body).Decode(v)
} else if strings.HasPrefix(ct, ApplicationForm) { } else if strings.HasPrefix(ct, ApplicationXML) {
err = nil err = xml.NewDecoder(r.Body).Decode(v)
} }
return err return err
}) })

View File

@ -18,8 +18,8 @@ import (
type ( type (
user struct { user struct {
ID string `json:"id"` ID string `json:"id" xml:"id"`
Name string `json:"name"` Name string `json:"name" xml:"name"`
} }
) )

View File

@ -26,8 +26,9 @@ A fast and unfancy micro web framework for Golang.
- Handy functions to send variety of HTTP response: - Handy functions to send variety of HTTP response:
- HTML - HTML
- HTML via templates - HTML via templates
- JSON
- String - String
- JSON
- XML
- NoContent - NoContent
- Redirect - Redirect
- Error - Error