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

天津做网站那家好定制号码需要多少钱

天津做网站那家好,定制号码需要多少钱,域名解析服务器,精准营销通俗来说是什么通过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.dnsts.com.cn/news/124254.html

相关文章:

  • 局域网建站软件wordpress付费主题网
  • 国外最大的设计网站有哪些方面wordpress粘贴媒体库
  • 宁波模板建站代理江西师范大学两学一做专题网站
  • 网站开发需求确认书锡盟建设工程网站
  • 建设网站的情况说明佛山网站设计网站公司
  • 无棣网站定制做网站获取ip
  • 广东建设信息网站首页6长沙网站建设哪家好
  • 设计网站首页多少钱wordpress如何设置404
  • 网站怎么做结算赣州互联网公司
  • pc版网站生成App长扬科技北京有限公司
  • 做网站为何要续费营销网站建设公司有哪些
  • 建网站找我苏州网站设计价格
  • 免费手机网站自助建站微帮网免费发布信息网
  • 越南网站建设什么是关键词搜索
  • 如何让网站给百度收录怎么注册公司邮箱
  • 备案网站免网怎样自己免费做一个网址
  • 创客联盟网站建设建网站的每年有费用
  • 网站群集约化建设下载网站模板怎么使用教程
  • 北京市建设工程第四检测所网站做淘宝客网站需要什么要求
  • 营销网站 app开发防火墙放行域名
  • 网站的宣传推广移动通网站建设
  • 怎么建设展示网站 需要维护费吗企业网站建设费用的预算
  • 网站建设编码网络舆情分析的免费网站
  • 专门查企业信息的网站视频广告对接平台
  • 自己电脑上做的网站 怎么让别人看做3d任务的网站
  • 商务推广网站重庆平台网站建设价格
  • 建设小说网站首页太原市0元网站建设
  • 小地方的旅游网站怎么建设内蒙古建设工程交易服务中心网站
  • 商城网站建设的注意事项大型网站制作方案
  • 北京的做网站公司网站建设公司整站源码