当前位置:   article > 正文

android通过webservice连接SQL Server详细教程(数据库+服务器+客户端)_c#开发android应用程序(连接sql server)

c#开发android应用程序(连接sql server)

android通过webservice连接SQL Server详细教程(数据库+服务器+客户端)这篇文章中讲到android如何通过webservice连接SQL Server。由于这篇文章距今也有四年了,一些代码在现在比较新的环境中运行不了。所以我根据评论中的提示和自己遇到的问题重新修改了部分代码,使得整个系统能在SQL Server2016+Win10+VS2015+android4.4上能够运行。具体的步骤就不说了,大致上和原来的教程差不多,只说几个比较容易出问题的地方。
1.原文章中登录SQL Server用的是Windows身份验证方式。如果像我出现登录失败的问题,可以改用SQL Server身份验证方式。在安全性-登录名中添加一个SQL Server身份验证方式登录的用户。



C#的代码里面数据库连接字符串还是粘贴属性里面的连接字符串,把密码改成自己的密码
private String ConServerStr = "Data Source=2013-20160523DL;Initial Catalog=test;User ID=houjingyi;Password=*******";
2.一定要先在webservice里面确认对数据库的操作没有问题,再去调android程序。只看到页面出来了很可能数据库连接有问题,这样即使android程序没问题也调不出来。
3.android4.0以后不允许在主线程中访问网络,因为万一主线程阻塞了,会使得界面没有响应。我们开启线程访问即可。

  1. public List<HashMap<String, String>> getAllInfo(final Handler myhandler)
  2. {
  3. HashMap<String, String> tempHash = new HashMap<String, String>();
  4. List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
  5. tempHash.put("Cno", "Cno");
  6. tempHash.put("Cname", "Cname");
  7. tempHash.put("Cnum", "Cnum");
  8. list.clear();
  9. arrayList1.clear();
  10. arrayList2.clear();
  11. arrayList3.clear();
  12. list.add(tempHash);
  13. new Thread()
  14. {
  15. public void run()
  16. {
  17. arrayList1 = Soap.GetWebServer("selectAllCargoInfor", arrayList1, arrayList2);
  18. Message msg=new Message();
  19. msg.what=0x123;
  20. msg.obj=arrayList1;
  21. myhandler.sendMessage(msg);
  22. }
  23. }.start();
  24. return list;
  25. }
  26. public void insertCargoInfo(String Cname, String Cnum)
  27. {
  28. arrayList1.clear();
  29. arrayList2.clear();
  30. arrayList1.add("Cname");
  31. arrayList1.add("Cnum");
  32. arrayList2.add(Cname);
  33. arrayList2.add(Cnum);
  34. new Thread()
  35. {
  36. public void run()
  37. {
  38. try
  39. {
  40. Soap.GetWebServer("insertCargoInfo", arrayList1, arrayList2);
  41. }
  42. catch(Exception e)
  43. {
  44. }
  45. }
  46. }.start();
  47. }
  48. public void deleteCargoInfo(String Cno)
  49. {
  50. arrayList1.clear();
  51. arrayList2.clear();
  52. arrayList1.add("Cno");
  53. arrayList2.add(Cno);
  54. new Thread()
  55. {
  56. public void run()
  57. {
  58. try
  59. {
  60. Soap.GetWebServer("deleteCargoInfo", arrayList1, arrayList2);
  61. }
  62. catch(Exception e)
  63. {
  64. }
  65. }
  66. }.start();
  67. }
4.android4.0以后子线程里是不能对主线程的UI进行改变的,因此就引出了Handler。主线程里定义Handler供子线程里使用。
  1. final Handler myhandler=new Handler()
  2. {
  3. public void handleMessage(Message msg)
  4. {
  5. if(msg.what==0x123)
  6. {
  7. ArrayList<String> drrayList=(ArrayList<String>) msg.obj;
  8. for(int j=0;!drrayList.isEmpty()&&j+2<drrayList.size();j+=3)
  9. {
  10. HashMap<String,String> hashMap=new HashMap<String,String>();
  11. hashMap.put("Cno", drrayList.get(j));
  12. hashMap.put("Cname", drrayList.get(j+1));
  13. hashMap.put("Cnum", drrayList.get(j+2));
  14. list.add(hashMap);
  15. }
  16. adapter=new SimpleAdapter(
  17. MainActivity.this,list,
  18. R.layout.adapter_item,
  19. new String[]{"Cno","Cname","Cnum"},
  20. new int[]{R.id.txt_Cno,R.id.txt_Cname,R.id.txt_Cnum});
  21. listView.setAdapter(adapter);
  22. }
  23. }
  24. };
