转载

使用 Bluemix 构建 MVC 风格的移动应用程序

在 IBM Bluemix™ 中开发应用程序非常容易,这不是什么秘密。企业开发人员现在对使用 Bluemix 创建 “模型-视图-控制器(MVC)” 风格的移动应用程序非常感兴趣。本教程使用了一个简单的商业案例,向您展示如何使用 MVC 风格的架构在 Bluemix 中设计和开发应用程序。在开始构建之前,我们会介绍一些基础知识。

MVC 架构

MVC 是用来开发用户界面的最常用的功能强大的架构模式。MVC 架构模式是将应用程序分成以下三个部分的一种方式:模型、视图和控制器。视图负责管理来自用户的图形和文字输入。控制器负责解释来自用户的输入以及模型或视图要更改的命令(视情况而定)。模型负责管理应用程序的行为和数据,并响应指令(通常来自控制器),以便更改状态。在本教程中,我们采用了 MVC 架构风格来构建移动应用程序。

RESTful Web 服务

RESTful Web 服务是一些满足具象状态传输 (REST) 架构约束条件的 API。它们不要求客户端了解关于 API 结构的任何事情。浏览器不会预先获得关于要将元数据提交到何处以及提交哪些元数据的信息。服务器向客户端提供了必要的信息,比如 URI 和所需的字段,以便成功完成 API 调用。我们在样例应用程序的服务层中使用了 RESTful Web 服务。

始终使用 MVC。明确将业务逻辑与控制器逻辑和表象区分开来。良好的分层可以减少很多错误。

- The top Java EE best practices

示例商业案例

Bluemix Dairy Production Center 是一个研究所,可以使用相关技术和知识帮助牛奶生产商优化牛奶生产。牛奶生产商会获得经过 Dairy Production Center 分析和测试的奶牛,并收到关于每年的挤奶顺序和疾病控制的分析和建议。在执行分析期间,Dairy Production Center 想为牛奶生产商提供一种方式来查看有关其奶牛、牧群、挤奶顺序和疾病的信息。牛奶生产商能够发送和接收来自 Dairy Production Center 的新闻。

利用我们的简单的移动应用程序,牛奶生产商可以查看他们在 Dairy Production Center 中看到的相关信息。

使用 Bluemix 构建 MVC 风格的移动应用程序

应用程序架构和设计

设计该应用程序的时候使用了 MVC 风格的架构。

使用 Bluemix 构建 MVC 风格的移动应用程序

点击查看大图

关闭 [x]

使用 Bluemix 构建 MVC 风格的移动应用程序

流程

  1. Dairy Production Center Android 移动应用程序可以充当一个视图组件,它向 Bluemix WebSphere Liberty Runtime 中部署的控制器模块发出了一个 RESTful 服务请求。
  2. 基于来自移动应用程序的输入,控制器模块会向适当的数据访问对象发起一个调用,该对象会将数据返回给控制器。
  3. 在收到来自数据访问对象(模型)的响应之后,控制器会对移动应用程序进行响应,该应用程序以适当的形式将数据显示给用户。

MVC 组件包括:

数据访问层(模型)
充当一个接口,提供了对底层数据库(或其他任何持久存储)的访问。样例应用程序使用该访问层作为访问数据库的接口。数据访问对象(DAO)被用于分隔对 API 或操作的底层数据访问和高级业务服务。以下列表显示了 DAO 中实现的一些方法,这些方法用于从数据库中获得数据。 使用 Bluemix 构建 MVC 风格的移动应用程序
服务层(控制器)
通过使用数据访问层提供了对 GET、PUT 和 POST 数据的 RESTful 服务调用。基于表示层(视图、网络内容、移动等等)所请求的调用,控制器将会调用数据访问层来进行响应。样例应用程序将使用 Apache Wink 框架发布 RESTful 服务调用,该框架被用于实现和使用这一层中基于 REST 的 Web 服务。Wink 服务器模块是 JAX-RS v1.0 规范的完整实现。
  • https://<app-route>/rest/dairyproductioncenter/producer/{prodid}/cows
  • https://<app-route>/rest/dairyproductioncenter/producer/{prodid}/cows/{cowid}/herds
  • https://<app-route>/rest/dairyproductioncenter/news
  • https://<app-route>/rest/dairyproductioncenter/verifylogin
  • https://<app-route>/rest/dairyproductioncenter/producer/postnews
表示层(视图)
可以是与服务层交互的任何接口。您可以使用一个基于 Web 或基于移动的接口来发出服务请求或 API 调用。Android 移动应用程序充当了视图组件,它将向用户展示数据。

