当前位置: 首页 > news >正文

天津做网站那家好东乌珠穆沁旗网站建设

天津做网站那家好,东乌珠穆沁旗网站建设,青岛官网seo,wordpress装饰设计主题通过go语言原生http中响应错误的实现方法#xff0c;逐步了解和使用微服务框架 kratos 的错误处理方式#xff0c;以及探究其实现原理。 一、go原生http响应错误信息的处理方法 处理方法#xff1a; ①定义返回错误信息的结构体 ErrorResponse // 定义http返回错误信息的… 通过go语言原生http中响应错误的实现方法逐步了解和使用微服务框架 kratos 的错误处理方式以及探究其实现原理。 一、go原生http响应错误信息的处理方法 处理方法 ①定义返回错误信息的结构体 ErrorResponse // 定义http返回错误信息的结构体 type ErrorResponse struct {Code int json:codeMessage string json:message } ②根据业务逻辑为结构体赋值相应的错误信息 //这里为了简化函数不进行业务逻辑判断而直接返回错误信息 er : ErrorResponse{Code: 403,Message: 用户名不能为空, } ③将错误信息序列化并写入到 http.ResponseWriter 中 // 设置响应头为JSON类型 w.Header().Set(Content-Type, application/json)// 设置响应状态码为400 w.WriteHeader(http.StatusBadRequest)// 将ErrorResponse转换为JSON并写入响应体 //json.NewEncoder(w).Encode(he)//将错误信息结构体序列化并返回 res, _ : json.Marshal(er) w.Write(res) 代码示例 package mainimport (encoding/jsonnet/http )// 定义http返回错误信息的结构体 type ErrorResponse struct {Code int json:codeMessage string json:message }func Login(w http.ResponseWriter, r *http.Request) {//这里为了简化函数不进行业务逻辑判断而直接返回错误信息er : ErrorResponse{Code: 403,Message: 用户名不能为空,}// 设置响应头为JSON类型w.Header().Set(Content-Type, application/json)// 设置响应状态码为400w.WriteHeader(http.StatusBadRequest)// 将ErrorResponse转换为JSON并写入响应体//json.NewEncoder(w).Encode(he)//将错误信息结构体序列化并返回res, _ : json.Marshal(er)w.Write(res) }func main() {//创建一个 HTTP 请求路由器mux : http.NewServeMux()mux.Handle(/login, http.HandlerFunc(Login))http.ListenAndServe(:8081, mux) } 效果演示 二、微服务框架kratos响应错误的方式 Kratos官网有关错误处理的介绍错误处理 | Kratos Kratos 有关错误处理的 examples 代码见examples/errors 、examples/http/errors 1、kratos默认的错误信息格式 kratos响应错误信息的默认JSON格式为: {// 错误码跟 http-status 一致并且在 grpc 中可以转换成 grpc-statuscode: 500,// 错误原因定义为业务判定错误码reason: USER_NOT_FOUND,// 错误信息为用户可读的信息可作为用户提示内容message: invalid argument error,// 错误元信息为错误添加附加可扩展信息metadata: {foo: bar} } 使用方法 ①导入 kratos 的 errors 包 import github.com/go-kratos/kratos/v2/errors ②在业务逻辑中需要响应错误时用 New 方法生成错误信息或通过 proto 生成的代码响应错误 注意这里的 New 方法是 Kratos 框架中的 errros.New而不是 go 原生的 errors.New func NewLoginRequest(username, password string) (*LoginRequest, error) {// 校验参数if username {//通过 New 方法创建一个错误信息err : errors.New(500, USER_NAME_EMPTY, 用户名不能为空)// 传递metadataerr err.WithMetadata(map[string]string{ remark: 请求参数中的 phone 字段为空,})return nil, err}if password {// 通过 proto 生成的代码响应错误并且包名应替换为自己生成代码后的 package name return nil, api.ErrorPasswordIsEmpty(密码不能为空)}return LoginRequest{username: username,password: password,}, nil } 返回结果 2、自定义错误信息格式 如果不想使用 kratos 默认的错误响应格式可以自定义错误信息处理格式方法如下 ①自定义错误信息结构体 type HTTPError struct {Code int json:codeMessage string json:messageMoreInfo string json:moreInfo } ②实现 FromError、errorEncoder 等方法 func (e *HTTPError) Error() string {return fmt.Sprintf(HTTPError code: %d message: %s, e.Code, e.Message) }// FromError try to convert an error to *HTTPError. func FromError(err error) *HTTPError {if err nil {return nil}if se : new(HTTPError); errors.As(err, se) {return se}return HTTPError{Code: 500} }func errorEncoder(w stdhttp.ResponseWriter, r *stdhttp.Request, err error) {se : FromError(err)codec, _ : http.CodecForRequest(r, Accept)body, err : codec.Marshal(se)if err ! nil {w.WriteHeader(500)return}w.Header().Set(Content-Type, application/codec.Name())w.WriteHeader(se.Code)_, _ w.Write(body) } ③创建 http.Server 时使用函数 http.ErrorEncoder() 将上述 errorEncoder 添加到 ServerOption 中 httpSrv : http.NewServer(http.Address(:8000),http.ErrorEncoder(errorEncoder), ) ④业务逻辑中需要响应错误的地方返回自定义消息对象 return HTTPError{Code: 400, Message: 用户名不存在, MoreInfo: 请求参数中 userName 张三} 完整代码示例为 package mainimport (errorsfmtlogstdhttp net/httpgithub.com/go-kratos/kratos/v2github.com/go-kratos/kratos/v2/transport/http )// HTTPError is an HTTP error. type HTTPError struct {Code int json:codeMessage string json:messageMoreInfo string json:moreInfo }func (e *HTTPError) Error() string {return fmt.Sprintf(HTTPError code: %d message: %s, e.Code, e.Message) }// FromError try to convert an error to *HTTPError. func FromError(err error) *HTTPError {if err nil {return nil}if se : new(HTTPError); errors.As(err, se) {return se}return HTTPError{Code: 500} }func errorEncoder(w stdhttp.ResponseWriter, r *stdhttp.Request, err error) {se : FromError(err)codec, _ : http.CodecForRequest(r, Accept)body, err : codec.Marshal(se)if err ! nil {w.WriteHeader(500)return}w.Header().Set(Content-Type, application/codec.Name())w.WriteHeader(se.Code)_, _ w.Write(body) }func main() {httpSrv : http.NewServer(http.Address(:8082),http.ErrorEncoder(errorEncoder),)router : httpSrv.Route(/)router.GET(login, func(ctx http.Context) error {return HTTPError{Code: 400, Message: 用户名不存在, MoreInfo: 请求参数中 userName 张三}})app : kratos.New(kratos.Name(mux),kratos.Server(httpSrv,),)if err : app.Run(); err ! nil {log.Fatal(err)} }返回结果 3、kratos返回错误信息JSON的源码探究 至此了解了 go 原生 http 和微服务框架 kratos 响应错误信息的处理方式对比可发现 ①在原生http响应处理中我们先将错误消息结构体序列化 res, _ : json.Marshal(er)然后通过 http.ResponseWriter.Write(res) 写入错误信息JSON并返回 ②在 kratos 中我们在业务处理函数中仅仅通过 return errors.New() 返回了一个 error并没有将其序列化但整个http请求却返回了一个有关错误信息的 json 字符串 是什么原因呢原来是 kratos 框架内部完成了将错误信息结构体序列化并写入http.ResponseWriter的过程。 具体实现方式如下 http server 结构体 Server 中含有一个字段 ene EncodeErrorFunc专门用来进行错误处理 //http/server.go // Server is an HTTP server wrapper. type Server struct {*http.Serverlis net.ListenertlsConf *tls.Configendpoint *url.URLerr errornetwork stringaddress stringtimeout time.Durationfilters []FilterFuncmiddleware matcher.MatcherdecVars DecodeRequestFuncdecQuery DecodeRequestFuncdecBody DecodeRequestFuncenc EncodeResponseFuncene EncodeErrorFunc // 用于错误处理strictSlash boolrouter *mux.Router }//http/codec.go // EncodeErrorFunc is encode error func. type EncodeErrorFunc func(http.ResponseWriter, *http.Request, error) 使用 NewServer() 创建时 http Server 时ene 属性会默认为 DefaultErrorEncoder该函数会将序列化错误信息并写入到 http.ResponseWriter 中 //http/server.go // NewServer creates an HTTP server by options. func NewServer(opts ...ServerOption) *Server {srv : Server{network: tcp,address: :0,timeout: 1 * time.Second,middleware: matcher.New(),decVars: DefaultRequestVars,decQuery: DefaultRequestQuery,decBody: DefaultRequestDecoder,enc: DefaultResponseEncoder,ene: DefaultErrorEncoder, //默认的错误处理函数strictSlash: true,router: mux.NewRouter(),}for _, o : range opts {o(srv)}srv.router.StrictSlash(srv.strictSlash)srv.router.NotFoundHandler http.DefaultServeMuxsrv.router.MethodNotAllowedHandler http.DefaultServeMuxsrv.router.Use(srv.filter())srv.Server http.Server{Handler: FilterChain(srv.filters...)(srv.router),TLSConfig: srv.tlsConf,}return srv }//http/codec.go // DefaultErrorEncoder encodes the error to the HTTP response. func DefaultErrorEncoder(w http.ResponseWriter, r *http.Request, err error) {se : errors.FromError(err)codec, _ : CodecForRequest(r, Accept)body, err : codec.Marshal(se) //序列化错误信息结构体if err ! nil {w.WriteHeader(http.StatusInternalServerError)return}w.Header().Set(Content-Type, httputil.ContentType(codec.Name()))w.WriteHeader(int(se.Code))_, _ w.Write(body) //将序列化的结果写入到响应中 }路由处理函数 router.GET() 等会调用 Router.Handle 其中会判断 HandlerFunc 是否有返回错误如果有则会调用 server.ene 函数从而完成错误信息序列化并返回 //main.go func main() {httpSrv : http.NewServer(http.Address(:8082),)router : httpSrv.Route(/)router.GET(login, func(ctx http.Context) error {return errors.New(500, USER_NOT_FOUND, 用户名不存在)}) }//http/router.go // GET registers a new GET route for a path with matching handler in the router. func (r *Router) GET(path string, h HandlerFunc, m ...FilterFunc) {r.Handle(http.MethodGet, path, h, m...) }//http/router.go // Handle registers a new route with a matcher for the URL path and method. func (r *Router) Handle(method, relativePath string, h HandlerFunc, filters ...FilterFunc) {next : http.Handler(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {ctx : r.pool.Get().(Context)ctx.Reset(res, req)//重点这里判断路由处理函数是否返回了 error如果是则调用 server.ene 函数序列化错误信息并返回if err : h(ctx); err ! nil {r.srv.ene(res, req, err)}ctx.Reset(nil, nil)r.pool.Put(ctx)}))next FilterChain(filters...)(next)next FilterChain(r.filters...)(next)r.srv.router.Handle(path.Join(r.prefix, relativePath), next).Methods(method) } 自定义错误消息结构体后创建 http server 时通过 http.ErrorEncoder(errorEncoder) 将自定义的错误处理函数赋值给 server.ene替换了默认的 DefaultErrorEncoder // main.go //自定义的错误处理函数 func errorEncoder(w stdhttp.ResponseWriter, r *stdhttp.Request, err error) {se : FromError(err)codec, _ : http.CodecForRequest(r, Accept)body, err : codec.Marshal(se)if err ! nil {w.WriteHeader(500)return}w.Header().Set(Content-Type, application/codec.Name())w.WriteHeader(se.Code)_, _ w.Write(body) }// main.go func main() {httpSrv : http.NewServer(http.Address(:8082),http.ErrorEncoder(errorEncoder), // 将自定义的错误处理函数赋值给 sever) }// http/server.go // ErrorEncoder with error encoder. func ErrorEncoder(en EncodeErrorFunc) ServerOption {return func(o *Server) {o.ene en} }
http://www.hkea.cn/news/14357449/

