应用程序一个应用到 Java™ 代码中。
在您开始之前
关于本系列
Rational Application Developer、Zend Core for IBM、PHP 5 以及 DB2。您将应用 Java 和 PHP 5 分别编写部分代码。表现一个现有的股票经纪人公司,您将把一个 Facebook 接口添加到他们的在线投资组合管理系统之中。
关于本教程
程序开发环境、Zend Core For IBM 及其自带的 Apache 2 和 IBM DB2 Express-C 数据库、以及 IBM WebSphere Application Server。然后,您详细了解了 Facebook 的集成点 —— Facebook 所提供的将应用程序集成到社交网络中的机制,并且开始了某些骨干开发。您已经在 Facebook 上面创建并且配置了应用程序,为 Callback URL 创建了一个测试 index.php,然后设置了 DB2 数据库,创建了某些基础的数据表,并且将示例数据添加到数据表中。
使用进行集成的屏障之一,往往是不同的背景和看待世界的不同方式。这两种语言可以在同一个应用程序(以及同一支团队)中很好地共存,并且具有高度的抽象性和清晰的结构。
先决条件
无论具备何种程度的开发水平和经验,只要您希望应用 Java、PHP 或者将两者结合起来编写 Facebook 应用程序,那么本教程就是适合您的。本文适合于那些希望了解如何使用 Spring 架构建造 J2EE 应用程序,以及如何将一个面向对象的结构应用到他们的 PHP 应用程序中的 PHP 开发人员;本文还适合于那些希望开始使用 PHP,也许是有兴趣将 PHP 添加到一个现有的 Java 企业中的 Java 开发人员。
掌握 Facebook 应用程序开发,第 1 部分
在 PHP 旁边添加 Java
在第 1 部分中,您已经将应用程序的 PHP 那一边运行起来了。现在,您将创建 Java 这一边的内容 —— 使用流行的 Spring 架构,创建一个 Rational Rational Application Developer项目和 Web 应用程序。然后,您将编写 PHP 类,它使您能够将 PHP 上同样的 MVC 模式运用到 Java 中,并且使用 mod_rewrite 和 mod_proxy 创建一个从 Apache 到 IBM WebSphere 的反转代理,从而您可以使用同样的 Facebook Callback URL 用于 PHP 和 Java 服务器。然后,您将根据请求 URI 使用 .htaccess 文件将请求分派到 PHP 或 Java 中。在您的 Java 和 PHP 服务器之间的一个共同结构,将使得它们能够更容易地集成起来,并且使您(或者您的团队)能够为每一个 Facebook 应用程序应用更加适当的技术,而 proxy 和 .htaccess 的使用将解耦合前端和后端。
设置 Rational Rational Application Developer 项目
遵照下述步骤在 Rational Rational Application Developer中设置一个项目:
从开始菜单中,打开 Rational Rational Application Developer:Start > All Programs > IBM Software Development Platform > IBM Rational Application Developer > IBM Rational Application Developer。
创建一个新的 Java 项目(File > New > Project),选择 Dynamic Web Project 作为项目类型,WebSphere Application Server v6.1 作为目标运行时间。
请确保 Project Facets Dynamic Web Module、Java、JSTL 和 WebSphere Web Facets 都被选中。
为 facebook-stock-demo 设置上下文根目录,内容目录默认值为 WebContent,Java 源代码目录为 src。Rational Rational Application Developer随后将为您创建标准的 Web 应用程序项目。
合并 Spring 架构
将通用的 Spring 架构添加到应用程序之中。
下载 Spring 结构的版本。
将其解压到某个有用的位置,比如 c:\ (解压操作可能需要花费一定的时间),并且将 dist 文件夹中的 spring.jar 文件和 dist/modules 文件夹中的所有 JARs 文件拷贝到项目的 WEB-INF/lib 目录下。您可以通过 Project > Properties 找到您的项目的 WEB-INF/lib 目录。举例来说,我将它们拷贝到 C:\Documents and Settings\jmiles\IBM\rationalsdp7.0\workspace\facebook-stock-demo\WebContent\WEB-INF\lib 之中。
将 commons-logging.jar 添加到您的项目的类路径中,从 Spring 架构的 lib/jakarta-commons 目录下,通过 Project > Properties > Java Build Path > Add External JARs (请参见图 1 中所示)。不要将这个 JAR 拷贝到您的 lib 目录下;否则将导致 WebSphere 部署期间的一个错误。
图 1. 将额外的 JARs 添加到 IBM Ration Rational Application Developer项目之中
刷新工作区(右键单击项目的名称,并且选择 Refresh),Project Explorer 视图将会更新所有被添加的 JARs。
配置 Spring
现在,您已经完成 Spring 的安装,并且您需要配置 Web 应用程序才能使用它。右键单击 Project Explorer 中的 web.xml (请参见图 2 中所示),并且选择 Open with > Text Editor。
图 2. 在 Rational Rational Application Developer中的文本编辑器中打开 web.xml
将内容替换为列表 1 中的内容。
列表 1. web.xml <?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>facebook-stock-demo</display-name>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/action/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
这将发送所有的请求,它们的 URI 以 facebook-stock-demo/action 开头,穿过 Spring 的 DispatcherServlet 入口点进入 Spring MVC 架构。
接下来,您需要一个 spring-servlet.xml 文件来配置 Spring beans。默认情况下,Spring 将 -servlet.xml 添加到 web.xml 中的 <servlet-name> 元素上,作为配置文件的名称,所以在 Project Explorer 视图中,在 WEB-INF 下创建一个新的文本文件,并且取名为 spring-servlet.xml。如果 Rational Rational Application Developer用一个 XML 编辑器将其打开的话,那么您就必须关闭该文件,然后右键单击它,从而在文本编辑器中将其打开。将列表 2 中的内容粘贴到 spring-servlet.xml 之中。
列表 2. 原始的 spring-servlet.xml<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.
handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<entry key="/stockList">
<ref bean="stockListController"/>
</entry>
</map>
</property>
</bean>
<bean id="stockListController"
class="com.jm.fbstockdemo.StockListController">
<property name="successView">
<value>stockList.jsp</value>
</property>
</bean>
</beans>
第一个 bean 指定了如何将视图名称映射到 URLs 上。每当控制器返回一个视图名称,视图解决器就会预先考虑 /WEB-INF/jsp/,举例来说,生产 /WEB-INF/jsp/stocks.jsp 来响应视图名称 stocks.jsp。第二个 bean 将 URLs 映射到 Spring 控制器,在这种情况下映射一个 /stockList 到控制器 bean 中,并且带有标识符 stockListController,而它正是定义在文件中的第三个 bean。stockListController bean 定义注入一个 successView 属性到 StockListController 对象中,从而保持 Java 代码外部视图的名称。
添加一个 Spring 控制器类和视图
要添加一个 Spring 控制器类和视图,请完成以下这些操作:
在 src 目录下,右键单击 Java Resources: src 创建一个包,并且选择 New > Package。我将我的称作 com.jm.fbstockdemo。
右键单击新创建的包,并且创建一个 StockPriceController 类,用来执行 org.springframework.web.servlet.mvc.Controller。您可以在点击 Add 后输入 Controller,则 Rational Rational Application Developer将列出一组与之匹配的选项。
填充基本的执行,返回一个视图名称(请参见列表 3 中所示)。
列表 3. 一个原始类 StockListController (Java) public class StockListController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
return new ModelAndView (getSuccessView());
}
}
接下来,右键单击 WEB-INF 并创建一个 jsp 目录。
在 jsp 目录下创建原始的 stockList.jsp,其中包含列表 4 中所示的 xml。
列表 4. 一个原始的 stockList.jsp <%@ page contentType="text/xml" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<stockList>
<stock>
<id>1</id>
<ticker>JAKE</ticker>
<price>3000</ticker>
</stock>
</stockList>
部署到 WebSphere Application Server
现在,您可以将 Java Spring 应用程序部署到 WebSphere Application Server 中了。
右键单击 Rational Rational Application Developer中的项目,创建 WAR 文件,并且选择 Export > WAR file。
在 Save As 窗口中,浏览到项目目录下(如前所示),并且创建一个名为 dist 的新文件夹。举例来说,我将我的 WAR 文件保存为 c:\Documents and Settings\jmiles\IBM\rationalsdp7.0\workspace\facebook-stock-demo\dist \facebook-stock-demo.war。
点击 Finish。Rational Rational Application Developer 将把应用程序包装到 facebook-stock-demo.war 之中。
图 3. 从 Windows 开始菜单中启动 WebSphere Application Server
登录进入 admin 控制台,打开 Applications 标签并且选择 Install New Application。
选择 Local file system,浏览到您的 WAR 文件,并且将其选中。
指定 /facebook-stock-demo 作为上下文的根目录,并且点击 Next。在 Select 安装选项窗口中,保持所有默认的设置并且点击 Next。
在 "Map modules to servers" 屏幕上,选择您所要添加到 server1 中的 Web 应用程序。
在总结屏幕上,点击 Finish。于是 WebSphere 将会安装该 Web 应用程序。请确保在安装过程结束之后,点击输出屏幕底部的 Save。
点击左侧的 Enterprise Applications,您将看到您的应用程序出现在已被安装的应用程序列表中。将其选中并且点击 Start 启动。
为了确认您的应用程序所运行的端口是哪一个,请打开左侧的 Servers 小节,点击 Application servers,选择 server1,并且在 Communications 小节中点击 Ports (请参见图 4 中所示)。WC_defaulthost 指定访问您的 Web 应用程序的端口号。在我的安装中,该端口号是 9083;将您的 WC_defaulthost 替换为图 4 中所示的内容。
图 4. 在 WebSphere Application Server 中找到您的服务器的 HTTP 端口。
最后,确认一切正常,打开另一个浏览器窗口,输入 http://localhost:9083/facebook-stock-demo/action/stockList,您将会看到 stockList.jsp 的 xml。
Spring MVC Web 应用程序现在已经被安装和工作在 IBM WebSphere 下面了,并且为开发您的 Facebook 应用程序代码提供了一个 标准的 MVC 结构。
构造一个 PHP 应用程序类似于构造一个 Java Spring 应用程序
Java Web 应用程序和 Spring 的 DispatcherServlet 结构为应用程序的 PHP 部分提供了一个极好的模型。与将这样出色的面向对象抽象抛出窗口所不同的是,您将快速地获得有助于模拟 Spring 的属性注入和 MVC 分派功能的一组类。您将编写一个负责读取多个属性文件的 Properties 类,一个使您从那些文件中向类实例注入属性的 Injectable 类,以及一个根据请求变化将其分派到正确的控制器类的 ActionDispatcher 类。
对于编写 PHP 代码来说,任何文本编辑器都是可以的,但是 Zend Studio 无疑是最好的一个选择。
从多个属性文件中读取数值(http://www.my400800.cn )
要保持应用程序的持续性,您将使用一组属性文件和一个读取它们的类 Properties,正如列表 5 中所示的那样(将 Properties.php 放到 fb_stock_demo 下面的一个 lib 子目录中)。
列表 5. Properties.php<?php
class Properties {
private $props;
public function __construct ($propertiesFilePaths) {
$this->props = array();
foreach ($propertiesFilePaths as $path) {
$this->loadProperties($path);
}
}
private function loadProperties($propertiesFilePath) {
$lines = file($propertiesFilePath);
foreach ($lines as $line) {
$trimmed = trim($line);
if (strlen($trimmed) > 0 && strchr($trimmed, 0, 1) != "#") {
$split = split("=", trim($line));
$key = $split[0];
$value = $split[1];
$this->props[$key] = $value;
}
}
}
public function get($key) {
if (! isset($this->props[$key])) {
throw new Exception ("Properties: unknown key $key");
}
return $this->props[$key];
}
}
您为构造器提供一组属性的文件路径,构造器将他们逐个读入,并且集合到 loadProperties() 之中。采用一组属性的文件路径而不是一个属性的文件路径,使您可以分割那些依赖于环境的属性,例如:数据库连接值等。这样做使得您从一个环境向另一个环境 复制代码变得更加容易,并且不需要重写那些值;在复制期间,您并不需要复制特定环境的文件,或者设置那些不能被您重写的许可。举例来说,这个应用程序将使 用两个属性文件,它们分别是 app.properties 和 db.properties,其中 app.properties 包含诸如 Facebook API Key 和 Secret 这样的约束条件,而 db.properties 包含数据库登录信息。
使用 PHP 5 魔法方法提供类似 Spring 属性的注入
对于 PHP 5 魔法来说,为了提供一些更加类似 Spring 的东西,您可以从一个配置文件中将属性注入到一个对象之中。所有需要这样的注入属性的类,都需要继承 Injectable 基类(请参见列表 6 中所示)。
列表 6. Injectable 类 (PHP)
class Injectable {
protected $properties;
private $prefix;
public function Injectable($properties=null, $propPrefix=null) {
$this->prefix = $propPrefix == null ? get_class($this) . '/' : $propPrefix;
$this->setProperties ($properties);
}
public function setProperties($properties) {
$this->properties = $properties;
}
public function __get($property) {
return $this->getProperty($property);
}
public function getProperty($property) {
return $this->properties->get($this->prefix . $property);
}
}