一般情况下,客户端和服务端的数据交互都是使用json和XML,相比于XML,json更加轻量级,并且省流量,但是,无论我们用json还是用xml,都需要我们先将数据封装成json字符串或者是一个xml字符串然后传输,那么有没有可能我们直接在android客户端上传递一个Object给服务器端呢?答案是肯定的。
我们看一个简单的App注册页面,如下图:
当我们点击注册按钮的时候,将用户的注册信息通过一个Object对象传递到服务器,好,下来我们看看怎么样来传递对象:
首先我们要把用户的注册信息封装成一个JavaBean,为了这个JavaBean可以在网络上传输,我们要实现Serializable接口:
public class Person implements Serializable { /** * */ private static final long serialVersionUID = 1L; private String password; private String username; private String nickname; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public Person(String password, String username, String nickname) { super(); this.password = password; this.username = username; this.nickname = nickname; } public Person() { } }
当我们点击注册按钮的时候,先将用户的注册信息封装起来,然后使用一个AsyncTask来执行网络请求,该AsyncTask的参数即用户注册信息封装成的Bean:
TransObject to = new TransObject(); to.execute(new Person(passwd.getText().toString(), name.getText() .toString(), nickname.getText().toString()));
好,我们下来看看TransObject这个类:
class TransObject extends AsyncTask<Person, Void, String> { @Override protected String doInBackground(Person... params) { StringBuffer sb = new StringBuffer(); Person p = params[0]; BufferedReader reader = null; HttpURLConnection con = null; ObjectOutputStream oos = null; try { URL url = new URL("http://192.168.1.106/android/to"); con = (HttpURLConnection) url.openConnection(); // 设置允许输出,默认为false con.setDoOutput(true); con.setConnectTimeout(5 * 1000); con.setReadTimeout(10 * 1000); // 请求方式为POST请求 con.setRequestMethod("POST"); oos = new ObjectOutputStream(con.getOutputStream()); // 向服务端写数据 oos.writeObject(p); // 获得服务端的返回数据 InputStreamReader read = new InputStreamReader( con.getInputStream()); reader = new BufferedReader(read); String line = ""; while ((line = reader.readLine()) != null) { sb.append(line); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (oos != null) { try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } if (con != null) { con.disconnect(); } } return sb.toString(); } @Override protected void onPostExecute(String result) { super.onPostExecute(result); if (result != null && "OK".equals(result)) { Toast.makeText(MainActivity.this, "注册成功", Toast.LENGTH_SHORT) .show(); } } }我们在doInBackground中执行我们的网络请求,通过一个对象输出流将我们的对象输出到服务端,然后将请求结果返回给onPostExecute方法,在onPostExecute中判断是否注册成功。这是客户端的写法,我们再看看服务端的写法:
@WebServlet("/to") public class TransObject extends HttpServlet { private static final long serialVersionUID = 1L; public TransObject() { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doGet"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doPost"); ObjectInputStream ois = new ObjectInputStream(request.getInputStream()); try { Person p = (Person) ois.readObject(); System.out.println("密码是:" + p.getPassword()); System.out.println("用户名是:" + p.getUsername()); System.out.println("昵称是:" + p.getNickname()); PrintWriter out = response.getWriter(); out.print("OK"); out.flush(); out.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if (ois != null) { ois.close(); } } } }
在服务端我们使用一个Servlet来接收客户端传来的数据,在doPost方法中,我们使用ObjectInputStream来接收android传来的对象,获得Person对象之后我们将其中的值打印出来,同时返回给客户端一个OK。这里需要注意的一点是服务端的Person类要和客户端的Person类一模一样(包括包名),否则会有异常,如下图:
好了,经过上面几个步骤我们就可以给将android客户端的一个Object传递到服务器上了,就这么简单,省去了将对象转为json或者XML的麻烦。