android连接webservice(通用,可使用复杂返回值)

本文为原创,转载请注明出处:http://blog.csdn.net/zhyl8157121/article/details/8709048


首先,说一下适用范围:

  1. 当使用java版的webservice的时候,可以直接使用KSOAP2这个类库,直接调用其方法就可以了。具体方法可以自行Google。
  2. 当使用.NET版的webservice的时候,KSOAP2这个类库不是很好用,我研究了一个下午没研究明白(可能是方法问题吧,欢迎大家共同交流)。所以,我就对这篇博客http://blog.csdn.net/zhyl8157121/article/details/8169172中的HttpConnSoap类进行了修改。目的是获取并解析复杂类型的返回值。

1.HttpConnSoap

<span style="font-size:14px;">package com.bottle.stockmanage;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

public class HttpConnSoap {
	public ArrayList<String> GetWebServre(String methodName, ArrayList<String> Parameters, ArrayList<String> ParValues) {
		ArrayList<String> Values = new ArrayList<String>();
		
		//ServerUrl是指webservice的url
		//10.0.2.2是让android模拟器访问本地(PC)服务器,不能写成127.0.0.1
		//11125是指端口号,即挂载到IIS上的时候开启的端口
		//Service1.asmx是指提供服务的页面
		String ServerUrl = "http://10.0.2.2:11125/Service1.asmx";
		
		//String soapAction="http://tempuri.org/LongUserId1";
		String soapAction = "http://tempuri.org/" + methodName;
		//String data = "";
		String soap = "<?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 />";
		String tps, vps, ts;
		String mreakString = "";

		mreakString = "<" + methodName + " xmlns=\"http://tempuri.org/\">";
		for (int i = 0; i < Parameters.size(); i++) {
			tps = Parameters.get(i).toString();
			//设置该方法的参数为.net webService中的参数名称
			vps = ParValues.get(i).toString();
			ts = "<" + tps + ">" + vps + "</" + tps + ">";
			mreakString = mreakString + ts;
		}
		mreakString = mreakString + "</" + methodName + ">";
		/*
		+"<HelloWorld xmlns=\"http://tempuri.org/\">"
		+"<x>string11661</x>"
		+"<SF1>string111</SF1>"
		+ "</HelloWorld>"
		*/
		String soap2 = "</soap:Envelope>";
		String requestData = soap + mreakString + soap2;
		//System.out.println(requestData);

		try {
			URL url = new URL(ServerUrl);
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			byte[] bytes = requestData.getBytes("utf-8");
			con.setDoInput(true);
			con.setDoOutput(true);
			con.setUseCaches(false);
			con.setConnectTimeout(6000);// 设置超时时间
			con.setRequestMethod("POST");
			con.setRequestProperty("Content-Type", "text/xml;charset=utf-8");
			con.setRequestProperty("SOAPAction", soapAction);
			con.setRequestProperty("Content-Length", "" + bytes.length);
			OutputStream outStream = con.getOutputStream();
			outStream.write(bytes);
			outStream.flush();
			outStream.close();
			InputStream inStream = con.getInputStream();

			//data=parser(inStream);
			//System.out.print("11");
			Values = inputStreamtovaluelist(inStream, methodName);
			//System.out.println(Values.size());
			return Values;

		} catch (Exception e) {
			System.out.print("2221");
			return null;
		}
	}

	public ArrayList<String> inputStreamtovaluelist(InputStream in, String MonthsName) throws IOException {
		StringBuffer out = new StringBuffer();
		String s1 = "";
		byte[] b = new byte[4096];
		ArrayList<String> Values = new ArrayList<String>();
		Values.clear();

		for (int n; (n = in.read(b)) != -1;) {
			s1 = new String(b, 0, n);
			out.append(s1);
		}

		System.out.println(out);
		String[] s13 = s1.split("><");
		String ifString = MonthsName + "Result";
		String TS = "";
		String vs = "";

		Boolean getValueBoolean = false;
		for (int i = 0; i < s13.length; i++) {
			TS = s13[i];
			System.out.println(TS);
			int j, k, l;
			j = TS.indexOf(ifString);
			k = TS.lastIndexOf(ifString);

			if (j >= 0) {
				System.out.println(j);
				if (getValueBoolean == false) {
					getValueBoolean = true;
				} else {

				}

				if ((j >= 0) && (k > j)) {
					System.out.println("FFF" + TS.lastIndexOf("/" + ifString));
					//System.out.println(TS);
					l = ifString.length() + 1;
					vs = TS.substring(j + l, k - 2);
					//System.out.println("fff"+vs);
					Values.add(vs);
					System.out.println("退出" + vs);
					getValueBoolean = false;
					return Values;
				}

			}
			if (TS.lastIndexOf("/" + ifString) >= 0) {
				getValueBoolean = false;
				return Values;
			}
			if ((getValueBoolean) && (TS.lastIndexOf("/" + ifString) < 0) && (j < 0)) {
				k = TS.length();
				//System.out.println(TS);
				vs = TS.substring(7, k - 8);
				//System.out.println("f"+vs);
				Values.add(vs);
			}

		}

		return Values;
	}

}
</span>
2.webservice的返回值