相关文章:

  • 临沂免费自助建站模板9 1短视频安装
  • html网站如何更新wordpress 4.7 多站点
  • 哪家网站制作 优帮云石家庄信息门户网站定制
  • 上海网站建设高端定制windows优化大师的功能
  • 灯笼制作手工简单又漂亮拼多多标题优化软件
  • html网站开发语言wordpress搭论坛
  • 苏州企业网站开发企业网站建设需注意点
  • 吉林省城乡建设官方网站网站建设推广营销策划
  • 怎么做链接网站自豪地采用wordpress
  • 做网站哪住房和城乡建设部网站规范答疑
  • 怎么发布自己的网站将网站建设外包出去的好处
  • 企业网站建设的一般要素包括找人做网站注意
  • 傻瓜网站制作天津的公司能在北京做网站备案吗
  • 商业网站大全上海那家公司做响应式网站建设
  • 高端网站设计合肥网站建设一般建设企业网站的费用
  • 金桥网站建设石家庄小程序开发多少钱
  • 南充免费推广网站网站制作技术
  • 谷歌浏览器 安卓下载seo人员是什么意思
  • 上海史特做网站多少钱中文网站排行榜
  • 手机微网站与微官网广州网站建设是什么
  • 创建自己的网站wordpress 头像本地化
  • 简述企业网站维护的重要性wordpress菜单左对齐
  • 青岛高级网站建设服务网站重大建设项目公开发布制度
  • 网站建设教程所需文字做网站时如何写接口文档
  • 网络优化网站建设专门做ppt背景的网站有哪些
  • 浙江网站建设营销简单详细搭建网站教程
  • 请打开网站网站推广的英文content
  • 网站怎么描述网站图片加alt标签
  • 塘厦做网站网站开发 图片
  • 企业网站建立制作wordpress可视化文章