【一步一个脚印】Tomcat+MySQL为自己的APP打造服务器(3-3)Json数据交互

来源:互联网 发布:有线网络信号增强器 编辑:程序博客网 时间:2024/06/03 17:53

这篇文章实在是耽搁了太久了,唉,人生呐,怎一个懒字了得!都不好意思扯会儿淡了,进入正题吧。

上篇我们将 Android 和 Servlet 进行 POST 方式进行数据交互搞通了,但是在例子中传输的数据是以最简单的 String 类型来举例的,下边我们就来用现在流行的 JSON 格式跑一个。Json,是个轻量级的数据交换格式,但具体有什么优劣、使用场景有哪些、或者和别的数据格式对比如何,这些不是我们本次的讨论内容,我单单说,怎么在 Android 和 Servlet 之间使用 Json 进行数据交互。开始吧——

动手前我们需要先考虑考虑:使用 Json 在 Android 和 Servlet 进行数据交互是一个什么样的构造?(“构造”这个词想了几分钟,觉得还比较恰当,因为如果直接用“过程”就太直接,因为可能我们还没有想到他就是一个数据格式转化的过程)

… …
留两行空间
留点自主思考的时间
… …

其实,使用 Json 格式进行数据交互,无非就是在数据在网络发送前转成 Json 格式,接收到后数据后用 Json 格式恢复,然后根据需要再转换成相应的数据格式方便使用,就是这个一个简单的过程。

所以,我们需要在 Android端 和 服务端 都加入对 Json 的支持,下面我们从服务端工程开始:
Java本身是不提供 Json这种数据结构,需要引入第三方jar包 或者 添加依赖库,在此我们也不讨论这些库的优劣,只以最经典的 json-lib(如有需要,点我免积分下载) 为例来使用 json。

还是以简单的登陆逻辑为例,首先我们在服务端工程中加入json-lib需要的几个包:
红色框中为json需要的几个jar包

然后全部 Add to Build Path,此时 JsonObject、JsonArray等类就可以使用了,直接看代码吧:

/** * Servlet implementation class LoginServlet */@WebServlet(description = "登录", urlPatterns = { "/LoginServlet" })public class LoginServlet extends HttpServlet {    private static final long serialVersionUID = 1L;    /**     * @see HttpServlet#HttpServlet()     */    public LoginServlet() {        super();    }    /**     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse     *      response)     */    protected void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        System.out.println("不支持GET方法;");    }    /**     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse     *      response)     */    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        BufferedReader read = request.getReader();        StringBuilder sb = new StringBuilder();        String line = null;        while ((line = read.readLine()) != null) {            sb.append(line);        }        String req = sb.toString();        System.out.println(req);        // 第一步:获取 客户端 发来的请求,恢复其Json格式——>需要客户端发请求时也封装成Json格式        JSONObject object = JSONObject.fromObject(req);        // 第二步:将Json转化为别的数据结构方便使用或者直接使用(此处直接使用),进行业务处理,生成结果        // 拼接SQL查询语句        String sql = String.format("SELECT * FROM %s WHERE account='%s'",                 DBNames.Table_Account,                 object.getString("name"));        System.out.println(sql);        // 自定义的结果信息类        CommonResponse res = new CommonResponse();        try {            ResultSet result = DatabaseUtil.query(sql); // 数据库查询操作            if (result.next()) {                if (result.getString("password").equals(object.getString("password"))) {                    res.setResult("0", "登陆成功");                    res.getProperty().put("custId", result.getString("_id"));                } else {                    res.setResult("100", "登录失败,登录密码错误");                }            } else {                res.setResult("200", "该登陆账号未注册");            }        } catch (SQLException e) {            res.setResult("300", "数据库查询错误");            e.printStackTrace();        }        // 第三步:将结果封装成Json格式准备返回给客户端,但实际网络传输时还是传输json的字符串        // 和我们之前的String例子一样,只是Json提供了特定的字符串拼接格式        String resStr = JSONObject.fromObject(res).toString();        System.out.println(resStr);//      response.getWriter().append(EncryptUtil.getEDSEncryptStr(resStr)); // 可以对字符串进行加密操作,相应的到了客户端就需要解密        response.getWriter().append(resStr).flush();    }}

