android 带header调用webservice接口,与.net交互,xml传输数据

这次项目,是关于小学生做试卷答题,但是后台没想到的是.net,需要用webservice  soap协议,如此一来,以往的OKGO啊,OKHttp啊等一些网络请求框架均不能使用了。

这种项目一般还确实比较少,也已经很久没用android写过这个了,但是记得有ksoap的jar包来支持。ksoap3.6

不知道为什么最低分必须是2分。。。



好了,废话不多说,开始来搞吧!

首先明白几个东西,命名空间,方法名,EndPoint,SOAP Action。前两个简单,不必多少,而EndPoint就是WSDL地址去掉?wsdl之后的部分,Soap  action 就是命名空间+方法名。而且如果可以参考我之前的文章,SoapUI这个工具的使用,来理解这些。


new Thread(new Runnable() {
            @Override
            public void run() {
                // 创建HttpTransportSE对象, url timeOut
                //    AndroidHttpTransport httpTransportSE = new AndroidHttpTransport(baseURL, TIMEOUT);但是不建议用这个了已经过时了
                HttpTransportSE httpTransportSE=new HttpTransportSE(endpoint);
                // 创建SoapObject对象
                SoapObject soapObject = new SoapObject(nameSpace, methodName);
                PropertyInfo pi = new PropertyInfo();
                pi.setName("key1");
                pi.setValue("value1");
                PropertyInfo pi1 = new PropertyInfo();
                pi1.setName("key2");
                pi1.setValue("value2");
                soapObject.addProperty(pi);
                soapObject.addProperty(pi1);
                SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
                envelope.bodyOut = soapObject;
                envelope.dotNet = true;
                envelope.setOutputSoapObject(soapObject);
                try {
                    // 调用WebService
                    httpTransportSE.call(soapAction, envelope);
                    SoapPrimitive  responseResult= (SoapPrimitive) soapEnvelope.getResponse();
                    String result =responseResult.toString();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //下面这个方式不知道为什么拿不到了返回的数据了,就用了上面那个
               // 获取返回的数据
                //SoapObject object = (SoapObject) envelope.bodyIn;
                // 获取返回的结果
                //String result = object.getProperty(0).toString();

                // 将WebService返回的结果显示在TextView中
                textView.setText(result);
            }
        }).start();

但是每次请求都这样太麻烦了,后来看到网上人家封装的WebServiceUtil,但是已经不知道出处在哪了,但是还缺少header部分,但是我这边请求每次要带有特殊的header部分,以及回调,所以我改动了一些

所以我的封装如此了

public class WebServiceUtils {

    // 含有3个线程的线程池
    private static final ExecutorService executorService = Executors
            .newFixedThreadPool(3);


    /**
     * @param url                WebService服务器地址
     * @param methodName         WebService的调用方法名
     * @param properties         WebService的参数
     * @param webServiceCallBack 回调接口
     */
    public static void callWebService(String url, final String methodName,
                                      HashMap<String, String> properties, Element[] header,
                                      final WebServiceCallBack webServiceCallBack) {
        // 创建HttpTransportSE对象,传递WebService服务器地址
        final HttpTransportSE httpTransportSE = new HttpTransportSE(url);
        // 创建SoapObject对象
        SoapObject soapObject = new SoapObject(getServerIp(), methodName);

        // SoapObject添加参数
        if (properties != null) {
            for (Iterator<Map.Entry<String, String>> it = properties.entrySet()
                    .iterator(); it.hasNext(); ) {
                Map.Entry<String, String> entry = it.next();
                soapObject.addProperty(entry.getKey(), entry.getValue());
            }
        }

        // 实例化SoapSerializationEnvelope,传入WebService的SOAP协议的版本号
        final SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        // 设置是否调用的是.Net开发的WebService
        if (header == null) {
            soapEnvelope.headerOut = MySoapHeader.getSoapHeader();
        } else {
            soapEnvelope.headerOut = header;
        }
        soapEnvelope.setOutputSoapObject(soapObject);
        soapEnvelope.dotNet = true;
        httpTransportSE.debug = true;
        // 用于子线程与主线程通信的Handler
        final Handler mHandler = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                // 将返回值回调到callBack的参数中
                if(webServiceCallBack==null){
                    Log.i("tag","是null");
                }
                if (msg.what==0x1131){
                    webServiceCallBack.NetFailed();
                }else {
                    webServiceCallBack.callBack((String) msg.obj);
                }

            }

        };

        // 开启线程去访问WebService
        executorService.submit(new Runnable() {

            @Override
            public void run() {
                SoapPrimitive result=null;
                String handlerResult=null;
                int whats=0;
//                SoapObject resultSoapObject = null;
                try {
                    httpTransportSE.call(getServerIp() + methodName, soapEnvelope);
                    if (soapEnvelope.getResponse() != null) {
                        result= (SoapPrimitive) soapEnvelope.getResponse();
                        handlerResult=result.toString();
//                        // 获取服务器响应返回的SoapObject
//                        resultSoapObject = (SoapObject) soapEnvelope.bodyIn;
//                        Log.i("tag","----------"+resultSoapObject.toString());
                    }else {
                        Log.i("tag","nu;;");
                    }
                } catch (HttpResponseException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.i("tag","nu;;"+e.getMessage());
                    if (e.getMessage().contains("Network is unreachable")){
                        handlerResult="Network is unreachable";
                        whats=0x1131;
                    }
                } catch (XmlPullParserException e) {
                    e.printStackTrace();
                } finally {
                    // 将获取的消息利用Handler发送到主线程
                    mHandler.sendMessage(mHandler.obtainMessage(whats,
                            handlerResult));
                }
            }
        });
    }

    /**
     * @author xiaanming
     */
    public interface WebServiceCallBack {
        public void callBack(String result);
        public void NetFailed();
    }

}