<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<ArrayOfReview xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
  <Review>
    <userID>201311521412</userID>
    <userName>wangjindong</userName>
    <reviewInfo>哇咔咔哇咔咔哇咔咔</reviewInfo>
    <reviewDate>2013-3-4 19:33:23</reviewDate>
  </Review>
  <Review>
    <userID>201311521412</userID>
    <userName>wangjindong</userName>
    <reviewInfo>abcdefghijklmn</reviewInfo>
    <reviewDate>2013/2/5 17:07:52</reviewDate>
  </Review>
</ArrayOfReview></span>

可以看到,上面的返回的是一个list<Review>。这样的话,用上面的那个HttpConnSoap就解析不了了。如果只看上面Values的值的话就是空的。这里我们就要对HttpConnSoap类进行一些修改,同时,对这个类进行一下讲解。

3.HttpConnSoap2

<span style="font-size:14px;">package com.pivotstudio.china.util;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import com.pivotstudio.china.config.AppConfig;

/**
 * 连接webservice的类
 *
 * @author Bottle
 *
 * @Date 2013-3-19 下午10:01:21
 */
public class HttpConnSoap2
{
    /**
     * 获取返回的InputStream,为了增强通用性,在方法内不对其进行解析。
     *
     * @param methodName
     *            webservice方法名
     * @param Parameters
     *            webservice方法对应的参数名
     * @param ParValues
     *            webservice方法中参数对应的值
     * @return 未解析的InputStream
     */
    public InputStream GetWebServre (String methodName, ArrayList<String> Parameters, ArrayList<String> ParValues)
    {

        //指定URL地址,我这里使用的是常量。
        //如:String ServerUrl = "http://10.0.2.2:11125/Service1.asmx";
        String ServerUrl = AppConfig.ServerURL;

        //soapAction = 命名空间 + 方法名
        String soapAction = "http://tempuri.org/" + methodName;

        //拼凑requestData
        String soap = "<?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 />";
        String tps, vps, ts;
        String mreakString = "";
        mreakString = "<" + methodName + " xmlns=\"http://tempuri.org/\">";
        for (int i = 0; i < Parameters.size(); i++)
        {
            tps = Parameters.get (i).toString();
            //设置该方法的参数为.net webService中的参数名称
            vps = ParValues.get (i).toString();
            ts = "<" + tps + ">" + vps + "</" + tps + ">";
            mreakString = mreakString + ts;
        }
        mreakString = mreakString + "</" + methodName + ">";
        String soap2 = "</soap:Envelope>";
        String requestData = soap + mreakString + soap2;
        //其上所有的数据都是在拼凑requestData,即向服务器发送的数据

        try
        {
            URL url = new URL (ServerUrl); //指定服务器地址
            HttpURLConnection con = (HttpURLConnection) url.openConnection();//打开链接
            byte[] bytes = requestData.getBytes ("utf-8"); //指定编码格式,可以解决中文乱码问题
            con.setDoInput (true); //指定该链接是否可以输入
            con.setDoOutput (true); //指定该链接是否可以输出
            con.setUseCaches (false); //指定该链接是否只用caches
            con.setConnectTimeout (6000); // 设置超时时间
            con.setRequestMethod ("POST"); //指定发送方法名,包括Post和Get。
            con.setRequestProperty ("Content-Type", "text/xml;charset=utf-8"); //设置(发送的)内容类型
            con.setRequestProperty ("SOAPAction", soapAction); //指定soapAction
            con.setRequestProperty ("Content-Length", "" + bytes.length); //指定内容长度

            //发送数据
            OutputStream outStream = con.getOutputStream();
            outStream.write (bytes);
            outStream.flush();
            outStream.close();

            //获取数据
            InputStream inputStream = con.getInputStream();
            return inputStream;

            /**
             * 此类到此结束了,比原来的HttpConnSoap还短,因为这里没有对返回的数据做解析。数据完全都保存在了inputStream中。
             * 而原来的类是将数据解析成了ArrayList
             * <String>格式返回。显然,这样无法解决我们上面的需求(返回值是复杂类型的List)
             */
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }

}
</span>

下面再简单说一下如何解析上面返回的inputStream。

4.XMLParase

<span style="font-size:14px;">/**
 * 利用xmlpull解析xml
 *
 * @author Bottle
 *
 * @Date 2013-3-22 下午4:53:35
 */
public class XMLParase
{