样例 Dairy Production Center 移动应用程序能够与 Bluemix 中暴露的 Dairy Production Center RESTful API 调用进行交互。该应用程序发布了任何外部客户端可以通过 HTTP 协议进行使用的 API。然后,牛奶生产商会有一个允许用户登录的移动应用程序:

使用 Bluemix 构建 MVC 风格的移动应用程序

查看奶牛列表和可用于奶牛的牧群的列表,并向 Dairy Production Center 传递消息。

使用 Bluemix 构建 MVC 风格的移动应用程序 使用 Bluemix 构建 MVC 风格的移动应用程序

运行应用程序

获取代码

实现应用程序需要做的准备工作

  • 一个 Bluemix 帐户。
  • 对 Java™ 编程和 Android Development ToolKit (ADT) 有基本的了解。
  • 熟悉 DB2®(或任何 RDBMS)和 JSON。
  • 了解基于 Apache Wink 1.1 的 JAX-RS 1.1 服务器运行时、Object Model 或 Streaming Model API for JSON Processing。

阅读: Android 应用程序开发

步骤 1. 构建数据访问层(模型)

要构建数据访问层,可以使用以下这些步骤创建数据库、模式、表、关系、数据和数据访问对象:

  1. 登录到 Bluemix 。
  2. 在仪表板中,在 Services 下,单击 ADD A SERVICE 。从 Data Management 部分添加 SQLDB Database 服务 。
  3. 单击仪表板中的图表打开 Launch 屏幕,以便查看 SQLDB Admin 控制台。
  4. 从 Bluemix 的 SQLDB/DB2 Service Management Console 中选择 Manage > Work with database objects使用 Bluemix 构建 MVC 风格的移动应用程序
  5. 在控制台的左上方,选择 Database Viewer > Schemas 。单击 RunDDL使用 Bluemix 构建 MVC 风格的移动应用程序
  6. 在 bluemixdairyproductioncenter-ddl 目录下执行 DevOps 代码库中提供的 DDL。
  7. 在无错误地执行 DDL 之后,通过选择并单击正确的模式、表、列和数据来验证表和列。 使用 Bluemix 构建 MVC 风格的移动应用程序

    点击查看大图

    关闭 [x]

    使用 Bluemix 构建 MVC 风格的移动应用程序

    使用 Bluemix 构建 MVC 风格的移动应用程序

    点击查看大图

    关闭 [x]

    使用 Bluemix 构建 MVC 风格的移动应用程序

现在是时候来查看用来开发数据访问层的代码了。

  1. 将源代码从 DevOps 服务导入到 Eclipse。
  2. 这一层中使用的主要数据访问对象是:

    • DairyProductionCenterDBConnection,该对象将连接到数据库
    • DairyProductionCenteDAOImpl,该对象将执行一些操作,在服务层发出请求的时候为生产商列出所有奶牛

    DAO 包下的列所组成的列表如下所示:

    使用 Bluemix 构建 MVC 风格的移动应用程序
  3. 要与数据库进行交互,必须获得一个连接到 SQLDB Service 的 JDBC 连接。使用以下代码连接到 Bluemix 中的 SQLDB 服务。
    public Connection getConnnection() throws SQLException{  Connection con = null;  try {   DB2SimpleDataSource dataSource = new DB2SimpleDataSource();   dataSource.setServerName(databaseHost);   dataSource.setPortNumber(port);   dataSource.setDatabaseName(databaseName);   dataSource.setUser(user);   dataSource.setPassword (password);   dataSource.setDriverType(4);   con=dataSource.getConnection();   con.setAutoCommit(false);  } catch (SQLException e) {   throw new SQLException();  }  return con;  }

下一个任务是使用 DAO 从数据库表 (DP_COWS) 中为生产商检索所有奶牛。

以下代码展示了如何从数据库中为生产商检索奶牛列表。执行以下方法从数据库中检索这些数据值:

public ArrayList<Cow> getAllCows(String prodid){  ArrayList<Cow> cwArraylist = new ArrayList<Cow>();  System.out.println("Inside Get All Cows" + prodid);  Connection conn = null;  try {   conn = new DairyProductionCenterDBConnection().getConnnection();   String tableName = "";   String sqlStatement = "";   String schemaName = "IBM_ECOD_DAIRYPRODUCTIONCENTER";   tableName = schemaName + "." + "DP_COWS";   Statement stmt = conn.createStatement();   sqlStatement = "SELECT * FROM " + tableName + " WHERE PRODUCER_ID =  " + "'" + prodid + "'";   ResultSet rs = stmt.executeQuery(sqlStatement);   while (rs.next()) {       Cow cw = new Cow(rs.getString("COW_ID"),      rs.getString("RFTAG_ID"),      rs.getString("HERD_ID"),      rs.getString("REPORT_COMMENTS"),      rs.getString("COW_NAME"));    cwArraylist.add(cw);   }   rs.close();   stmt.close();  }catch (SQLException e) {   return null;  } finally {   try { conn.close(); } catch (Exception e) { /* ignored */ }  }  return cwArraylist; } 

