WebService中ksoap2的使用总结

来源:互联网 发布:ae cc for mac 编辑:程序博客网 时间:2024/05/21 13:46

公司的服务端开发也是醉了,上一个项目使用webservice,这个项目又使用webservice,天呐,怎么都不会HTTP啊,好吧,由于本人记性超级差,上次用过又忘记了,这次来个大总结,因为webservice使用的是soap协议,官网给出对应开源的框架是ksoap2,所以来总结下ksoap2的用法吧

第一步:项目添加依赖

下载ksoap2的jar包,下载地址:下载ksoap2的jar包

下载完成后将jar包添加进你的项目中

第二步:创建一个网络访问的工具类WebServiceUtil

这个类中的call方法就是专门用来访问WebService的,其实这个类的封装可以自己修改的,网上有很多各式各样的,根据自己的需求去修改吧,下面我把它贴出来,你可以自己进行封装

/** * WebService访问方式的工具类 */public class WebServiceUtils {    // 访问的服务器是否由dotNet开发    public static boolean isDotNet = true;    // 线程池的大小,这里创建了5    private static int threadSize = 5;    // 创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程    private static ExecutorService threadPool = Executors.newFixedThreadPool(threadSize);    // 连接响应标示    public static final int SUCCESS_FLAG = 0;    public static final int ERROR_FLAG = 1;    // 一般自己公司开发都是需要身份验证的,当然你也可以不验证    private static final String ID_HEADERNAME = "verify method";// 身份验证方法名    private static final String ID_NAME_PARAM = "verify key1";// 身份验证 key    private static final String ID_NAME_VALUE = "verify value1";// 身份验证 value    private static final String ID_PASSWORD_PARAM = "verify key2";// 身份验证 key    private static final String ID_PASSWORD_VALUE = "verify value2";// 身份验证 value    /**     * 调用WebService接口,此方法只访问过用Java写的服务器,我这里给了5个参数,其实服务端地址和命名空间可以在本类中的属性里写成常量,这样不用每次调用的时候都给这两个参数了,这样只有三个参数了     *     * @param endPoint        WebService服务器地址     * @param nameSpace       命名空间(在服务器那边是写死了的,固定的,在服务器接口那里可以看见)     * @param methodName      WebService的调用方法名     * @param mapParams       WebService的参数集合,可以为null     * @param reponseCallBack 服务器响应接口,我这里已经将这个接口移到外面单独出来了,其实是可以写在这个工具类中的,看代码的最底部,这个接口就写在这个工具类中的,这样做也是可以的     */    public static void call(final String endPoint, final String nameSpace, final String methodName, SimpleArrayMap<String, String> mapParams, final ResponseInterface reponseCallBack) {        // 1.创建HttpTransportSE对象,传递WebService服务器地址        final HttpTransportSE transport = new HttpTransportSE(endPoint);        transport.debug = true;        // 身份验证(如果需要的话)//        Element[] header = new Element[1];//        // 传入命名空间与验证的方法名//        header[0] = new Element().createElement(nameSpace, ID_HEADERNAME);//        // 创建参数 1//        Element userName = new Element().createElement(nameSpace, ID_NAME_PARAM);//        userName.addChild(Node.TEXT, ID_NAME_VALUE);//        header[0].addChild(Node.ELEMENT, userName);//        // 创建参数 2//        Element password = new Element().createElement(nameSpace, ID_PASSWORD_PARAM);//        password.addChild(Node.TEXT, ID_PASSWORD_VALUE);//        header[0].addChild(Node.ELEMENT, password);        // 2.创建SoapObject对象用于传递请求参数        final SoapObject request = new SoapObject(nameSpace, methodName);        // 2.1.添加参数,也可以不传        if (mapParams != null) {            for (int index = 0; index < mapParams.size(); index++) {                String key = mapParams.keyAt(index);//                String value = mapParams.get(key); // 多数情况下,传递的参数都为 String 类型,不过少数情况下会有 boolean 类型,所以用 Object 代替                Object value = mapParams.get(key);                request.addProperty(key, value);            }        }        // 3.实例化SoapSerializationEnvelope,传入WebServiceSOAP协议的版本号        // 这里有 VER10 VER11 VER12 三种版本,根据自己需要填写        final SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);//        envelope.headerOut = header; // 身份验证(如果需要的话)        envelope.dotNet = isDotNet; // 设置是否调用的是.Net开发的WebService        envelope.setOutputSoapObject(request);// 传递参数//        envelope.bodyOut = request; //和上一句envelope.setOutputSoapObject(request);等价        // 4.用于子线程与主线程通信的Handler,网络请求成功时会在子线程发送一个消息,然后在主线程上接收        final Handler responseHandler = new Handler() {            @Override            public void handleMessage(Message msg) {                super.handleMessage(msg);                // 根据消息的arg1值判断调用哪个接口                if (msg.arg1 == SUCCESS_FLAG) {                    Log.e("WebServiceResult---", msg.obj.toString());                    reponseCallBack.onSuccess((SoapObject) msg.obj);//这里接口中用的是SoapObject的,其实也可以是String,那就要写成(String)msg.obj                } else {                    reponseCallBack.onError((Exception) msg.obj);                }            }        };        // 5.提交一个子线程到线程池并在此线种内调用WebService        if (threadPool == null || threadPool.isShutdown())            threadPool = Executors.newFixedThreadPool(threadSize);        threadPool.submit(new Runnable() {            @Override            public void run() {                SoapObject result = null;//                String result = null;//接口中可以是String                try {                    // 解决EOFException                    System.setProperty("http.keepAlive", "false");                    // 连接服务器,有的服务可能不需要传递 NAMESPACE + methodName,第一个参数传递 null                    transport.call(nameSpace + methodName, envelope);                    if (envelope.getResponse() != null) {                        // 获取服务器响应返回的SoapObject                        result = (SoapObject) envelope.bodyIn;//                        SoapObject object = (SoapObject) envelope.bodyIn;//接口中也可以是String//                        result = object.getProperty(0).toString();                    }                } catch (IOException e) {                    // call方法的第一个参数为null时会有一定的概念抛IO异常                    // 因此需要需要捕捉此异常后用命名空间加方法名作为参数重新连接                    e.printStackTrace();                    try {                        transport.call(nameSpace + methodName, envelope);                        if (envelope.getResponse() != null) {                            // 获取服务器响应返回的SoapObject                            result = (SoapObject) envelope.bodyIn;//                            SoapObject object = (SoapObject) envelope.bodyIn;//接口中也可以是String//                            result = object.getProperty(0).toString();                        }                    } catch (Exception e1) {                        // e1.printStackTrace();                        responseHandler.sendMessage(responseHandler.obtainMessage(0, ERROR_FLAG, 0, e1));                    }                } catch (XmlPullParserException e) {                    // e.printStackTrace();                    responseHandler.sendMessage(responseHandler.obtainMessage(0, ERROR_FLAG, 0, e));                } finally {                    // 将获取的消息利用Handler发送到主线程                    responseHandler.sendMessage(responseHandler.obtainMessage(0, SUCCESS_FLAG, 0, result));                }            }        });    }    /**     * 设置线程池的大小     *     * @param threadSize     */    public static void setThreadSize(int threadSize) {        WebServiceUtils.threadSize = threadSize;        threadPool.shutdownNow();        threadPool = Executors.newFixedThreadPool(WebServiceUtils.threadSize);    }    /**     * 服务器响应接口,在响应后需要回调此接口,在这里已经将这个接口给独立出去咯,在interfaces包中,所以给注释掉     *///    public interface Response {//        public void onSuccess(SoapObject result);//当前使用的是SoapObject////      public void onSuccess(String result);//也可以用string表示////        public void onError(Exception e);//    }}
看到代码的后面,Response接口被我给注释掉了,其实我是将这个接口给独立出来放到一个单独的类中的,如下,只是变了个名字,变成ResponInterface,其实是一样的

import org.ksoap2.serialization.SoapObject;/** * Created by jjg on 2016/10/18. */public interface ResponseInterface {    public void onSuccess(SoapObject result);    public void onError(Exception e);}

第三步:有了这个工具类后,那就好办了,但是我还创建了一个类,专门用来存放那些啥命名空间的、网络地址啥的,前面我说过,其实可以将这些放进WebServiceUtil工具类中,但为了方便和减少代码之间的耦合度,我还是单独给出了一个ServiceConstants类来存放这些常量,如下:

/** * 这个类中存放的是一些服务常量,主要是一些服务器的接口链接 * Created by Eli on 2016/10/8. */public class ServiceConstants {    //服务器的接口总地址    public static final String URL_IMAGE= "http://justec.vicp.net:658";    // webservice服务器执行登入的地址    public static final String URL_BASE = "http://justec.vicp.net:658/ThermometerService.asmx?op=";    //web服务的命名空间    public static final String NAME_SPACE = "http://tempuri.org/";    //查询用户是否存在    /**     * <QueryUserIsExist xmlns="http://tempuri.org/">     <userName>string</userName>     </QueryUserIsExist>     */    public static final String METHOD_USER_ISEXIST = "QueryUserIsExist";    //soap请求地址    public static final String SOAP_ACTION = "http://tempuri.org/QueryUserIsExist";    //用户登录    /**     * <UserLogin xmlns="http://tempuri.org/">     <userName>string</userName>     <password>string</password>     </UserLogin>     */    public static final String METHOD_LOGIN = "UserLogin";    //用户注册    /**     * <UsersRegister xmlns="http://tempuri.org/">     <userName>string</userName>     <pwd>string</pwd>     </UsersRegister>     */    public static final String METHOD_REGISTER = "UsersRegister";    //查询家庭用户是否存在    /**     * <QueryUserFamilyIsExist xmlns="http://tempuri.org/">     <userName>string</userName>     <UserID>int</UserID>     </QueryUserFamilyIsExist>     */    public static final String METHOD_FAMILYISEXIST = "QueryUserFamilyIsExist";    //新增家庭用户    /**     * <InsertUsersFamily xmlns="http://tempuri.org/">     <userName>string</userName>     <UserID>int</UserID>     </InsertUsersFamily>     */    public static final String METHOD_INSTER_FAMILY = "InsertUsersFamily";    //获取所有家庭成员信息    /**     * <GetAllFamilyUsers xmlns="http://tempuri.org/">     <userID>int</userID>     </GetAllFamilyUsers>     */    public static final String METHOD_GET_FAMILY = "GetAllFamilyUsers";    //删除家庭用户    /**     * <userFamilyID>int</userFamilyID>     */    public static final String METHOD_DELETE_FAMILY = "DeleteUsersFamily";    /**     * 更新家庭成员信息     * <UpdateUsersFamily xmlns="http://tempuri.org/">     * <strJson>string</strJson>     * </UpdateUsersFamily>     */    public static final String METHOD_UPDATA_USER = "UpdateUsersFamily";    /**     * 更新家庭成员信息     * <UpdateUsersFamily xmlns="http://tempuri.org/">     * <strJson>string</strJson>     * </UpdateUsersFamily>     */    public static final String METHOD_UPDATA_MASTER= "UpdateUsers";}

看到了吗,因为我这里会用到很多服务端的方法名字,用户登入、用户注册等等都是有各自的方法名的,所以我在WebServiceUtil工具类中也将服务地址和命名空间放进Call参数中,因为我每次访问网络的地址是需要重新组织下的,而不是固定某一个不变的地址的,这样即使以后想要扩展其他网络接口,我可以直接在这里添加服务常量,然后组合成网络地址就可以调用Call方法直接使用了,要是你每次访问的服务地址是固定的,完全可以写成常量放进WebServiceUtil工具类中。

第四步:这一步也是为了编程的扩展性而添加的一个管理类,由于网络端访问的方法名很多,所以我写了个管理类来管理,就像MVP思想一样,我只需要在V层调用一个方法,具体的一些逻辑思路都是M层完成一个道理

/** * 这个类是个操作服务器的类,一系列的登入,注册,删除,查询等等方法集中在这里,可以直接来调用 * Created by jjg on 2016/10/18. */public class Login_manager {    private static Login_manager instance;//实例    public static synchronized Login_manager getInstance() {//获取实例,下次用到这个类不用使用new来创建对象,直接Login_manager.getInstance()就可以        if (instance == null) {            instance = new Login_manager();        }        return instance;    }    private Login_manager() {//构造方法    }    /**     * 注册密码MD5加密(就是注册完毕后将密码加密后上传给服务器,以防原始密码在传送过程中被别人盗用,这样保证密码不会泄露)     *     * @param info     * @return     */    public String getMD5(String info) {//给的参数是个String,经过加密后返回的也是一个String        try {            MessageDigest md5 = MessageDigest.getInstance("MD5");            md5.update(info.getBytes("UTF-8"));            byte[] encryption = md5.digest();            StringBuffer strBuf = new StringBuffer();            for (int i = 0; i < encryption.length; i++) {                if (Integer.toHexString(0xff & encryption[i]).length() == 1) {                    strBuf.append("0").append(Integer.toHexString(0xff & encryption[i]));                } else {                    strBuf.append(Integer.toHexString(0xff & encryption[i]));                }            }            return strBuf.toString();        } catch (NoSuchAlgorithmException e) {            return "";        } catch (UnsupportedEncodingException e) {            return "";        }    }    /**     * 请求登入     * @param context     * @param userName     * @param pwd     * @param responseInterface     */    public void requestLogin(Context context, final String userName, final String pwd, final ResponseInterface responseInterface) {        // 参数集合        SimpleArrayMap mapParams = new SimpleArrayMap();        mapParams.put("userName", userName + "");        mapParams.put("password", getMD5(pwd));        final ProgressDialog dialog2 = ProgressDialog.show(context, null, "正在登陆...");        dialog2.setCancelable(true);        dialog2.setCanceledOnTouchOutside(false);        WebServiceUtils.call(ServiceConstants.URL_BASE + ServiceConstants.METHOD_LOGIN,                ServiceConstants.NAME_SPACE, ServiceConstants.METHOD_LOGIN, mapParams,                new ResponseInterface() {                    @Override                    public void onSuccess(SoapObject result) {                        dialog2.dismiss();                        responseInterface.onSuccess(result);                    }                    @Override                    public void onError(Exception e) {                        dialog2.dismiss();                        responseInterface.onError(e);                    }                });    }    /**     * 检测用户是否存在(检测的是注册的那个管理员用户)     *     * @param context     * @param userName     * @param responseInterface     */    public void requestUserIsExist(Context context, final String userName, ResponseInterface responseInterface) {        // 参数集合        SimpleArrayMap mapParams = new SimpleArrayMap();        mapParams.put("userName", userName + "");        WebServiceUtils.call(ServiceConstants.URL_BASE + ServiceConstants.METHOD_USER_ISEXIST,                ServiceConstants.NAME_SPACE, ServiceConstants.METHOD_USER_ISEXIST, mapParams,                responseInterface);    }    /**     * 请求注册     * @param context     * @param userName     * @param pwd     * @param iamge     * @param responseInterface     */    public void requestRegister(Context context, final String userName, final String pwd,final String iamge, final ResponseInterface responseInterface) {        // 参数集合        SimpleArrayMap mapParams = new SimpleArrayMap();        mapParams.put("userName", userName + "");        mapParams.put("password", getMD5(pwd));        mapParams.put("image", iamge);        final ProgressDialog dialog2 = ProgressDialog.show(context, null, "正在注册...");        dialog2.setCancelable(true);        dialog2.setCanceledOnTouchOutside(false);        WebServiceUtils.call(ServiceConstants.URL_BASE + ServiceConstants.METHOD_REGISTER,                ServiceConstants.NAME_SPACE, ServiceConstants.METHOD_REGISTER, mapParams,                new ResponseInterface() {                    @Override                    public void onSuccess(SoapObject result) {                        dialog2.dismiss();                        responseInterface.onSuccess(result);                    }                    @Override                    public void onError(Exception e) {                        dialog2.dismiss();                        responseInterface.onError(e);                    }                });    }    /**     * 请求添加家庭成员     <InsertUsersFamily xmlns="http://tempuri.org/">     <userName>string</userName>     <realName>string</realName>     <userID>int</userID>     <image>string</image>     </InsertUsersFamily>     *     * @param context     * @param userName     * @param userId     * @param responseInterface     */    public void requestAddFamily(Context context, final String userName, final String realName,final String sex,final String age,final int userId, final String imgUrl, final ResponseInterface responseInterface) {        // 参数集合        SimpleArrayMap mapParams = new SimpleArrayMap();        mapParams.put("userName", userName);        mapParams.put("realName",realName);        mapParams.put("sex",sex);        mapParams.put("birthday",age);        mapParams.put("userID", userId + "");        mapParams.put("image", imgUrl);        Log.e("image-------", imgUrl.length() + "----" + imgUrl);        final ProgressDialog dialog2 = ProgressDialog.show(context, null, "正在增加用户...");        dialog2.setCancelable(true);        dialog2.setCanceledOnTouchOutside(false);        WebServiceUtils.call(ServiceConstants.URL_BASE + ServiceConstants.METHOD_INSTER_FAMILY,                ServiceConstants.NAME_SPACE, ServiceConstants.METHOD_INSTER_FAMILY, mapParams,                new ResponseInterface() {                    @Override                    public void onSuccess(SoapObject result) {                        dialog2.dismiss();                        responseInterface.onSuccess(result);                    }                    @Override                    public void onError(Exception e) {                        dialog2.dismiss();                        responseInterface.onError(e);                    }                });    }    /**     * 查询家庭用户是否存在     *     * @param context     * @param userName     * @param userId     * @param responseInterface     */    public void requestFamilyIsExist(Context context, final String userName, final int userId, final ResponseInterface responseInterface) {        // 参数集合        SimpleArrayMap mapParams = new SimpleArrayMap();        mapParams.put("userName", userName + "");        mapParams.put("userID", userId + "");        final ProgressDialog dialog2 = ProgressDialog.show(context, null, "正在查询用户是否存在...");        dialog2.setCancelable(true);        dialog2.setCanceledOnTouchOutside(false);        WebServiceUtils.call(ServiceConstants.URL_BASE + ServiceConstants.METHOD_FAMILYISEXIST,                ServiceConstants.NAME_SPACE, ServiceConstants.METHOD_FAMILYISEXIST, mapParams,                new ResponseInterface() {                    @Override                    public void onSuccess(SoapObject result) {                        dialog2.dismiss();                        responseInterface.onSuccess(result);                    }                    @Override                    public void onError(Exception e) {                        dialog2.dismiss();                        responseInterface.onError(e);                    }                });    }    /**     * 删除家庭成员     *     * @param context     * @param userId     * @param responseInterface     */    public void requestDeleteUserFamily(Context context, final int userId, final ResponseInterface responseInterface) {        // 参数集合        SimpleArrayMap mapParams = new SimpleArrayMap();        mapParams.put("userFamilyID", userId + "");        final ProgressDialog dialog2 = ProgressDialog.show(context, null, "正在删除用户...");        dialog2.setCancelable(true);        dialog2.setCanceledOnTouchOutside(false);        WebServiceUtils.call(ServiceConstants.URL_BASE + ServiceConstants.METHOD_DELETE_FAMILY,                ServiceConstants.NAME_SPACE, ServiceConstants.METHOD_DELETE_FAMILY, mapParams,                new ResponseInterface() {                    @Override                    public void onSuccess(SoapObject result) {                        dialog2.dismiss();                        responseInterface.onSuccess(result);                    }                    @Override                    public void onError(Exception e) {                        dialog2.dismiss();                        responseInterface.onError(e);                    }                });    }    /**     * 获取所有家庭成员信息     *     * @param context     * @param userId     * @param responseInterface     */    public void requestGetFamily(Context context, final int userId, final ResponseInterface responseInterface) {        // 参数集合        SimpleArrayMap mapParams = new SimpleArrayMap();        mapParams.put("userID", userId + "");        final ProgressDialog dialog2 = ProgressDialog.show(context, null, "正在获取用户...");        dialog2.setCancelable(true);        dialog2.setCanceledOnTouchOutside(false);        WebServiceUtils.call(ServiceConstants.URL_BASE + ServiceConstants.METHOD_GET_FAMILY,                ServiceConstants.NAME_SPACE, ServiceConstants.METHOD_GET_FAMILY, mapParams,                new ResponseInterface() {                    @Override                    public void onSuccess(SoapObject result) {                        dialog2.dismiss();                        responseInterface.onSuccess(result);                    }                    @Override                    public void onError(Exception e) {                        dialog2.dismiss();                        responseInterface.onError(e);                    }                });    }    /**     * 更新家庭成员信息     * <UpdateUsersFamily xmlns="http://tempuri.org/">     * <strJson>string</strJson>     * </UpdateUsersFamily>     *     * UpdateUsersFamilyResult     */    public void requestUpdateUsers(Context context, final String strJson, final ResponseInterface responseInterface) {        // 参数集合        SimpleArrayMap mapParams = new SimpleArrayMap();        mapParams.put("strJson", strJson + "");        final ProgressDialog dialog2 = ProgressDialog.show(context, null, "正在修改信息...");        dialog2.setCancelable(true);        dialog2.setCanceledOnTouchOutside(false);        WebServiceUtils.call(ServiceConstants.URL_BASE + ServiceConstants.METHOD_UPDATA_USER,                ServiceConstants.NAME_SPACE, ServiceConstants.METHOD_UPDATA_USER, mapParams,                new ResponseInterface() {                    @Override                    public void onSuccess(SoapObject result) {                        dialog2.dismiss();                        responseInterface.onSuccess(result);                    }                    @Override                    public void onError(Exception e) {                        dialog2.dismiss();                        responseInterface.onError(e);                    }                });        Log.e("经过联网向服务器发送过去了Json字符串","服务器将返回修改成功或者失败");    }    /**     * 更新主用户信息     * <UpdateUsersFamily xmlns="http://tempuri.org/">     * <strJson>string</strJson>     * </UpdateUsersFamily>     *     * UpdateUsersFamilyResult     */    public void requestUpdateMaster(Context context, final String strJson, final ResponseInterface responseInterface) {        // 参数集合        SimpleArrayMap mapParams = new SimpleArrayMap();        mapParams.put("strJson", strJson + "");        final ProgressDialog dialog2 = ProgressDialog.show(context, null, "正在修改信息...");        dialog2.setCancelable(true);        dialog2.setCanceledOnTouchOutside(false);        WebServiceUtils.call(ServiceConstants.URL_BASE + ServiceConstants.METHOD_UPDATA_MASTER,                ServiceConstants.NAME_SPACE, ServiceConstants.METHOD_UPDATA_MASTER, mapParams,                new ResponseInterface() {                    @Override                    public void onSuccess(SoapObject result) {                        dialog2.dismiss();                        responseInterface.onSuccess(result);                    }                    @Override                    public void onError(Exception e) {                        dialog2.dismiss();                        responseInterface.onError(e);                    }                });    }}

好了,现在直接可以在Activity中使用了

第五步:开始使用

使用的话我就以登入为例吧,可以直接在Activity中这样调用

Login_manager.getInstance().requestLogin(this, username, usercode, new ResponseInterface() {    @Override    public void onSuccess(SoapObject result) {    String strResult=result.getPrimitivePropertyAsString("UserLoginResult");    JSONArray jsonArray = null;        int userID = 0;//这个userID是连接成功后返回的管理员ID,需要保存起来,在刷新数据的时候会用到        try {            jsonArray = new JSONArray(strResult);            userID = jsonArray.getJSONObject(0).getInt("ID");        } catch (JSONException e) {            e.printStackTrace();        }        if (userID > 0) {            Toast.makeText(Login_Activity.this, "登录成功!", Toast.LENGTH_SHORT).show();            saveUserMaster(userID, username);            Intent intent = new Intent(Login_Activity.this, UserActivity.class);            startActivity(intent);            finish();        } else {            Toast.makeText(Login_Activity.this, "登录失败,用户名或密码错误!", Toast.LENGTH_SHORT).show();        }    }    @Override    public void onError(Exception e) {    }});

好了,要是没看懂,多看几遍,然后找个服务端口实践下,我这里的服务端口好像已经没有用了,服务已经关闭了。



原创粉丝点击