当前位置: 首页 > 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.hkea.cn/news/14305250/

相关文章:

  • 商城建站流程天津站内关键词优化
  • 建设行业门户网站需要什么条件单位网站建设目的
  • 高埗网站建设公司装修公司最怕三种人
  • 信息产业部网站备案大港网站建设公司
  • 网站推广的基本方法有哪些织梦网站每天被挂马
  • 网站统计访客数量怎么做广州开展线上教学
  • 网站论坛源码自己做一个小程序要多少钱
  • 关于做网站的文献综述网站建设一般多少钱比较合适
  • 电子商务网站建设内容上海环球金融中心观光厅
  • 网站流量查询站长之家在线教育网站开发
  • asp网站建设代码汕头建设工程总公司
  • 网站建设读书笔记网页商城设计商城网站设计案例
  • phpcms 怎么做视频网站网站可分为哪两种类型
  • 网站设计公司网站佛山专业建站公司哪家好
  • 临桂区建设局网站导航网站后台源码
  • 上海域邦建设集团网站设计制作图片
  • 那些网站做推广php网站空间支持
  • 南昌制作网站的公司wordpress主题付费下载
  • 百度云做网站空间华龙网重庆
  • 池州做网站培训深圳搜索优化
  • 云南省建设厅网站人员查询百度推广一年收费标准
  • 中国建设银行官网站诚聘英才福安网站定制
  • 网站开发前景如何域名注销期间网站还能打开吗
  • 用jsp做网站的感想win7安装wordpress
  • 牡丹江网站seo网站建设怎么找客源
  • 电子商务网站建设与实践上机指导网站流量如何赚钱
  • 网站优化 seo和sem电商网站有哪些使用场景
  • 温州教育网站建设青岛网站搜索排名
  • 怎么知道网站用什么软件做的江门众瞬网络科技有限公司
  • 设计与制作网站郑州电力高等专科学校面试问题