zoukankan      html  css  js  c++  java
  • webapi基于单请求封装多请求的设计【转】

    怎么说,单请求封装多请求,这句话确实有点绕了,但还是要看清楚,想明白这到底是怎么一回事,单请求即一次请求(get,post,put,delete),封闭多请求,即在客户端发送的一个请求中可能包含多个子请求(真实的请求,接口),这种设计确实看着很灵活,客户端可以根据自己的需要去拿服务器的数据,确实不错!

    首先我们要定义一套自己的请求和响应对象

     
    #region 请求对象
        /// <summary>
        /// 参数对象
        /// </summary>
        [DataContractAttribute]
        public class RequestParam
        {
            public RequestParam(string name, string value)
            {
                this.ParamName = name;
                this.ParamValue = value;
            }
            [DataMemberAttribute]
            public string ParamName { get; private set; }
            [DataMemberAttribute]
            public string ParamValue { get; private set; }
        }
        /// <summary>
        /// 数据包中的实体
        /// </summary>
        [DataContractAttribute]
        public class RequestData
        {
            public RequestData()
            {
                this.HttpMethod = 0;
                this.RequestParam = new Dictionary<string, string>();
            }
            /// <summary>
            /// 本次通讯唯一标示
            /// </summary>
            [DataMemberAttribute]
            public string GuidKey { get; set; }
            /// <summary>
            /// 请求方式0:get,1:Post
            /// </summary>
            public int HttpMethod { get; set; }
            /// <summary>
            /// 要调用的方法
            /// </summary>
            [DataMemberAttribute]
            public string Url { get; set; }
            /// <summary>
            /// 方法的参数列表
            /// </summary>
            [DataMemberAttribute]
            public IDictionary<string, string> RequestParam { get; set; }
        }
        /// <summary>
        /// 请求数据包
        /// </summary>
        [DataContractAttribute]
        public class RequestDataSegment
        {
            public RequestDataSegment()
            {
                this.RequestData = new List<RequestData>();
            }
            [DataMemberAttribute]
            public List<RequestData> RequestData { get; set; }
        }
        #endregion
     

    再来看一下响应对象

     
    #region 响应对象
        /// <summary>
        /// 数据包实体
        /// </summary>
        [DataContractAttribute]
        public class ResponseData
        {
            /// <summary>
            /// 本次传输过程中唯一标识
            /// </summary>
            [DataMemberAttribute]
            public string GuidKey { get; set; }
            /// <summary>
            /// 状态:100失败,200成功
            /// </summary>
            [DataMemberAttribute]
            public int Status { get; set; }
            /// <summary>
            /// 数据包:Json对象
            /// </summary>
            [DataMemberAttribute]
            public string Data { get; set; }
        }
        /// <summary>
        /// 响应数据包
        /// </summary>
        [DataContractAttribute]
        public class ResponseDataSegment
        {
            public ResponseDataSegment()
            {
                this.ResponseData = new List<ResponseData>();
            }
            [DataMemberAttribute]
            public List<ResponseData> ResponseData { get; set; }
        }
        #endregion
     

    而我们服务器对客户端开放的是一个大接口,或者叫入口接口,它负责把客户端传来的请求进行解析,然后代理客户端,处理多请求,并将结果进行组装,返回给客户端,在mvc和web api里,我们为了让程序扩展性更强,通常把这个核心逻辑写在attribute里

    下面看一下代码的实现 

     
        /// <summary>
        /// Api代理过滤器(api多任务请求的入口)
        /// </summary>
        [AttributeUsage(AttributeTargets.Method)]
        public class ApiProxyFilter : ActionFilterAttribute
        {
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                var Request = filterContext.HttpContext.Request;
                var responseDataSegment = new ResponseDataSegment();
                var data = VCommons.SerializeMemoryHelper.DeserializeFromJson<RequestDataSegment>(Request.Form["dataSeg"]);
                if (data != null && data.RequestData.Any())
                {
                    foreach (var item in data.RequestData)
                    {
                        try
                        {
                            HttpResponseMessage response;
                            var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };
                            using (var http = new HttpClient(handler))
                            {
    
                                if (item.HttpMethod == 0)
                                {
                                    if (item.RequestParam != null)
                                    {
                                        item.Url += "?";
                                        foreach (var p in item.RequestParam)
                                            item.Url += p.Key + "=" + p.Value + "&";
                                        item.Url = item.Url.Remove(item.Url.Length - 1, 1);
                                    }
                                    response = http.GetAsync(item.Url).Result;
                                }
                                else
                                {
                                    var content = new FormUrlEncodedContent(item.RequestParam);
                                    response = http.PostAsync(item.Url, content).Result;
                                }
    
                                response.EnsureSuccessStatusCode();
                                responseDataSegment.ResponseData.Add(new ResponseData
                                {
                                    GuidKey = item.GuidKey,
                                    Status = 200,
                                    Data = response.Content.ReadAsStringAsync().Result
                                });
                            }
                        }
                        catch (Exception ex)
                        {
    
                            responseDataSegment.ResponseData.Add(new ResponseData
                            {
                                GuidKey = item.GuidKey,
                                Status = 100,
                                Data = ex.Message
                            });
                        }
    
                    }
    
                }
                filterContext.HttpContext.Response.ContentType = "applicatin/json";
                filterContext.HttpContext.Response.Write(VCommons.SerializeMemoryHelper.SerializeToJson(responseDataSegment));
                base.OnActionExecuting(filterContext);
            }
        }

    对于你的具体项目,选个主入口,在它上面添加上ApiProxy特性即可复制代码

         /// <summary>
            /// Api统一处理的入口
            /// </summary>
            /// <returns></returns>
            [ApiProxyFilter]
            public JsonResult Index()
            {
                return null;
            }

    现在你就可以去测试你的客户端了,哈哈,看是否把你的单个请求里的(三个请求)转发并为你返回了,呵呵.

  • 相关阅读:
    paip.环境设置 mybatis ibatis cfg 环境设置
    paip。java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型
    paip. java的 函数式编程 大法
    paip.函数方法回调机制跟java php python c++的实现
    paip.配置ef_unified_filter() failed ext_filter_module mod_ext_filter.so apache 错误解决
    paip. 解决java程序不能自动退出
    Paip.声明式编程以及DSL 总结
    paip. dsl 编程语言优点以及 常见的dsl
    paip.函数式编程方法概述以及总结
    paip.jdbc 连接自动释放的测试
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/12046576.html
Copyright © 2011-2022 走看看