51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 2427|回复: 1

[讨论] android与webservice通过json通讯

[复制链接]

该用户从未签到

发表于 2018-6-20 15:37:19 | 显示全部楼层 |阅读模式
前言

前段时间来了个小项目,项目是通过手机扫货架上面的二维码,然后进行物料相关的操作,然后货架
上面对应的物料灯就会亮起,整个项目流程并不复杂,但是需要对接的服务器是webservice的,在我
们android开发中,我们经常与后台对接,但是大多都是http的请求,返回json格式,但是与webservi
ce通讯中,常用到的一些库并不推荐使用。一开始我们采用soap解析xml,还是可以使用的,但是随
着功能的增加,xml规范还是不太适合android,尤其是xml的解析看起来很乱,不像是json有很多的
实用库,用起来很方便,后来还是感觉json作为返回值会方便的很多。

WebService

由于我不是做服务端的,起初webservice并不了解,但是代码都是很类似的,也是参与到了其中的部
分开发,这里简单的介绍一下,webservice服务我就理解为一个后台接口,只不过通讯用的是soap,
返回的xml。网上有很多介绍webservice的博文,介绍的都很详细。

在使用json前我们需要添加几个库。

using System.Net.Http;
using Newtonsoft.Json;
using System.Text;
using System.Runtime.Serialization.Json;
这里需要添加一些资源库进去,然后引用。
分别是System.Net.Http.dll Newtonsoft.Json.dll。


下面举一个接口的例子:

[WebMethod(Description = "核实登录信息")]
public string WebLogin(string username, string pass)
{
        ResponseMessage rs = new ResponseMessage();
        try
        {
            string ConnStr = "server=lz-bjb;database='jzclk';uid='sa';pwd='sadhslzlz';";
            SqlConnection sqlConn = new SqlConnection(ConnStr);
            sqlConn.Open();
            string sqlSel = "select count(*) from tb_md where [工号]='" + username + "' and [密码]='" +
pass + "'";
            SqlCommand sqlcom = new SqlCommand(sqlSel, sqlConn);
            int i = Convert.ToInt32(sqlcom.ExecuteScalar());
            sqlConn.Close();
            if (i == 1)
            {
                string sqlSel1 = "select 姓名,部门,权限 from tb_md where [工号]='" + username + "' and [密
码]='" + pass + "'";
                SqlDataAdapter da = new SqlDataAdapter(sqlSel1, sqlConn);
                DataSet ds = new DataSet();
                da.Fill(ds, "tb_md");
                DataRowView drv = ds.Tables["tb_md"].DefaultView[0];
                string name = Convert.ToString(drv.Row["姓名"]);
                string bm = Convert.ToString(drv.Row["部门"]);
                string qx = Convert.ToString(drv.Row["权限"]);

                KCB cb = new KCB();
                cb.Gonghao = username;
                cb.Name = name;
                cb.Dept = bm;
                cb.Auth = qx;

                rs.Code = 1;
                rs.Msg = "success";
                rs.Result = cb;

                String sjon =JsonConvert.SerializeObject(rs);
                //GetQrCodeList(sjon);
                //Context.Response.Charset = "GB2312"; //设置字符集类型  
                //Context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
                //Context.Response.Write(sjon);
                return sjon;
            }
            else
            {
                rs.Code = 2;
                rs.Msg = "工号错误或密码错误";
                //rs.Result = "工号错误或密码错误";

                String sjon = JsonConvert.SerializeObject(rs);
                //GetQrCodeList(sjon);
                //Context.Response.Charset = "GB2312"; //设置字符集类型  
                //Context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
                //Context.Response.Write(sjon);
                return sjon;
            }
        }catch (Exception ex){         
            rs.Code =0;
            rs.Msg = "服务器处理异常错误";
            //rs.Result = "服务器处理异常错误";

            String sjon = JsonConvert.SerializeObject(rs);
            //GetQrCodeList(sjon);
            //Context.Response.Charset = "GB2312"; //设置字符集类型  
            //Context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
            //Context.Response.Write(sjon);
            return sjon;
        }
}
方法就是一个简单的登录的功能,参数是客户端传入的用户名和密码,然后webservice和sqlserivce数据库
去比对,正确了就登录。
我们注意到其中屏蔽的代码。