另外附上DatebaseUtil.java的代码:

public class DatabaseUtil {    private static Connection mConnection;    /**     * 获取数据库连接     *      * @return 唯一数据库连接     */    private static Connection getConnection() {        if (mConnection == null) {            String url = "jdbc:mysql://localhost:3306/db_myworld"; // 数据库的Url            try {                Class.forName("com.mysql.jdbc.Driver"); // java反射,固定写法                mConnection = (Connection) DriverManager.getConnection(url, "root", "wang,jie.");                LogUtil.log("创建数据库连接");            } catch (ClassNotFoundException e) {                e.printStackTrace();            } catch (SQLException e) {                System.out.println("SQLException: " + e.getMessage());                System.out.println("SQLState: " + e.getSQLState());                System.out.println("VendorError: " + e.getErrorCode());            }        }        return mConnection;    }    /**     * 查询操作     *      * @param querySql     *            查询操作SQL语句     * @return 查询     * @throws SQLException     */    public static ResultSet query(String querySql) throws SQLException {        Statement stateMent = (Statement) getConnection().createStatement();        return stateMent.executeQuery(querySql);    }    /**     * 插入、更新、删除操作     *      * @param insertSql     *            插入操作的SQL语句     * @return     * @throws SQLException     */    public static int update(String insertSql) throws SQLException {        Statement stateMent = (Statement) getConnection().createStatement();        return stateMent.executeUpdate(insertSql);    }    /**     * 关闭数据库连接     */    public static void closeConnection() {        if (mConnection != null) {            try {                mConnection.close();                mConnection = null;            } catch (SQLException e) {                LogUtil.log("数据库关闭异常:[" + e.getErrorCode() + "]" + e.getMessage());            }        }    }}

为了明了,数据库表格中就这么一条数据:

数据库表就这么一条示例数据

好了,服务端的处理就处理完了;

接下来该 Android 客户端的处理了:
Android 使用 Json 比服务端要简单很多,因为(据说,未经考证)自 Android 2.3起,Google 将Json加入 Android 源码,所以在 Android 2.3 及更高版本可以直接使用 Json 各类(Json 在 org.json 包下)而不用加入第三方jar包或额外添加依赖。

因为之前的文章中已经说的够清楚了,这里就不再粘贴大篇幅的代码,只将不同的不分贴出来:
参考 【一步一个脚印】Tomcat+MySQL为自己的APP打造服务器(3-1)Android 和 Service 的交互之GET方式 末尾 AsyncTask 类的使用,只要修改其中

    @Override    protected void onPostExecute(String result) {        if (!"".equals(result)) {            LogUtil.logResponse(result); // 日志输出原始应答报文            try {                JSONObject resultJson = new JSONObject(result); // 此处就可以将服务端返回的Json的字符串还原成Json格式的数据                // 下边就可以根据需求将Json转化合适的数据结构来使用了                // ... ...自己的业务逻辑            } catch (JSONException e) {                e.printStackTrace();            }        } else {            Log.e("WangJ", "结果为空!");        }    }

其实,说白了就是多了一步——在获取到服务端返回的报文后,将读取到的报文体字符串重新恢复 Json 格式(因为我们在 Servlet 中将信息封装成 Json 格式的返回给了 Android 客户端)。之后就可以根据自己的业务逻辑,将这个 Json 转成需要的数据结构,然后就是任你摆布了!

到此,使用 Json 进行数据交互的过程就可以说完成了。

但是,你肯定会觉得,这样的代码还真是不堪入目啊,毫无美感可言,甚至可以说是真烂真丑,我承认,确实。因为我们没有进行任何的封装,所以这些代码用起来真心不好用,也不好看,所以我们需要再用一篇来收个尾,把这个过程封装一下,也给这个系列画个句号——敬请期待,完结篇。

水平有限,如有不足,敬请指正,程序猿大人先行谢过!

8 0
原创粉丝点击