在Activity中使用就这样即可:

        HashMap hashMap = new HashMap();
        hashMap.put("UserID", SharedPreferencesHelper.getString(getContext(), "user_id"));
        hashMap.put("pageNo", pageNo);
        hashMap.put("day", day);
        hashMap.put("statu", statu);
        hashMap.put("keyword", keyword);
        WebServiceUtils.callWebService(getDataOperaNamespace(), GET_PAPER_LIST, hashMap, null, new WebServiceUtils.WebServiceCallBack() {
            @Override
            public void callBack(String result) {
                if (null != result) {
                    Log.i("tag", "s========" + result);
                    
                }
            }

            @Override
            public void NetFailed() {

            }
        });

我这里提取了我的header部分,上面的第四个参数null就代表是使用默认的header,header如此:

public class MySoapHeader  {
    public static Element[] getSoapHeader(){
        Element[] header = new Element[1];
        header[0] = new Element().createElement(getServerIp(), "MySoapHeader");
        Element username = new Element().createElement(getServerIp(), "appKey");
        username.addChild(Node.TEXT, "d095587f7482XXXXXXXXXXXXXX2fb");
        header[0].addChild(Node.ELEMENT, username);
        Element pwd = new Element().createElement(getServerIp(), "appSecret");
            pwd.addChild(Node.TEXT, "85cXXXXXXXXXXXXXX9aeb");
        header[0].addChild(Node.ELEMENT, pwd);
        return header;
    }
}


原以为就这样结束了,确实也就这样结束了,但是万万没想到,还有个问题,就是我在性能测试的时候,用LeakCanary进行测试的时候,发现内存泄漏了




测试的情景是当我发起网络请求的时候,但是网络情况不佳,还没有返回数据,我就关闭了这个页面,此外还导致了报错。这个LeakCanary用起来特别好,它会告诉你你是怎么内存泄漏的,就比如我这个,就是因为这个CallBack回调接口,是匿名内部类的引用,但是它持有着handler,就导致了内存泄漏。


肯定不能就这么任着,必须要解决啊。所以最后封装成如此:

public class WebServiceUtils {

    // 含有3个线程的线程池
    private static final ExecutorService executorService = Executors
            .newFixedThreadPool(3);

    static WebServiceCallBack webServiceCallBack;

