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:
- HTML
- HTML via templates
- JSON
- String
- JSON
- XML
- NoContent
- Redirect
- Error

View File

@ -2,6 +2,7 @@ package echo
import (
"encoding/json"
"encoding/xml"
"net/http"
"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.WriteHeader(code)
if err = c.echo.renderer.Render(c.response, name, data); err != nil {
println(err.Error())
c.response.clear()
}
return
@ -128,6 +128,17 @@ func (c *Context) HTML(code int, format string, a ...interface{}) (err error) {
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.
func (c *Context) JSON(code int, i interface{}) (err error) {
c.response.Header().Set(ContentType, ApplicationJSON)
@ -138,12 +149,12 @@ func (c *Context) JSON(code int, i interface{}) (err error) {
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)
// XML sends an application/xml response with status code.
func (c *Context) XML(code int, i interface{}) (err error) {
c.response.Header().Set(ContentType, ApplicationXML)
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()
}
return

View File

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

View File

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

View File

@ -18,8 +18,8 @@ import (
type (
user struct {
ID string `json:"id"`
Name string `json:"name"`
ID string `json:"id" xml:"id"`
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:
- HTML
- HTML via templates
- JSON
- String
- JSON
- XML
- NoContent
- Redirect
- Error