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

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

上篇我们将 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需要的几个包:
【一步一个脚印】Tomcat+MySQL为自己的APP打造服务器(3-3)Json数据交互_第1张图片

然后全部 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 进行数据交互的过程就可以说完成了。

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

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

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