    public static void callWebService(Activity context,String url, final String methodName,
                                      HashMap<String, String> properties, Element[] header,
                                      WebServiceCallBack webServiceCallBacks) {
        webServiceCallBack=webServiceCallBacks;
        // 创建HttpTransportSE对象,传递WebService服务器地址
        final HttpTransportSE httpTransportSE = new HttpTransportSE(url);
        // 创建SoapObject对象
        SoapObject soapObject = new SoapObject(getServerIp(), methodName);

        // SoapObject添加参数
        if (properties != null) {
            for (Iterator<Map.Entry<String, String>> it = properties.entrySet()
                    .iterator(); it.hasNext(); ) {
                Map.Entry<String, String> entry = it.next();
                soapObject.addProperty(entry.getKey(), entry.getValue());
            }
        }

        // 实例化SoapSerializationEnvelope,传入WebService的SOAP协议的版本号
        final SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        // 设置是否调用的是.Net开发的WebService
        if (header == null) {
            soapEnvelope.headerOut = MySoapHeader.getSoapHeader();
        } else {
            soapEnvelope.headerOut = header;
        }
        soapEnvelope.setOutputSoapObject(soapObject);
        soapEnvelope.dotNet = true;
        httpTransportSE.debug = true;
        // 用于子线程与主线程通信的Handler
        final MyHandler mHandler = new MyHandler(context) {

            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                // 将返回值回调到callBack的参数中
                if (weakReference.get()!=null){
                    Log.i("tag","hello");
                    if (msg.what == 0x1131) {
                        webServiceCallBack.NetFailed();
                    } else {
                        webServiceCallBack.callBack((String) msg.obj);
                    }
                }else {
                    Log.i("tag","亲,已经销毁了");
                }

            }

        };

        // 开启线程去访问WebService
        executorService.submit(new Runnable() {

            @Override
            public void run() {
                SoapPrimitive result=null;
                String handlerResult=null;
                int whats=0;
//                SoapObject resultSoapObject = null;
                try {
                    httpTransportSE.call(getServerIp() + methodName, soapEnvelope);
                    if (soapEnvelope.getResponse() != null) {
                        result= (SoapPrimitive) soapEnvelope.getResponse();
                        handlerResult=result.toString();
//                        // 获取服务器响应返回的SoapObject
//                        resultSoapObject = (SoapObject) soapEnvelope.bodyIn;
//                        Log.i("tag","----------"+resultSoapObject.toString());
                    }else {
                        Log.i("tag","nu;;");
                    }
                } catch (HttpResponseException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.i("tag","nu;;"+e.getMessage());
                    if (e.getMessage().contains("Network is unreachable")){
                        handlerResult="Network is unreachable";
                        whats=0x1131;
                    }
                } catch (XmlPullParserException e) {
                    e.printStackTrace();
                } finally {
                    // 将获取的消息利用Handler发送到主线程
                    mHandler.sendMessage(mHandler.obtainMessage(whats,
                            handlerResult));
                }
            }
        });
    }

    static class MyHandler extends Handler{
        WeakReference<Activity> weakReference;

        public MyHandler(Activity context){
            weakReference =new WeakReference<Activity>(context);
        }

    }

    /**
     * @author xiaanming
     */
    public interface WebServiceCallBack {
        public void callBack(String result);
        public void NetFailed();
    }

    public static void cancelCall(){
        webServiceCallBack=null;
    }

}


在activity中这样

@Override
    protected void onDestroy() {
        super.onDestroy();
        WebServiceUtils.cancelCall();
    }



看,没有泄漏了


先这样吧,我觉得我这个里面还有很多的问题,或者有更好的解决方案,你们可以留言给我。谢谢了


此外再向大家推荐一个超好用的xml转json的工具,这样,xml转json,再gson转对象,太方便。

JSONObject jsonObject = XML.toJSONObject(result);

用的jar包在这 java-json.jar

本人个人原创,如有雷同,纯属巧合,或者与本人联系,做改动。请转载或者CV组合标明出处,谢谢!(如有疑问或错误欢迎指出,本人QQ:752231513)


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值