5.HttpConnSoap.java这个类是干什么的。我们看一下这些操作的SOAP1.1请求和响应示例。
selectAllCargoInfo:
请求:
POST /Service1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/selectAllCargoInfor"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <selectAllCargoInfor xmlns="http://tempuri.org/" />
  </soap:Body>
</soap:Envelope>
响应:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <selectAllCargoInforResponse xmlns="http://tempuri.org/">
      <selectAllCargoInforResult>
        <string>string</string>
        <string>string</string>
      </selectAllCargoInforResult>
    </selectAllCargoInforResponse>
  </soap:Body>
</soap:Envelope>
insertCargoInfo:
请求:
POST /Service1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/insertCargoInfo"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <insertCargoInfo xmlns="http://tempuri.org/">
      <Cname>string</Cname>
      <Cnum>int</Cnum>
    </insertCargoInfo>
  </soap:Body>
</soap:Envelope>
响应:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <insertCargoInfoResponse xmlns="http://tempuri.org/">
      <insertCargoInfoResult>boolean</insertCargoInfoResult>
    </insertCargoInfoResponse>
  </soap:Body>
</soap:Envelope>
deleteCargoInfo:
请求:
POST /Service1.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/deleteCargoInfo"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <deleteCargoInfo xmlns="http://tempuri.org/">
      <Cno>string</Cno>
    </deleteCargoInfo>
  </soap:Body>
</soap:Envelope>
响应:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <deleteCargoInfoResponse xmlns="http://tempuri.org/">
      <deleteCargoInfoResult>boolean</deleteCargoInfoResult>
    </deleteCargoInfoResponse>
  </soap:Body>
