grpc服务端转换protobuf到http请求参数query

前提

grpc服务接收到request的请求后,需要把参数转换成http,去请求其他接口。

使用go作为grpc的服务端,数据协议是protobuf

想到的几种解决方案:

  • 1.编译好的pb.go文件里有个string(),可以把所有参数都打印出来,参数之间是空格隔开的,参数和值是k:v的形式,但是不带引号,不是json格式
  • 2.把接收到的数据转换为json,直接以json的格式,发送请求
  • 3.根据传过来的request反射到固定的struct上,得到具体的属性和获取此属性的方法,再加入到url.values{},再encode()发送请求

实现

方案1

方案1是比较简单的,用空格分割,得到参数和值,再根据":"分割得到参数、值,再加入到url.values{}

代码如下:

param := url.Values{}
//得到请求的字符串形式
rs := strings.Split(request.String(), " ")
    for _, v := range rs {
        if v != "" {
            vv := strings.Split(v, ":")
            param.Add(vv[0], strings.Trim(vv[1], "\""))
            vv := strings.SplitN(v, ":", 2)
            //转换成
            val, e := strconv.Unquote(vv[1])
            log.Print(val, e)
            if e == nil {
                param.Add(vv[0], val)
            }
        }
    }

前期运行OK,后期遇到了两个问题:

  • 1.提交的值里有空格时,分割会有问题
  • 2.得到的中文是utf8字符

放弃方案1

方案2

把数据先转成json,再解析成map[string]string 的形式,目的是为了省去值都转换为string

str, _ := json.Marshal(request)
    jsonstr := string(str)

    m := make(map[string]interface{})
    e := json.Unmarshal([]byte(jsonstr), &m)
    param := url.Values{}
    if e != nil {
        return param
    }

    for k, v := range m {
        sv := fmt.Sprint(v)
        param.Add(k, sv)
    }

结果:对于中文还有空格的问题是解决了,不过会把int64的数字类型转换成float类型,转换有问题

方案3

根据go的reflect包反射出实际的struct,go编译pb的文件里struct里属性名和proto文件不一样,需要根据属性的tag得到实际的参数名

代码如下:

    ty := reflect.TypeOf(request).Elem()
    #得到struct的属性数量
    fieldnum := ty.NumField()

    #实际数据的指针
    ob := reflect.ValueOf(request)
    param := url.Values{}
    #由于编译好的属性最后3位不用
    for i := 0; i < fieldnum-3; i++ {
        f := ty.Field(i).Tag.Get("json")
        fv := strings.Split(f, ",")
        k := fv[0]

        fieldname := ty.Field(i).Name
        ret := ob.MethodByName("Get" + fieldname).Call(nil)
        if !ret[0].IsZero() {
            # 这一步,用了很巧的办法把各个类型转换成了string才能加入到param里
            v := fmt.Sprint(ret[0])
            param.Add(k, v)
        }
    }
    return param

原文地址:https://www.cnblogs.com/efan/p/12061823.html

时间: 2024-10-24 05:43:20

grpc服务端转换protobuf到http请求参数query的相关文章

grpc(3):使用 golang 开发 grpc 服务端和客户端

1,关于grpc-go golang 可以可以做grpc的服务端和客户端. 官网的文档: http://www.grpc.io/docs/quickstart/go.html https://github.com/grpc/grpc-go 和之前写的java的grpc客户端调用相同.也需要使用protobuf的配置文件. 但是golang下面的类库非常的简单,而且golang的性能也很强悍呢. 有些简单的业务逻辑真的可以使用golang进行开发. 性能强悍而且,消耗的资源也很小.java感觉上已

Unity3D客户端和Java服务端使用Protobuf

原文:http://blog.csdn.net/kakashi8841/article/details/17334493 前几天有位网友问我关于Unity3D里面使用Protobuf的方法,一时有事拖到现在才写这篇文章,不好意思哈. 本文测试环境: 系统:WINDOWS 7(第3.6步).OS X 10.9(第4步) 软件:VS 2012(第3.6步).Eclipse(第5.6步) 硬件:iPad 2(第4步).Macbook Pro Mid 2012(第4步) 文章目录: 1.关于Protob

grpc(3):使用 golang 开发 grpc 服务端和client

1,关于grpc-go golang 能够能够做grpc的服务端和client. 官网的文档: http://www.grpc.io/docs/quickstart/go.html https://github.com/grpc/grpc-go 和之前写的java的grpcclient调用同样.也须要使用protobuf的配置文件. 可是golang以下的类库很的简单.并且golang的性能也很强悍呢. 有些简单的业务逻辑真的能够使用golang进行开发. 性能强悍并且.消耗的资源也很小. ja

[.Net Core] - 在 .NET Core 中创建 gRPC 服务端和客户端

gRPC 官网:https://grpc.io/ 1. 创建服务端 1.1 基于 ASP.NET Core Web 应用程序模板创建 gRPC Server 项目. 1.2 编译并运行 2. 创建客户端 2.1 基于控制台应用程序模板创建 gRPC Client 项目,并安装 Nuget 包(Google.Protobuf,Grpc,Grpc.Core,Grpc.Tools). 2.2 拷贝 Server 项目中的 Protos/greet.proto 文件到 Client 项目中 2.3 更新

zookeeper源码分析之五服务端(集群leader)处理请求流程

leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcessor -> ProposalRequestProcessor ->CommitProcessor -> Leader.ToBeAppliedRequestProcessor ->FinalRequestProcessor 具体情况可以参看代码: @Override protected v

Http协议:客户端提交数据给服务端和从服务端获得数据,像WebView也是向百度的服务端发出一条Http请求,服务端返回HTML页面,客户端(浏览器)解析后展示出页面

提交数据和获得数据的方式有很多,这里介绍一种,使用HttpURLConnection来向服务器提交数据或者获得数据. 获得数据: //传入网址,获得请求网页数据(XML文件数据或JSON文件数据) public static String sendHttpRequest(String address) { HttpURLConnection connection=null; try { URL url=new URL(address); connection=(HttpURLConnection

spring 请求参数和路径变量

请求参数和路径变量:客户端传递参数给服务端的两种方式 请求参数可以发送值传递给服务器,请求参数采用key=value的形式并使用“&”符号进行参数间的分隔,例如: http://localhost:8080/springmvc/user?name=yu&password=123456. 传递过来的值Spring MVC需要解析,采用@RequestParam的形式来注释方法中的参数,获取上面两个参数的方法为: Public void login(@RequestParam String n

jQuery通过Ajax向PHP服务端发送请求并返回JSON数据

ON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写,同时也易于机器解析和生成.JSON在前后台交互的过程中发挥着相当出色的作用.请接着往下看教程. XHTML  <ul id="userlist">    <li><a href="#" rel="1">张三</a></li>    <li><a href=&quo

微信开发SDK使用教程--手机微信有好友请求添加好友的通知服务端

微信开发SDK使用教程--手机微信有好友请求添加好友的通知服务端 case FriendAddReqeustNotice: {//有好友请求添加好友的通知 log.debug("socket:msgtype=FriendAddReqeustNotice"); friendAddReqeustNoticeHandler.handleMsg(ctx, msgVo); break; } package com.jubotech.framework.netty.handler.socket;