您会在数据库表 (DP_COWS) 中看到某个生产商的奶牛列表数据:

奶牛列表

使用 Bluemix 构建 MVC 风格的移动应用程序

点击查看大图

关闭 [x]

奶牛列表

使用 Bluemix 构建 MVC 风格的移动应用程序

步骤 2. 构建服务层(控制器)

创建一个服务层,该服务层将会调用数据服务层(模型),并向外部客户端发布 RESTful 服务。这一节将重点介绍如何构建和发布 CowList REST 服务,我们已经构建了数据访问层。REST 服务调用将通过调用数据访问层(如包结构中提到的那样)和下方的类来检索奶牛列表。

这一层是使用 Apache Wink REST 服务框架和 Java JSON Builder layer 实用工具实现的。用来开发 RESTful 服务调用的包和类如下所示:

使用 Bluemix 构建 MVC 风格的移动应用程序
  1. 使用以下代码来调用数据访问层,并开始发布 RESTful 服务(/dairyproductioncenterapi/producer/{prodid}/cows),以便访问 JSON 格式的数据。这些代码使用 RESTful 服务调用实现来检索某个生产商的奶牛列表。
    @Path("/dairyproductioncenterapi") public class DairyProductionCenterRestAPIs{    DairyProductionCenterDAO dpcDao = new DairyProductionCenterDAOImpl();   @Context HttpServletRequest request;  @GET  @Path("/producer/{prodid}/cows")  @Produces(MediaType.APPLICATION_JSON)  public Response getCows(@PathParam("prodid") String prodid){   System.out.println("Getting All Cows for----" + prodid);   ArrayList<Cow> cw = dpcDao.getAllCows(prodid);   if (cw.size() > 0) {    return Response.ok(JsonBuilderUtils.constructCowJSON(cw)).build();   } else {    return Response.ok(JsonBuilderUtils.constructCowJSON(cw)).build();   }  }
  2. 在完成服务和数据访问层之后,构建一个 WAR 文件,并在 Bluemix 中部署 WebSphere Liberty Runtime。
  3. 使用 REST 客户端访问 CowList RESTful 服务。下图是一个来自 Google Chrome Web 存储的 高级 REST 客户端 。您还可以使用来自 Google Chrome Web 存储的 Postman - REST 客户端

    来显示 RESTful 服务调用及其结果。

    比较 JSON 响应数据与数据库中的数据,如List of Cows中所示。

    https://bluemixdairyproductioncenter.mybluemix.net/rest/dairyproductioncenterapi/producer/PROD1/cows

    使用 Bluemix 构建 MVC 风格的移动应用程序

    点击查看大图

    关闭 [x]

    使用 Bluemix 构建 MVC 风格的移动应用程序

步骤 3. 构建表示层(视图)

表示层中的简单 Android 应用程序用于查看生产商的奶牛列表,该操作是使用前面小节中创建的服务和数据访问层来实现的。要构建移动应用程序,可以使用 Android Development ToolKit (ADT)。要调用 REST 服务调用,可以使用 Apache HTTP 客户端框架。

  1. 将源代码 (bluemixdairyproductioncenter-android) 从 DevOps Services 导入 ADT。从 Dairy Production Center Android Application Package 单击并打开 CowListActivity 类。 使用 Bluemix 构建 MVC 风格的移动应用程序
  2. 以下代码来自 CowListActivity 类,这些代码解释了如何调用服务层公布的 CowList RESTful 服务调用。前面步骤中的 RESTful 服务调用的结果将会导致产生一个 JSON 字符串。
    protected Boolean doInBackground(final String... args) {  // Creating service handler class instance  RESTInvoker sh = new RESTInvoker();  System.out.println("URL in cowlist-------" + url);  // Making a request to url and getting response  String jsonStr = sh.makeServiceCall(url, RESTInvoker.GET);   Log.d("Response: ", "> " + jsonStr);  return true; }  //RESTInvoker public String makeServiceCall(String url, int method,    List<NameValuePair> params) {  try {   // http client   DefaultHttpClient httpClient = new DefaultHttpClient();   HttpEntity httpEntity = null;   HttpResponse httpResponse = null;    //Checking http request method type   if (method == POST) {   HttpPost httpPost = new HttpPost(url);     if (params != null) {    httpPost.setEntity(new UrlEncodedFormEntity(params));    }     httpResponse = httpClient.execute(httpPost);     } else    if (method == GET) {     // appending params to url    if (params != null) {     String paramString = URLEncodedUtils       .format(params, "utf-8");     url += "?" + paramString;     System.out.println("URL in Service Handler ----" + url);    }    System.out.println("URL in Service Handler ----" + url);    HttpGet httpGet = new HttpGet();    URI website = new URI(url.trim());    httpGet.setURI(website);    httpResponse = httpClient.execute(httpGet);    }   httpEntity = httpResponse.getEntity();   response = EntityUtils.toString(httpEntity);   System.out.println("Response from Output Cow Rest call----" + response);   } catch (UnsupportedEncodingException e) {   e.printStackTrace();  } catch (ClientProtocolException e) {   e.printStackTrace();  } catch (IOException e) {   e.printStackTrace();  } catch (URISyntaxException e) {   // TODO Auto-generated catch block   e.printStackTrace();  }   return response;  }
  3. 您可以解析来自 RESTful 服务调用的 JSON 字符串响应(生产商的奶牛列表),以便在移动应用程序中显示数据。使用以下代码解析该请求:
    if (jsonStr != null) {     JSONObject jsonObj = new JSONObject(jsonStr);   System.out.println("JSONString in After converting to JSON Object -------" + jsonObj);   // Getting JSON Array node   cows = jsonObj.getJSONArray(TAG_COWS);    // looping through All Cows   for (int i = 0; i < cows.length(); i++) {    JSONObject c = cows.getJSONObject(i);    System.out.println("JSONString Inside i loop -------" + c);    String rfid = c.getString(TAG_RFID);    String cowname = c.getString(TAG_COWNAME);    String cowid = c.getString(TAG_COWID);    String herdid = c.getString(TAG_HERDID);    String report = c.getString(TAG_REPORT);     // tmp hashmap for single contact    HashMap<String, String> cows = new HashMap<String, String>();     // adding each child node to HashMap key => value    cows.put(TAG_COWID, cowid);    cows.put(TAG_RFID, rfid);    cows.put(TAG_HERDID, herdid);    cows.put(TAG_REPORT, report);     // adding contact to contact list    cowsList.add(cows);   } }
  4. 使用 ListAdapter 在移动应用程序中显示生产商的奶牛列表:
    protected void onPostExecute(final Boolean success) {      // Dismiss the progress dialog  if (pDialog.isShowing()){   pDialog.dismiss();  }  /**   * Updating parsed JSON data into ListView   * */  ListAdapter adapter = new SimpleAdapter(context,    cowsList, R.layout.cowinfo, new String[] { TAG_COWID,    TAG_RFID,TAG_HERDID,TAG_REPORT,}, new int[] { R.id.cowid,    R.id.rfid, R.id.herdid,R.id.report});   setListAdapter(adapter);   }

现在,编码已经完成了,您可以构建代码,并开始在 Android Emulator 中运行应用程序:

  1. 在 Eclipse 中,转到 Project > Properties > Android
  2. 确保选中了符合您的 API 级别的 API,然后单击 Apply
  3. 打开 Android Virtual Device Manager,选择您的设备,单击 Edit ,并设置 Target to API Level XX (其中的 XX 应该与您的 API 级别相匹配)。
  4. 右键单击 Project 并选择 Run As > Android Application
  5. 适用一个生产商 ID 登录到移动应用程序。
  6. 单击 Show My Cows
    使用 Bluemix 构建 MVC 风格的移动应用程序

    生产商的奶牛列表将会显示。

    使用 Bluemix 构建 MVC 风格的移动应用程序
  7. 将列表与数据库中的数据进行比较,如原始奶牛列表中所示。

结束语

使用 Bluemix 功能构建一个 MVC 风格的移动应用程序非常简单。在规划呈现内容和呈现方式的时候,一定要了解 MVC 实现的一些基础知识;在您自己的 MVC 平台上构建应用程序时,要了解关于事件和用户输入的基础知识。Bluemix PaaS 提供了一个用户友好的平台,该平台有许多功能,比如运行时、服务和移动特性,这些功能可以帮助您快速而又轻松地构建一个 MVC 风格的应用程序。

BLUEMIX SERVICE USED IN THIS TUTORIAL: SQLDB 数据库服务 向您的应用程序添加了一个随需应变的关系数据库。受到 DB2 的支持,它提供了一个托管数据库服务来处理 Web 工作负载和事务工作负载。

正文到此结束
Loading...