    /**
     * 解析评论xml信息
     * @param inputStream
     * @return
     */
    public static ArrayList<CommentInfor> paraseCommentInfors (InputStream inputStream)
    {
        ArrayList<CommentInfor> list = new ArrayList<CommentInfor>();
        XmlPullParser parser = Xml.newPullParser();

        try
        {
            parser.setInput (inputStream, "UTF-8");
            int eventType = parser.getEventType();
            CommentInfor info = new CommentInfor();

            while (eventType != XmlPullParser.END_DOCUMENT)
            {
                switch (eventType)
                {
                case XmlPullParser.START_DOCUMENT:// 文档开始事件,可以进行数据初始化处理
                    break;
                case XmlPullParser.START_TAG:// 开始元素事件
                    String name = parser.getName();
                    if (name.equalsIgnoreCase ("Review") )
                    {
                        info = new CommentInfor();
                    }
                    else if (name.equalsIgnoreCase ("userID") )
                    {
                        eventType = parser.next();
                        info.setUserID (parser.getText() );
                    }
                    else if (name.equalsIgnoreCase ("userName") )
                    {
                        eventType = parser.next();
                        info.setUserName (parser.getText() );
                    }
                    else if (name.equalsIgnoreCase ("reviewInfo") )
                    {
                        eventType = parser.next();
                        info.setReviewInfo (parser.getText() );
                    }
                    else if (name.equalsIgnoreCase ("reviewDate") )
                    {
                        eventType = parser.next();
                        info.setReviewDate (parser.getText() );
                    }
                    break;
                case XmlPullParser.END_TAG:// 结束元素事件
                    if (parser.getName().equalsIgnoreCase ("Review") )
                    {
                        list.add (info);
                        info = null;
                    }
                    break;
                }
                eventType = parser.next();
            }
            inputStream.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return list;
    }
}
</span>
其实就是利用xmlpull解析xml,具体可以视需求而定。

调用的时候只需如下。

<span style="font-size:14px;">HttpConnSoap2 webservice = new HttpConnSoap2();
String methodName = "showReview";//方法名
ArrayList<String> paramList = new ArrayList<String>();
ArrayList<String> parValueList = new ArrayList<String>();
ArrayList<CommentInfor>() resultList = new ArrayList<CommentInfor>();

paramList.add ("ID");//指定参数名
parValueList.add ("001");//指定参数值

InputStream inputStream = webservice.GetWebServre (methodName, paramList, parValueList);
resultList = XMLParase.paraseCommentInfors (inputStream);</span>

获取的所有的数据都在resultList中了。

再说一些小问题:

  • 有的同学反映说返回值是URL的时候结果很诡异。这个我没有遇到过,最好能给我LogCat,咱们一起研究一下。
  • 上面的方法一定不是完美的,只是说了一下思路,大家可以根据自己需要自行修改。当然直接拿来用的话问题也不大(没有专利费):D
  • 欢迎大家批评指正。
  • 也可以在下面留言。
  • 31
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 100
    评论
要通过Android连接SQL Server并使用WebService,您可以按照以下步骤进行操作: 1. 首先,确保您已经创建了一个用于SQL Server数据库的服务器以及相应的表。 2. 下载并安装适用于Android开发的IDE(如Android Studio)并创建新的Android项目。 3. 在Android项目的build.gradle文件中,添加Java连接SQL Server所需的依赖项。示例代码如下: ```java dependencies { implementation 'net.sourceforge.jtds:jtds:1.3.1' } ``` 4. 在Android的MainActivity.java文件中,编写以下代码来创建使用WebService连接SQL Server的逻辑: ```java import android.os.AsyncTask; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private static final String ip = "your_server_ip_address"; private static final String port = "your_sql_server_port"; private static final String database = "your_database_name"; private static final String user = "your_username"; private static final String password = "your_password"; private Button connectButton; private TextView resultTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); connectButton = findViewById(R.id.connectButton); resultTextView = findViewById(R.id.resultTextView); connectButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new ConnectSQLServer().execute(); } }); } private class ConnectSQLServer extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... voids) { String result = ""; try { Class.forName("net.sourceforge.jtds.jdbc.Driver"); String url = "jdbc:jtds:sqlserver://" + ip + ":" + port + "/" + database; Connection connection = DriverManager.getConnection(url, user, password); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("your_sql_query_here"); while (resultSet.next()) { result += resultSet.getString("your_column_name"); } resultSet.close(); statement.close(); connection.close(); } catch (Exception e) { Log.e(TAG, "Error: " + e.getMessage()); result = "Error: " + e.getMessage(); } return result; } @Override protected void onPostExecute(String result) { resultTextView.setText(result); } } } ``` 通过上述代码,当用户点击Connect按钮时,将会创建一个异步任务来连接SQL Server并执行查询。请确保将您的服务器IP地址、端口、数据库名称、用户名和密码替换为实际值。 5. 在Android的布局文件(activity_main.xml)中,创建一个Button和一个TextView用于显示查询结果。 ```xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="16dp" android:paddingTop="16dp" android:paddingRight="16dp" android:paddingBottom="16dp"> <Button android:id="@+id/connectButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Connect" android:layout_centerInParent="true"/> <TextView android:id="@+id/resultTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/connectButton" android:textSize="18sp"/> </RelativeLayout> ``` 6. 运行Android应用程序,并点击Connect按钮以连接SQL Server并显示查询结果。 这就是使用Android连接SQL Server并使用WebService的详细教程。请注意,这只是一个基本示例,您可能需要根据您的特定需求进行一些调整。
评论 100
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值