使用HttpURLConnection實現在android客戶端和服務器之間傳遞對象

一般情況下,客戶端和服務端的數據交互都是使用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:

ansObject to = new TransObject();
            to.execute(new Person(passwd.getText().toString(), name.getText()
                    .toString(), nickname.getText().toString()));

好,我們下來看看TransObject這個類

class TransObject extends AsyncTask<person, 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();
        }
    }
}</person,>

我們在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的麻煩。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章