//GetQrCodeList(sjon);
//Context.Response.Charset = "GB2312"; //设置字符集类型  
//Context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
//Context.Response.Write(sjon);
在使用这段代码中,我们并没有return,这样浏览器测试接口的时候,我们发现接口虽然通,返回的的结
果也是json,但是我们知道webservice取值的时候还是需要命名空间的,没有xml我无法拿到其中的内容(
····这里是我不知道怎么去取),所以我将返回的内容封装到json然后再通过xml的内容返回给客户端。
用浏览器打开webserservice浏览



这里我们做了一些其他功能,我们先选择登录。


这个是webserivce的测试接口的方法,在对话框中填入测试的值,然后调用就可以测试了。



我们看到浏览器的返回值中,在xml内部便出现了json内容,这样我们在客户端可以进行soap进行解析出
json,然后就可以用gson之类的常用库进行json的解析啦。

android

在客户端用使用soap也是需要库的,我们添加了soap的库之后便可以进行soap的解析了。
soap下载链接:
http://download.csdn.net/download/ljz0826/9959925
首先我们封装一下soap的请求代码。
  1. <p>
  2. </p>
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

x
回复

使用道具 举报

该用户从未签到

 楼主| 发表于 2018-6-20 15:37:57 | 显示全部楼层


  1. <p>public class RemoteDataHandler {</p><p>
  2. </p><p>    private static Map<String,SoapObject> sso = new HashMap<String, SoapObject>();</p><p>
  3. </p><p>    private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(6,</p><p>            30, 30L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());</p><p>
  4. </p><p>    public interface CallBackXml {</p><p>        public void dataLoaded(SoapObject soapObject);</p><p>    }</p><p>
  5. </p><p>    /**</p><p>     *</p><p>     * @param activity  BaseActivity</p><p>     * @param methodname  方法名</p><p>     * @param rpc  参数</p><p>     * @param callback  回调</p><p>     * @param showProgress  是否显示对话框</p><p>     */</p><p>    public static void asyncSoap(final BaseActivity activity, final String methodname, final SoapObject rpc, fi</p><p>nal CallBackXml callback, final boolean showProgress){</p><p>        if (showProgress)</p><p>            activity.showProgress();</p><p>        final Handler handler = new Handler() {</p><p>            @Override</p><p>            public void handleMessage(Message msg) {</p><p>                switch (msg.what){</p><p>                    case 0:</p><p>                        activity.closeProgress();</p><p>                        SoapObject soapObject = sso.get(msg.obj);</p><p>                        sso.clear();</p><p>                        callback.dataLoaded(soapObject);</p><p>                }</p><p>            }</p><p>        };</p><p>
  6. </p><p>        threadPool.execute(new Runnable() {</p><p>            @Override</p><p>            public void run() {</p><p>                String nameSpace = Constants.NAME_SPACE; //命名空间</p><p>                String endPoint = Constants.END_POINT;</p><p>                String soapAction = nameSpace+methodname; //Action</p><p>                // 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本</p><p>                SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);</p><p>                envelope.bodyOut = rpc;</p><p>                // 设置是否调用的是dotNet开发的WebService</p><p>                envelope.dotNet = true;</p><p>                // 等价于envelope.bodyOut = rpc;</p><p>                envelope.setOutputSoapObject(rpc);</p><p>                HttpTransportSE transport = new HttpTransportSE(endPoint);</p><p>                try {</p><p>                    // 调用WebService</p><p>                    transport.call(soapAction, envelope);</p><p>                } catch (Exception e) {</p><p>                    e.printStackTrace();</p><p>                }</p><p>                SoapObject object = (SoapObject) envelope.bodyIn;</p><p>                Log.i("soap","object : "+object+"");</p><p>                ////////////////////////////////////////////////////////</p><p>                sso.put(methodname, object);</p><p>                Message msg = handler.obtainMessage(0,methodname);</p><p>                handler.sendMessage(msg);</p><p>            }</p><p>        });</p><p>
  7. </p><p>    }</p><p>
  8. </p><p>    /**</p><p>     *</p><p>     * @param fragment  BaseFragment</p><p>     * @param methodname  方法名</p><p>     * @param rpc  参数</p><p>     * @param callback  回调</p><p>     * @param showProgress  是否显示对话框</p><p>     */</p><p>    public static void asyncSoapfromfragment(final BaseFragment fragment, final String methodname, final S</p><p>oapObject rpc, final CallBackXml callback, final boolean showProgress){</p><p>        if (showProgress)</p><p>            TrainApplication.getCoreApplication().showProgressDialog(fragment.getContext());</p><p>        final Handler handler = new Handler() {</p><p>            @Override</p><p>            public void handleMessage(Message msg) {</p><p>                switch (msg.what){</p><p>                    case 0:</p><p>                        TrainApplication.getCoreApplication().dismissProgressDialog();</p><p>                        SoapObject soapObject = sso.get(msg.obj);</p><p>                        callback.dataLoaded(soapObject);</p><p>                        sso.clear();</p><p>                }</p><p>            }</p><p>        };</p><p>
  9. </p><p>        threadPool.execute(new Runnable() {</p><p>            @Override</p><p>            public void run() {</p><p>                String nameSpace = Constants.NAME_SPACE; //命名空间</p><p>                String endPoint = Constants.END_POINT;</p><p>                String soapAction = nameSpace+methodname; </p><p>                // 生成调用WebService方法的SOAP请求信息,并指定SOAP的版本</p><p>                SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);</p><p>                envelope.bodyOut = rpc;</p><p>                // 设置是否调用的是dotNet开发的WebService</p><p>                envelope.dotNet = true;</p><p>                // 等价于envelope.bodyOut = rpc;</p><p>                envelope.setOutputSoapObject(rpc);</p><p>                HttpTransportSE transport = new HttpTransportSE(endPoint);</p><p>                try {</p><p>                    // 调用WebService</p><p>                    transport.call(soapAction, envelope);</p><p>                } catch (Exception e) {</p><p>                    e.printStackTrace();</p><p>                }</p><p>                SoapObject object = (SoapObject) envelope.bodyIn;</p><p>                ////////////////////////////////////////////////////////</p><p>                sso.put(methodname, object);</p><p>                Message msg = handler.obtainMessage(0,methodname);</p><p>                handler.sendMessage(msg);</p><p>            }</p><p>        });</p><p>    }</p><p>}</p><p>这里就是soap请求webservice的方法。</p><p>我们在使用的时候:</p><p>
  10. </p><p>    private void login(){</p><p>        if(TextUtils.isEmpty(username.getText().toString().trim())){</p><p>            TrainToast.makeText(LoginActivity.this, getResources().getString(R.string.error_empty_username), </p><p>Toast.LENGTH_SHORT).show();</p><p>            return;</p><p>        }</p><p>        if(TextUtils.isEmpty(password.getText().toString().trim())){</p><p>            TrainToast.makeText(this, getResources().getString(R.string.error_empty_password), Toast.LENG</p><p>TH_SHORT).show();</p><p>            return;</p><p>        }</p><p>        SoapObject rpc = new SoapObject(Constants.NAME_SPACE, Constants.METHOD_LOGIN);</p><p>        rpc.addProperty("username", username.getText().toString().trim());</p><p>        rpc.addProperty("pass", password.getText().toString().trim());</p><p>        RemoteDataHandler.asyncSoap(LoginActivity.this, Constants.METHOD_LOGIN, rpc, new RemoteDataH</p><p>andler.CallBackXml() {</p><p>            @Override</p><p>            public void dataLoaded(SoapObject soapObject) {</p><p>                if (soapObject != null && soapObject.getPropertyCount() > 0) {</p><p>                    String result = soapObject.getPropertyAsString(0);</p><p>                    if(result!=null){</p><p>                        StuffEntity stuffEntity = GsonUtil.json2bean(result, StuffEntity.class);</p><p>                        if(stuffEntity!=null){</p><p>                            int code = stuffEntity.getCode();</p><p>                            if(code==1){</p><p>                                //进行登录操作</p><p>                            }else{</p><p>                                TrainToast.makeText(LoginActivity.this,stuffEntity.getMsg(), Toast.LENGTH_SHORT).show();</p><p>                            }</p><p>                        }else{</p><p>                            TrainToast.makeText(LoginActivity.this,getResources().getString(R.string.error_service), Toast.LENGTH_SHORT).show();</p><p>                        }</p><p>                    }else{</p><p>                        TrainToast.makeText(LoginActivity.this,getResources().getString(R.string.error_service), Toast.LENGTH_SHORT).show();</p><p>                    }</p><p>                } else {</p><p>                    TrainToast.makeText(LoginActivity.this, getResources().getString(R.string.error_net), Toast.LENGTH_SHORT).show();</p><p>                }</p><p>            }</p><p>        }, true);</p><p>    }</p>
复制代码

这样我们就很熟悉了,拿到了结果不需要再进行复杂的xml解析,直接取到soapobject其中的第一条strin
g,便是我们需要的json,然后直接用gson解析到bean类里面。这样我们便成功的用android与webservic
e进行通讯并拿到了json的结果。

回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-3-29 16:55 , Processed in 0.068812 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表