一、WebService的概念
1、WebService 的软件开发思想
- 快速打造满足业务需求的个性化解决方案
2、WebService的特点
- 可以由单个应用程序在内部使用,也可以通过 Internet 在外部公开以供任意数目的应用程序使用。由于 XML Web services 可通过标准接口进行访问,因此 XML Web services 允许多个异构系统(即操作系统、编程语言和组件模型均可不同)作为单个计算网络协同工作。
- 服务的实现和使用之间存在高度的抽象(松耦合、通用的数据格式、无所不在的通信)。通过将基于 XML 的消息用作服务的创建和访问机制,Web services 客户端和 Web services 提供程序只要相互知道输入、输出和位置,就不用再了解任何其他信息了。
- 类似于B/S架构,只需要开发服务器端,不需要开发客户端,客户端只要遵循soap协议,就可以调用。(本人第一次接触WebServer是因为我们的软件需要从甲方的信息中心获取数据,甲方信息中心只需要为我们提供网址接口,我们即可获取数据)
3、WebService的基础结构
- WebService是在SOAP协议下,通过UDDI对服务进行注册和查找。并使用WSDL对服务进行说明和注释。
- SOAP:通信协议
- SOAP(Simple Object Access Protocol)是Web Service的传输协议。它规定Web Service 提供者和调用者之间信息的编码和传送方式。
- SOAP协议是建立在HTTP协议之上的互联网应用层协议(使用80端口),因此,它允许信息穿过防火墙而不被拦截。
- UDDI:查找方法
- UDDI(Universal Description,Discovery and Integration)统一描述、发现和集成。它是一种用于查找Web Service的机制。
- WSDL:描述文档
- WSDL(Web Service Description Language,Web服务描述语言):用于描述Web Service的一种XML格式的语言,说明服务端接口、方法、参数和返回值,通知其他的Web应用程序如何调用自己,WSDL是随服务发布成功,自动生成,无需编写。
4、WebService的优缺点
- 优点:
- 接口中实现的方法和要求参数一目了然
- 传递参数可以为数组,对象等各种复杂类型,数据格式更为通用
- 不用担心大小写及中文的编码问题
- 代码中不用多次声明认证(账号,密码)参数
- 缺点
- 要进行xml解析,速度可能会有所降低
二、WebService的一种实现方式
- 此方法有助于我们理解WebService。
三、WebService 的另一种实现方式
1、REST接口
REST(Representational State Transfer):表述状态转移,采用Web 服务使用标准的 HTTP 方法 (GET/PUT/POST/DELETE) 来抽象所有 Web 系统的服务能力,它是一种软件架构风格,一种针对网络应用的开发方式,可以降低开发的复杂性。REST从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源的表征。
2、代码实现
1.获取token
/// <summary>
/// 通过认证接口获取token,,以便后续访问,获取一次即可,长期有效,多次获取token会改变.
/// </summary>
/// <param name="url">认证接口的url</param>
/// <returns>token</returns>
public static string GetToken(string url)
{
try
{
//string url = "http://daswebsite.scp.XXX.XXXX/SSOService/checkAppKey?appKey=123&appSecret=123"; // 请求接口和对应的账号密码按照自己实际填写
// 这里不知道用的是哪个版本的SSL加密,所以把所有版本都填上
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
// 构造请求
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.ProtocolVersion = HttpVersion.Version11;
request.Method = "get";
request.ContentType = "text/plain";
// 获取响应
using (var response = request.GetResponse())
{
// 从返回数据字符串中 解析 token
var stremReader = new StreamReader(response.GetResponseStream());
JObject jo = (JObject)JsonConvert.DeserializeObject(stremReader.ReadToEnd());
return jo["token"].ToString();
}
}
catch (Exception ex)
{
XtraMessageBox.Show("获取token错误:" + ex.Message);
return "";
}
}
2、获取数据
// 获取token
string token = BigDataUtility.GetToken("http://daswebsite.scp.XXX.XXXX/SSOService/checkAppKey?appKey=123&appSecret=123"");
string method = "get";
List<ParamEntity> header = new List<ParamEntity>();
ParamEntity header_token = new ParamEntity();
header_token.Name = "token"; //必须传,认证用
header_token.Value = token; //必须传,认证用
header.Add(header_token);
//参数信息
List<ParamEntity> paramers = new List<ParamEntity>();
ParamEntity paramer = new ParamEntity();
string resultvalue;
string bodyStr = "";
string url = "";
string tableName = "";
resultvalue = BigDataUtility.InvokeRest(url, header, paramers, method, bodyStr);
/// <summary>
/// 根据 url 和条件 获取数据
/// </summary>
/// <param name="url">接口网址</param>
/// <param name="headers">请求头</param>
/// <param name="paramers">请求条件,键值对型的列表</param>
/// /// <param name="method">请求方式:get|post|put|</param>
/// <param name="bodyStr"></param>
/// <returns>Json 格式的字符串</returns>
///
static int i = 0;
public static string InvokeRest(string url, List<ParamEntity> headers, List<ParamEntity> paramers, string method = "get", string bodyStr = "")
{
i++;
string paramstr = "";
foreach (ParamEntity item in paramers)
{
paramstr += "&" + item.Name + "=" + Convert.ToString(item.Value);
}
if (!string.IsNullOrEmpty(paramstr))
{
if (url.Contains("?"))
{
url += paramstr;
}
else
{
url += "?" + paramstr.TrimStart('&');
}
}
//Web访问对象,构造请求的parturl地址
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
if (url.ToLower().StartsWith("https://"))
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
WebProxy proxyObject = new WebProxy("10.76.19.142", 8010);//str为IP地址 port为端口号
request.Proxy = proxyObject; //设置代理
request.Method = method;
foreach (ParamEntity item in headers)
{
request.Headers.Add(item.Name, Convert.ToString(item.Value));
}
if (method.Equals("post", StringComparison.OrdinalIgnoreCase) || method.Equals("put", StringComparison.OrdinalIgnoreCase))
{
//提交请求数据
byte[] bytes = new byte[0];
if (!string.IsNullOrEmpty(bodyStr))
{
bytes = Encoding.UTF8.GetBytes(bodyStr);
}
request.ContentLength = bytes.Length;
using (Stream myRequestStream = request.GetRequestStream())
{
myRequestStream.Write(bytes, 0, bytes.Length);
}
}
string returnStr = "";
HttpWebResponse response = null;
try
{
using (response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK
&& response.StatusCode != HttpStatusCode.Created
&& response.StatusCode != HttpStatusCode.Accepted
&& response.StatusCode != HttpStatusCode.NoContent)
{
var message = String.Format("请求失败. 接收的HTTP状态为{0}", response.StatusCode);
throw new ApplicationException(message);
}
// 获得接口返回值
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null && responseStream.CanRead)
{
using (StreamReader reader = new StreamReader(responseStream))
{
returnStr = reader.ReadToEnd();
}
}
}
}
}
catch (WebException exception)
{
using (var reader = new StreamReader(exception.Response.GetResponseStream()))
{
returnStr = reader.ReadToEnd();
}
XtraMessageBox.Show(paramers[0].Value + i.ToString() + url
+ "获取数据出现异常: " + exception.Message);
Console.WriteLine(paramers[0].Value + i.ToString() + url
+ "获取数据出现异常: " + exception.Message);
}
return returnStr;
}
3、解析Json字符串
/// <summary>
/// Json 字符串 转换为 DataTable数据集合
/// </summary>
/// <param name="jsonStr">Json格式 字符串</param>
/// <returns>DataTable数据集合</returns>
public static DataTable JsonToDataTable(string jsonStr, string wellName, string url)
{
DataTable dataTable = new DataTable(); //实例化
DataTable result;
if (jsonStr == string.Empty || jsonStr == "")
{
result = dataTable;
return result;
}
try
{
JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
javaScriptSerializer.MaxJsonLength = Int32.MaxValue; //取得最大数值
// 对jsonStr 进行多层解析
JObject jo = (JObject)JsonConvert.DeserializeObject(jsonStr);
string datas = jo["data"][0]["datas"].ToString();
ArrayList arrayList = javaScriptSerializer.Deserialize<ArrayList>(datas);
string fields = jo["data"][0]["fields"].ToString();
fields = "[" + fields + "]";
ArrayList fieldsList = javaScriptSerializer.Deserialize<ArrayList>(fields);
if (arrayList.Count > 0)
{
//Columns
if (fieldsList.Count > 0)
{
if (dataTable.Columns.Count == 0)
foreach (Dictionary<string, object> dict in fieldsList)
{
foreach (string item in dict.Keys)
{
if (item == "id")
{
dataTable.Columns.Add("ids", GetTypeByString(dict[item].ToString()));
// dataTable.Columns.Add("ids", typeof(string));
}
else
{
string a = dict[item].ToString();
dataTable.Columns.Add(item, GetTypeByString(dict[item].ToString()));
//Console.WriteLine(dictionary[current].GetType());
// dataTable.Columns.Add(current, typeof(string));
}
}
}
foreach (Dictionary<string, object> dictionary in arrayList)
{
if (dictionary.Keys.Count<string>() == 0)
{
result = dataTable;
return result;
}
//Rows
DataRow dataRow = dataTable.NewRow();
foreach (string current in dictionary.Keys)
{
if (dictionary[current].ToString().Trim() != "")
{
if (current == "id")
{
//dataRow["ids"] = dictionary[current].ToString().Trim();
dataRow["ids"] = dictionary[current];
}
else
{
// dataRow[current] = dictionary[current].ToString().Trim();
dataRow[current] = dictionary[current];
}
}
}
dataTable.Rows.Add(dataRow); //循环添加行到DataTable中
}
}
}
}
catch (Exception ex)
{
XtraMessageBox.Show(wellName + url + "jsonStr转Tbale出现异常: " + ex.Message + " jsonStr:" + jsonStr);
Console.WriteLine(wellName + url + "jsonStr转Tbale出现异常: " + ex.Message + " jsonStr:" + jsonStr);
}
result = dataTable;
return result;
}
public static Type GetTypeByString(string type)
{
switch (type.ToLower())
{
case "bool":
return Type.GetType("System.Boolean", true, true);
case "byte":
return Type.GetType("System.Byte", true, true);
case "sbyte":
return Type.GetType("System.SByte", true, true);
case "char":
return Type.GetType("System.Char", true, true);
case "decimal":
return Type.GetType("System.Decimal", true, true);
case "double":
return Type.GetType("System.Double", true, true);
case "float":
return Type.GetType("System.Single", true, true);
case "int":
return Type.GetType("System.Int32", true, true);
case "uint":
return Type.GetType("System.UInt32", true, true);
case "long":
return Type.GetType("System.Int64", true, true);
case "ulong":
return Type.GetType("System.UInt64", true, true);
case "object":
return Type.GetType("System.Object", true, true);
case "short":
return Type.GetType("System.Int16", true, true);
case "ushort":
return Type.GetType("System.UInt16", true, true);
case "string":
return Type.GetType("System.String", true, true);
case "date":
case "datetime":
return Type.GetType("System.DateTime", true, true);
case "guid":
return Type.GetType("System.Guid", true, true);
default:
return Type.GetType("System.String", true, true);
}
}
四、参考文献