1:KSOAP2完成POJO对象序列化网络传输
在Android应用中对象的序列化传输总是一个很重要的话题,我们再往程序中提交信息的时候,总是尝试着以对象的形式来封装,然后传递的也是对象。序列化传输是Java的基础知识,具体怎样去用,就属于javaIO的基础知识,此处不做解释,现在我们主要来讨论一下POJO对象在网络中的序列化传输;先假设服务器端数据库中某一个表中有3个字段:uid(int),username(varchar),password(varchar),这里用MySQL数据库做验证, 我们在服务器端创建一个POJO对象包括前面说过的三个属性
user类:要序列化的对象
//创建一个POJO类,用于对象传输 public class User { private int uid; private String username; private String password; public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } 。。。省略其余两个 public User(int uid, String username, String password) { super(); this.uid = uid; this.username = username; this.password = password; } public User() { super(); } }
用做数据库连接的DBConn类,要是有时间的话,可以进一步封装;
public class DBConn { private Connection conn; private PreparedStatement ptmt; private ResultSet rs; //得到数据库连接 private void getConn(){ try { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://172.31.147.20:3306/user"; String username = "root"; String password = "root"; conn = DriverManager.getConnection(url, username, password); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } //关闭数据库 public void closeConn(){ if(rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(ptmt != null){ try { ptmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } //增删改 操作 public int execOther(final String strSQL,final Object[] params){ this.getConn(); System.out.println("SQL>"+strSQL); try { ptmt = conn.prepareStatement(strSQL); for (int i = 0; i < params.length; i++) { this.ptmt.setObject(i+1, params[i]); } int res = this.ptmt.executeUpdate(); return res; } catch (SQLException e) { e.printStackTrace(); } return -1; } //查询操作 public ResultSet execQuery(final String strSQL,final Object[] params){ this.getConn(); System.out.println("SQL>"+strSQL); try { ptmt = conn.prepareStatement(strSQL); for (int i = 0; i < params.length; i++) { this.ptmt.setObject(i+1, params[i]); } ResultSet rs = this.ptmt.executeQuery(); return rs; } catch (SQLException e) { e.printStackTrace(); } return null; } }
服务器端Dao类UserDao
public class UserDao { DBConn dbconn = null; public UserDao() { super(); this.dbconn = new DBConn(); } // 用户信息的添加操作 public boolean addUser(final User user) { //调用JDBC,完成数据库的添加操作 System.out.println("调用UserDao的addUser方法了..."); String username = user.getUsername(); String password = user.getPassword(); String strSQL = "insert into user values(null,?,?)"; System.out.println("strSQL->"+strSQL); Object params[] = new Object[]{username,password}; int res = dbconn.execOther(strSQL, params); dbconn.closeConn(); return res>0?true:false; } }
现在,我们在服务器端的工作已经做好了,进行Web Service界面的调试,查看是否有问题,如果插入数据不出现异常,说明Web Service --->MySQL成功
然后,我们开发Android端的编写,在Android端建立一个要序列化的类。类名要与服务器端的一致,下面给出代码详细说明一下
Android端User
public class User implements KvmSerializable { // 这里所有的属性都必须与Server端相同,还要重写4个方法 private int uid; private String username; private String password; ........同服务器端程序 //index代表属性的下标,一定要是从0开始 @Override public Object getProperty(int index) { Object obj = null; switch(index){ case 0: obj = this.uid; break; case 1: obj = this.username; break; case 2: obj = this.password; break; } return obj; } //该实体类共有多少属性 @Override public int getPropertyCount() { // 这里一定不能写成User.class.getFields().length,要写明白数目 return 3; } //得到所有属性的详细信息 @Override public void getPropertyInfo(int index, @SuppressWarnings("rawtypes") Hashtable arg1, PropertyInfo info) { switch (index) { case 0: info.name = "uid"; info.type = PropertyInfo.INTEGER_CLASS; break; case 1: info.name = "username"; info.type = PropertyInfo.STRING_CLASS; break; case 2: info.name = "password"; info.type = PropertyInfo.STRING_CLASS; break; default: break; } } //设置属性 @Override public void setProperty(int index, Object obj) { switch (index) { case 0: this.uid = Integer.parseInt(obj.toString()); break; case 1: this.username = obj.toString(); break; case 2: this.password = obj.toString(); break; default: break; } } }
Android端前台界面如下
Activity逻辑代码:
class ViewOcl implements View.OnClickListener { String wsdlURL; String webMethod; String namespace; String soapAction; SoapObject soapObject; SoapSerializationEnvelope envelope; HttpTransportSE se; @Override public void onClick(View v) { switch (v.getId()) { case R.id.btnAddUser: User u = new User(); //u.setUid(1); u.setUsername("罗逸"); u.setPassword("233456"); // 步骤1:设置调用Web Service的参数 wsdlURL = "http://172.31.147.20:8080/CloudService/services/UserService"; webMethod = "add"; namespace = "http://services.chinasoft.com"; soapAction = namespace + webMethod; // 步骤2:创建一个SoapObject对象,信封中的信内容 soapObject = new SoapObject(namespace, webMethod); // 步骤3:传递参数 ,添加user对象到信封, // user应该与 Web Services Explorer页面中add方法要传递的对象名称保持相同 soapObject.addProperty("user", u); // 步骤4:创建一个SoapSerializationEnvelope,信封:设定信封传递方式 envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); //核心重点:指定服务器端的反序列化类对象, //namespace和name都需要到WebService的XML文件中查找,clazz:指定要序列化的类对象 envelope.addMapping("http://po.chinasoft.com/xsd", "User", u.getClass()); // 步骤5:设置一下传回对象 将信装载到信封 envelope.bodyOut = soapObject; // 步骤6:创建HttpTransportSE,用于传输数据,邮递员:将邮递地址给予邮递员 se = new HttpTransportSE(wsdlURL); try { // 步骤7:发送请求 送信 se.call(soapAction, envelope); // 步骤8:获取从互联网返回的结果,测试信有没有送到 if (envelope.getResponse() != null) { Object result = envelope.getResponse(); // 测试:显示结果 Toast.makeText(SoapClientActivity.this, "结果为:" + result.toString(), Toast.LENGTH_LONG) .show(); } } catch (IOException e) { e.printStackTrace(); } catch (XmlPullParserException e) { e.printStackTrace(); } break;
最后不要忘记加包:mysql_jdbc和KSoap包,还有
最后在AndroidManifest.xml中添加:
<uses-permission android:name="android.permission.INTERNET"/>