</soap:Envelope>
其实这个类就是在GetWebServer先拼XML格式的POST请求发给页面,然后在StreamtoValue里面对返回的数据做解析。GetWebServer这个函数比较简单,而在StreamtoValue里面要根据返回类型的不同执行不同的操作。删除和插入操作返回的是布尔类型,而查询操作返回的是String和int。我们也可以看到,删除和插入操作返回的XML格式是一样的。相信大家对比着XML和注释就能明白。
  1. package com.bottle.stockmanage;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.OutputStream;
  5. import java.net.HttpURLConnection;
  6. import java.net.URL;
  7. import java.util.ArrayList;
  8. import android.app.Activity;
  9. import android.net.ConnectivityManager;
  10. import android.widget.Toast;
  11. public class HttpConnSoap
  12. {
  13. public ArrayList<String> GetWebServer(String MethodName, ArrayList<String> Parameters, ArrayList<String> ParValues)
  14. {
  15. ArrayList<String> Values = new ArrayList<String>();
  16. //在android模拟器中测试填写10.0.2.2
  17. //在真机中测试填写电脑的IP地址
  18. String ServerUrl = "http://10.8.167.229:6666/Service1.asmx";
  19. String soapAction = "http://tempuri.org/" + MethodName;
  20. String soap = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
  21. + "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
  22. + "<soap:Body />";
  23. String s1, s2, s3, s4 = "";
  24. s4 = "<" + MethodName + " xmlns=\"http://tempuri.org/\">";
  25. for (int i = 0; i < Parameters.size(); i++)
  26. {
  27. s1 = Parameters.get(i).toString();
  28. s2 = ParValues.get(i).toString();
  29. s3 = "<" + s1 + ">" + s2 + "</" + s1 + ">";
  30. s4 = s4 + s3;
  31. }
  32. s4 = s4 + "</" + MethodName + ">";
  33. String s5 = "</soap:Envelope>";
  34. String requestData = soap + s4 + s5;
  35. try
  36. {
  37. URL url = new URL(ServerUrl);
  38. HttpURLConnection con = (HttpURLConnection) url.openConnection();
  39. byte[] bytes = requestData.getBytes("utf-8");
  40. con.setDoInput(true);
  41. con.setDoOutput(true);
  42. con.setUseCaches(false);
  43. con.setConnectTimeout(6000);
  44. con.setRequestMethod("POST");
  45. con.setRequestProperty("Content-Type", "text/xml;charset=utf-8");
  46. con.setRequestProperty("SOAPAction", soapAction);
  47. con.setRequestProperty("Content-Length", "" + bytes.length);
  48. OutputStream outStream = con.getOutputStream();
  49. outStream.write(bytes);
  50. outStream.flush();
  51. outStream.close();
  52. InputStream inStream = con.getInputStream();
  53. Values = StreamtoValue(inStream, MethodName);
  54. return Values;
  55. }
  56. catch (Exception e)
  57. {
  58. return null;
  59. }
  60. }
  61. public ArrayList<String> StreamtoValue(InputStream in, String MethodName) throws IOException
  62. {
  63. StringBuffer out = new StringBuffer();
  64. String s1 = "";
  65. byte[] b = new byte[4096];
  66. ArrayList<String> Values = new ArrayList<String>();
  67. Values.clear();
  68. for (int n; (n = in.read(b)) != -1;)
  69. {
  70. s1 = new String(b, 0, n);
  71. out.append(s1);
  72. }
  73. System.out.println(out);
  74. //分割
  75. String[] s2 = s1.split("><");
  76. String s5 = MethodName + "Result";
  77. String s3 = "",s4 = "";
  78. Boolean getValueBoolean = false;
  79. for (int i = 0; i < s2.length; i++)
  80. {
  81. s3 = s2[i];
  82. System.out.println(s3);
  83. int FirstIndexPos, LastIndexPos, LengthofS5;
  84. FirstIndexPos = s3.indexOf(s5);
  85. LastIndexPos = s3.lastIndexOf(s5);
  86. /*
  87. 删除:deleteCargoInfoResult>boolean</deleteCargoInfoResult
  88. 插入:insertCargoInfoResult>boolean</insertCargoInfoResult
  89. 查询:
  90. selectAllCargoInforResult
  91. string>string</string
  92. string>string</string
  93. /selectAllCargoInforResult
  94. */
  95. if (FirstIndexPos >= 0)
  96. {
  97. if (getValueBoolean == false)
  98. {
  99. getValueBoolean = true;
  100. }
  101. //如果返回的是布尔值,对应删除和增加操作
  102. if ((FirstIndexPos >= 0) && (LastIndexPos > FirstIndexPos))
  103. {
  104. LengthofS5 = s5.length() + 1;
  105. s4 = s3.substring(FirstIndexPos + LengthofS5, LastIndexPos - 2);
  106. Values.add(s4);
  107. getValueBoolean = false;
  108. return Values;
  109. }
  110. }
  111. //查询操作取值结束
  112. if (s3.lastIndexOf("/" + s5) >= 0)
  113. {
  114. getValueBoolean = false;
  115. return Values;
  116. }
  117. //如果返回的不是布尔值,对应查询操作
  118. if ((getValueBoolean) && (s3.lastIndexOf("/" + s5) < 0) && (FirstIndexPos < 0))
  119. {
  120. LastIndexPos = s3.length();
  121. s4 = s3.substring(7, LastIndexPos - 8);
  122. Values.add(s4);
  123. }
  124. }
  125. return Values;
  126. }
  127. }

6.如果你的电脑和我一样使用的是局域网,那么手机必须连和电脑在同一个网段的WIFI,不能用4G或者3G连接。如果你用的是公网IP或者以后把程序发布到一个服务器上从而获得一个公网IP,就没有这个限制了。
最后欢迎大家一起交流,学习,也感谢原作者的文章。修改后可运行的代码在:https://github.com/houjingyi233/android-connect-to-SQL-Server-On-PC-by-webservice/

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/314203
推荐阅读
相关标签
  

闽ICP备14008679号