func NewEncoder(opts ...Options) martini.Handler { return func(c martini.Context, w http.ResponseWriter) { wrappedWriter := newWrappedResponseWriter(w) c.MapTo(wrappedWriter, (*http.ResponseWriter)(nil)) c.MapTo(encoder.JsonEncoder{PrettyPrint: true}, (*encoder.Encoder)(nil)) var rtnHandler martini.ReturnHandler rtnHandler = func(ctx martini.Context, vals []reflect.Value) { rv := ctx.Get(inject.InterfaceOf((*http.ResponseWriter)(nil))) res := rv.Interface().(http.ResponseWriter) var responseVal reflect.Value if len(vals) > 1 && vals[0].Kind() == reflect.Int { res.WriteHeader(int(vals[0].Int())) responseVal = vals[1] } else if len(vals) > 0 { responseVal = vals[0] } if isNil(responseVal) { wrappedRes := res.(*wrappedResponseWriter) code := wrappedRes.statusCode if code == 0 { panic(errors.New("No return code set for error")) } responseVal = reflect.ValueOf(errorResponse{Error: code, Message: http.StatusText(code)}) } if canDeref(responseVal) { responseVal = responseVal.Elem() } if isByteSlice(responseVal) { res.Write(responseVal.Bytes()) } else if isStruct(responseVal) || isStructSlice(responseVal) { encv := ctx.Get(inject.InterfaceOf((*encoder.Encoder)(nil))) enc := encv.Interface().(encoder.Encoder) res.Header().Set("Content-Type", "application/json; charset=utf-8") buf := bytes.NewBuffer(encoder.Must(enc.Encode(responseVal.Interface()))) if len(opts) > 0 { if opts[0].Html { val := buf.Bytes() buf.Reset() json.HTMLEscape(buf, val) } if opts[0].Indent { val := buf.Bytes() buf.Reset() json.Indent(buf, val, "", "\t") } } res.Write(buf.Bytes()) } else { res.Write([]byte(responseVal.String())) } } c.Map(rtnHandler) } }
func main() { fmt.Println(inject.InterfaceOf((*interface{})(nil))) //output interface{} fmt.Println(inject.InterfaceOf((*SpecialString)(nil))) fmt.Println(reflect.TypeOf((*SpecialString)(nil))) //output main.SpecialString //如果不传指针类型的话,会报panic //下面这两个都不行 //fmt.Println(inject.InterfaceOf(1)) //fmt.Println(inject.InterfaceOf((*int)(nil))) }
func Test_InterfaceOf(t *testing.T) { iType := inject.InterfaceOf((*SpecialString)(nil)) expect(t, iType.Kind(), reflect.Interface) // Expecting nil defer func() { rec := recover() refute(t, rec, nil) }() iType = inject.InterfaceOf((*testing.T)(nil)) }
// ReturnHandler is a service that is called when a route handler returns // something. The ReturnHandler is responsible for writing to the // ResponseWriter based on the values that are passed into this function. func ReturnHandler() martini.ReturnHandler { return func(ctx martini.Context, vals []reflect.Value) { rv := ctx.Get(reflect.TypeOf((*http.Request)(nil))) req := rv.Interface().(*http.Request) acceptType := req.Header.Get("Accept") rv = ctx.Get(inject.InterfaceOf((*http.ResponseWriter)(nil))) res := rv.Interface().(http.ResponseWriter) var responseVal reflect.Value if len(vals) > 1 && vals[0].Kind() == reflect.Int { res.WriteHeader(int(vals[0].Int())) responseVal = vals[1] } else if len(vals) > 0 { responseVal = vals[0] } if strings.Contains(acceptType, "json") { res.Header().Set("Content-Type", "application/json; charset=utf-8") data, err := json.Marshal(responseVal.Interface()) if err == nil { res.Write(data) } } else if strings.Contains(acceptType, "xml") { res.Header().Set("Content-Type", "application/xml; charset=utf-8") data, err := xml.Marshal(responseVal.Interface()) if err == nil { res.Write(data) } } else { if stringer, ok := responseVal.Interface().(fmt.Stringer); ok { res.Write([]byte(stringer.String())) } } } }
func defaultReturnHandler() ReturnHandler { return func(ctx Context, vals []reflect.Value) { rv := ctx.Get(inject.InterfaceOf((*http.ResponseWriter)(nil))) res := rv.Interface().(http.ResponseWriter) var responseVal reflect.Value if len(vals) > 1 && vals[0].Kind() == reflect.Int { res.WriteHeader(int(vals[0].Int())) responseVal = vals[1] } else if len(vals) > 0 { responseVal = vals[0] } if canDeref(responseVal) { responseVal = responseVal.Elem() } if isByteSlice(responseVal) { res.Write(responseVal.Bytes()) } else { jsonBody, err := json.Marshal(responseVal.Interface()) if err != nil { res.Write([]byte(responseVal.String())) } else { res.Write(jsonBody) } } } }
func TestInjectImplementors(t *testing.T) { injector := inject.New() g := &Greeter{"Jeremy"} injector.Map(g) expect(t, injector.Get(inject.InterfaceOf((*fmt.Stringer)(nil))).IsValid(), true) }
func newReturnHandler() martini.ReturnHandler { return func(ctx martini.Context, vals []reflect.Value) { rv := ctx.Get(inject.InterfaceOf((*http.ResponseWriter)(nil))) res := rv.Interface().(http.ResponseWriter) resp := vals[0] if canDeref(resp) { resp = resp.Elem() } asserted, ok := resp.Interface().(response) if !ok { panic("Controller must return a response.") } // write the headers type BEFORE writing anything else, or else the gzip // middleware would set an autodetected header, which would be "app/x-gzipped". contentType := "text/html" content := asserted.Content if asserted.Status == 302 { res.Header().Set("Location", asserted.Content) content = "You are being redirected to " + asserted.Content contentType = "text/plain" } res.Header().Set("Content-Type", contentType+"; charset=utf-8") res.WriteHeader(asserted.Status) res.Write([]byte(content)) } }
// Recovery returns a middleware that recovers from any panics and writes a 500 if there was one. // While Martini is in development mode, Recovery will also output the panic as HTML. func Recovery() Handler { return func(c Context, log *log.Logger) { defer func() { if err := recover(); err != nil { stack := stack(3) log.Printf("PANIC: %s\n%s", err, stack) // Lookup the current responsewriter val := c.Get(inject.InterfaceOf((*http.ResponseWriter)(nil))) res := val.Interface().(http.ResponseWriter) // respond with panic message while in development mode var body []byte if Env == Dev { res.Header().Set("Content-Type", "text/html") body = []byte(fmt.Sprintf(panicHtml, err, err, stack)) } res.WriteHeader(http.StatusInternalServerError) if nil != body { res.Write(body) } } }() c.Next() } }
func Test_InjectorSetParent(t *testing.T) { injector := inject.New() injector.MapTo("another dep", (*SpecialString)(nil)) injector2 := inject.New() injector2.SetParent(injector) expect(t, injector2.Get(inject.InterfaceOf((*SpecialString)(nil))).IsValid(), true) }
func RestPostHandler() martini.Handler { return func(c martini.Context, rw http.ResponseWriter, req *http.Request) { defer func(c martini.Context, rw http.ResponseWriter, req *http.Request) { restErrorVal := c.Get(inject.InterfaceOf((*error)(nil))) restResultVal := c.Get(inject.InterfaceOf((*RestResult)(nil))) //no rest func if !restErrorVal.IsValid() && !restResultVal.IsValid() { return } restReturnObj := &RestReturnObj{} if restErrorVal.IsValid() { restErrorObj := restErrorVal.Interface().(*RestError) restReturnObj.ErrorCode = restErrorObj.ErrorCode } else { restResultObj := restResultVal.Interface().(RestResult) restReturnObj.ErrorCode = 0 restReturnObj.Result = restResultObj } rw.Header().Set("Access-Control-Allow-Origin", "*") rw.Header().Set("Content-Type", "application/json; charset=utf-8") content, err := json.Marshal(restReturnObj) if err != nil { panic("encode error") } rw.WriteHeader(http.StatusOK) rw.Write(content) }(c, rw, req) c.Next() } }
func (r *routeContext) run() { for r.index < len(r.handlers) { handler := r.handlers[r.index] vals, err := r.Invoke(handler) if err != nil { panic(err) } r.index += 1 // if the handler returned something, write it to the http response if len(vals) > 0 { rv := r.Get(inject.InterfaceOf((*http.ResponseWriter)(nil))) ev := r.Get(reflect.TypeOf(ReturnHandler(nil))) handleReturn := ev.Interface().(ReturnHandler) handleReturn(rv.Interface().(http.ResponseWriter), vals) } if r.written() { return } } }
func main() { ij := inject.New() ij.Map(20) ij.MapTo("Good Morning", (*MyString)(nil)) ij1 := inject.New() ij1.Map("Steven") ij.SetParent(ij1) ij.Invoke(Hello) fmt.Println(inject.InterfaceOf((*MyString)(nil))) team := MyStruct{} ij2 := inject.New() ij2.Map("Liverpool LFC") ij2.MapTo("England", (*MyString)(nil)) ij2.Apply(&team) fmt.Printf("TEAM NAME: %s \n", team.Name) fmt.Printf("TEAM TEAM: %s \n", team.Team) fmt.Printf("TEAM LOCATION: %s \n", team.Location) }
func (r *routeContext) run() { for r.index < len(r.handlers) { handler := r.handlers[r.index] vals, err := r.Invoke(handler) if err != nil { panic(err) } r.index += 1 // if the handler returned something, write it to // the http response rv := r.Get(inject.InterfaceOf((*http.ResponseWriter)(nil))) res := rv.Interface().(http.ResponseWriter) if len(vals) > 1 && vals[0].Kind() == reflect.Int { res.WriteHeader(int(vals[0].Int())) res.Write([]byte(vals[1].String())) } else if len(vals) > 0 { res.Write([]byte(vals[0].String())) } if r.written() { return } } }
func getDependency(m *martini.Martini, i interface{}) interface{} { return m.Get(inject.InterfaceOf(i)).Interface() }