WEB开发网
开发学院操作系统Linux/Unix 在 AIX Version 5.3 中使用 Java 和 PHP 技术进行... 阅读

在 AIX Version 5.3 中使用 Java 和 PHP 技术进行开发 (6)

 2008-11-10 08:25:53 来源:WEB开发网   
核心提示:开始之前本教程面向那些希望在 Web 应用程序开发中快速集成 PHP 和 Java™ 的 AIX® 5.3 开发人员,在本教程中,在 AIX Version 5.3 中使用 Java 和 PHP 技术进行开发 (6),您将完成一个解决方案的构建过程,其中使用 PHP 作为前端,所得到的结果是原始类的

开始之前

本教程面向那些希望在 Web 应用程序开发中快速集成 PHP 和 Java™ 的 AIX® 5.3 开发人员。在本教程中,您将完成一个解决方案的构建过程,其中使用 PHP 作为前端,而使用问卷调查应用程序的 Java 类作为后端。在您研究后端 Java 类的 PHP 接口的最终解决方案之前,您还将研究 Web 服务和 PHP Java Bridge 接口之间的区别、以及 PHP 和 Java 开发方法之间的区别。您应该具有基本的 Java 编程能力,并对基本的 Web 开发环境有所了解。

关于本系列

PHP 是一种非常优秀的 Web 开发语言,而在商业应用程序开发方面,Java 编程语言十分流行。因此,为了在 AIX Version 5.3 操作系统上充分利用它们的优势,专门开发了 PHP Java Bridge。本系列文章向 AIX 5.3 开发人员介绍了如何在他们的 Web 应用程序开发中集成 PHP 和 Java 技术。

为了说明这一点,您将按照典型的开发过程来构建一个简单的问卷调查应用程序,具体内容包括:

开发主要的 Java 应用程序

通过 Servlet 将 Java 应用程序公开为基于 Java 的 Web 应用程序

添加在数据库中存储信息的支持

将原始应用程序公开为 Web Services,并为该应用程序提供 PHP 接口

使用专门的 PHP Java Bridge 重新开发 PHP 接口

本系列文章共分为六个部分:

第 1 部分介绍了一个应用程序,并为构建 Java 应用程序以及使用 Tomcat 执行基于 Java 的 Web 应用程序搭建了相应的环境。

第 2 部分介绍了主要的应用程序代码以及一个简单的 Java Servlet 的开发,以便为信息提供一个 Web 接口。

第 3 部分将核心应用程序连接到 DB2® 数据库,以便对问卷调查的问题和回答进行存储。

第 4 部分对原始应用程序进行转换,使其能够作为 Web Services 进行访问,并且它为 PHP 接口提供了基础。

第 5 部分使用 PHP Java Bridge 为 Java 应用程序构建 PHP 接口。

第 6 部分对这个应用程序进行重新开发,以便使用 PHP Java Bridge 来代替 Web Services 接口。

关于本教程

本教程是这个系列文章的最后一个部分,在本教程中,您将了解如何组合使用 PHP 和 Java 技术,以便为支持问卷调查应用程序的原始 Java 类构建 Web 接口。这个最终解决方案使用 PHP Java Bridge 以使得您可以为在本系列文章的前面几个部分中所开发的 Java 类构建基于 PHP 的接口。

您首先将了解 PHP Java Bridge、以及它的操作与最初开发的 Web 服务方法之间的区别,从而对这几种不同的技术进行比较。然后,在研究原始 Java 类的 PHP 接口的最终备选方法之前,您将研究几种不同的集成您的基于 PHP 和 Java 的解决方案。

先决条件

为了学习本教程,您需要安装下列软件:

IBM pSeries® 服务器(本文中的代码使用 AIX Version 5.3 进行了测试。)

Apache Tomcat 系统

Eclipse IDE

Java 5 64-bit SDK(要下载这个包,您需要进行注册,但注册是免费的。)

Mozilla Web browser for AIX

几种不同连接技术的比较

问卷调查应用程序所使用的 Web 服务方法为您提供了极大的灵活性,而 PHP Java Bridge 以不同的方式提供了类似的灵活性。在您更深入地研究开发过程之前,让我们更仔细地分析一下它们之间的区别和相似之处。

Web 服务方法

您对原始应用程序进行了转换,这样一来,在本系列文章的第四部分中(请参见参考资料),就可以将其作为 Web Services 进行访问。除了可访问性之外,Web Services 模型还具有许多其它的优点。通过 Web Services 接口来公开类,您可以保证互操作性,因为几乎所有的语言都支持某些形式的 Web Services ,无论是 XML-RPC 还是简单对象访问协议 (SOAP)。

这也就带来了极大的灵活性。现在,您的 Java 后端可以由采用 C、Perl、Java 语言、PHP、JavaScript 和许多其他编程语言所编写的脚本和应用程序来进行访问;然而,实现互操作性是要付出一定代价的。

正如您在本系列文章的第四部分中所看到的,将您的应用程序公开为 Web Services 是一项复杂的任务。要正确地完成这项工作,需要通过 Web 服务描述语言 (WSDL) 文件开发和部署您的代码;然后,您必须单独地为每个函数定义不同的接口,同时还需要确保采用与您希望使用的标准可互操作的格式,对所提供的值和返回的值进行编码和封装。

在您为核心类开发和添加新的功能和扩展时,所有的这些工作都需要花费大量的时间进行开发、以及较长的时间进行控制。要使得原始类能够通过 Web 服务接口进行访问,可能会使得您的开发时间增加 20% 到 50%。

而且,正如稍后将更详细地进行介绍的,Web 服务方法还隐含了不容忽视的显著性能开销(如果您希望在大型操作环境中部署该应用程序的话)。

PHP Java Bridge

在本系列文章的第五部分中,您详细地了解了 PHP Java Bridge(请参见参考资料),但是 PHP Java Bridge 的关键元素允许您直接从 PHP 内部访问 Java 类,就好像您正在访问本地 PHP 类一样。

尽管 Web 服务和 PHP Java Bridge 接口在本质上存在很大的差别,但事实上,它们都使用 XML 进行通信,以交换有关原始方法和类、以及应该如何对它们进行访问的信息。与 Web 服务解决方案有所不同,这个过程是自动的。

正如您在第五部分中所看到的(请参见参考资料)、以及本文清单 1 中所介绍的,在您导入 PHP 元素、并且创建到远程 Java 主机的连接之后,使用和创建 Java 类和对象是非常简单的。

清单 1. 简单的 PHP Java Bridge 的示例

          
<?
require_once("http://sulaco.mcslp.pri:8080/JavaBridge/java/Java.inc");
$System = new Java("java.lang.System");
print_r($System->getProperties());
?>

在本教程后面的内容中,您将研究所需的确切的方法和解决方案。

区别和相似之处

Web Services 和 PHP Java 解决方案之间存在许多明显的区别和相似之处,从而使得采用这两种方法开发和部署应用程序时具有相应的优点和缺点。

例如,Web 服务和 PHP Java Bridge 解决方案都允许您使用 PHP 作为前端、使用 Java 环境作为应用程序的后端部分。对于 Web 服务解决方案,您必须开发原始类、Web 服务类和 PHP 接口。对于 PHP Java Bridge,您只需要开发原始 Java 类和 PHP 前端,PHP Java Bridge 可以为您处理所有的互操作性问题。

在 Web 服务和 PHP Java Bridge 解决方案之间还存在一个比较显著的区别,即完成解决方案所需的步骤有所不同。Web 服务解决方案需要额外的开发时间,以使用所需的 Web 服务接口来公开服务、并使得它们可供使用。在 PHP 中使用 Web 服务也是相当繁琐的,因为您必须开发一个能够为已开发的 Web 服务接口提供接口的解决方案。

对于 PHP Java Bridge,您可以直接访问现有的 Java 类,而不必在 Java 端显式地开发接口、或者在 PHP 端显式地开发访问接口。

性能

为了将您的原始请求转换为完全与平台无关的形式,使用 Web 服务的关键问题之一是必须将请求转换为 XML。所得到的 XML 数据包中包括请求、源或目标信息、以及请求中所包含的任何数据或者信息(例如,方法或函数的参数),这使得 XML 组件的负载变得非常大。

采用这种方式生成有效的 XML 是相当花费时间的,但是对该信息进行解码甚至可能需要花费更多的时间,因为 XML 解析的过程并不像您所预期的那么简单和直接。和发送请求到服务器的客户端的负载相比,这个处理过程会呈现更高的负载,随后还会有接受请求和最后处理请求的过程。在将响应发送回客户端的时候,将按相反的顺序执行相同的处理过程(采用 XML 对响应进行编码,发送到客户端,客户端解析 XML 并且提取响应)。

您可以在图 1 中更详细地看到这个过程。

图 1. 实际应用中的 Web 服务接口

在 AIX Version 5.3 中使用 Java 和 <a target=PHP 技术进行开发 (6)" onload="return imgzoom(this,550);" onclick="javascript:window.open(this.src);" style="cursor:pointer;"/>

开放的格式和采用 XML 进行编码使得 Web 服务具有较好的兼容性和可访问性;然而,它也使得客户端和服务器出现了显著的负载,因为必须创建并解析 XML 以进行信息交换。

如果您希望使用 Web Services 作为您的解决方案,以便使用 PHP 作为前端来公开您的 Java 应用程序,那么请记住,Web 服务器中将出现较大的负载,因为您必须在同一台计算机中对 XML 进行两次编码和解码。

通过使用 PHP Java Bridge,仍然需要对信息进行编码,甚至采用 XML 进行编码,但是与 SOAP 或者 XML-RPC 相比,这种编码形式更加严格,并且更加容易进行编码和解码。

Java 和 PHP 开发

在开发基于 Java 的 Web 应用程序和 PHP 应用程序时,存在一些重要的区别。需要考虑这些区别、及其对开发问卷调查解决方案所产生的影响。

Java 技术是一种基于对象和类的编译型语言。正如您在使用 Java 语言时所看到的,您必须编辑源代码,然后在使用源代码之前,将这些源代码编译为最终的类。

PHP 是一种解释型的语言,这意味着您只需要编辑源代码,然后访问 PHP 页面以执行程序。这使得应用程序的开发变得非常快捷,因为您只需要做很少的工作就可以启用您的应用程序了。

在缺省情况下,PHP 并不是一种面向对象的语言,但是它支持面向对象的概念,并且您可以访问类实例的各种属性和执行类实例的各种方法。在 Java 环境中,通过在类实例和某个方法之间使用点号进行分隔,您就可以访问这个方法:

surveyquestion.ashtml()

对于 PHP,您需要使用下面这行代码:
$surveyquestion->ashtml()

对于 PHP Java Bridge,大多数 PHP 类型将被自动地转换为相应的 Java 类型(反之亦然)。因为可用的类型存在区别,所以两者之间存在一些细微的区别。例如,PHP 没有 Java 语言中的 Boolean 数据类型的概念。要在 PHP 和 Java 语言之间交换 Boolean 数据类型,您必须为这个值使用整数创建一个新的 Boolean 类型,然后使用它,如清单 2 中所示。

清单 2. 为这个值使用整数创建一个新的 Boolean 类型

          
$boolean = new Java("java.lang.Boolean",1);    
print $question->htmlquestion($boolean);

对于数组也存在类似的问题,PHP 本身并不支持不带参数的数组类型(PHP 中的所有数组都是映射),但是通过使用 PHP array() 类型创建一个通过下标进行引用的常规数组,您就可以模拟 Java 数组:

array("Red","Green","Blue")

在本教程后面的部分中,当您开始开发最终的 PHP 接口时,您将看见这种情况在实际应用中的一些示例。

开发 Web 接口

使用原始 Java 类,您开发了一个构建于 Java 类之上的 Java Servlet 解决方案,将最初通过简单命令行文本接口进行工作的、基于 Java 的问卷调查应用程序更改为 Web 应用程序。现在,您将构建一个新的接口,该接口使用了完全不同的语言。

再谈 Java 环境的 Web 接口

在本系列文章的第四部分中所开发的解决方案中使用了 Tomcat 部署平台的 Servlet 接口,以提供 Java 应用程序和您希望向用户提供的 HTML 以及 HTTP 接口之间的接口。

外部包装类 WebSurvey,是原始核心 Survey 类的一个扩展,它使用不同的 Survey 类构建了 SurveyQuestion 对象的一个集合,然后对每个问题对象进行遍历、并调用 askhtml() 方法,以便从 Servlet 类直接将 HTML 输出到 Writer 接口。

原始 Servlet 类 WebSurvey,在每个 SurveyQuestion 类实例之间,使用统一的方法生成了一种非常简单的表格。在整个过程中,生成代码的方法用于显式地打印各种 HTML 元素。清单 3 中显示了原始解决方案,以供参考。

清单 3. Java Servlet 问卷调查生成器

          
public void doGet(HttpServletRequest request,
        HttpServletResponse response)
 throws ServletException, IOException {
 PrintWriter out = response.getWriter();
 Integer formfieldid = 1;
 response.setContentType("text/html");
 out.println("<h1>Survey</h1>");
 out.println("<form action="/WebSurvey/survey" method="POST">");
  
 for(Iterator<SurveyQuestion> i = survey.iterator(); i.hasNext(); ) {
    SurveyQuestion question = (SurveyQuestion) i.next();
    question.askhtml(formfieldid,out);
    formfieldid++;
 }
  
 out.println("<input type="hidden" name="highfieldid" value=
  "" + survey.size() + "">");
 out.println("<input type="submit">");
 out.println("</form>");
}

这个方法通过直接写入到输出的方式生成了一些基本的 HTML,然后为每个 SurveyQuestion 类调用 askhtml() 方法,以便输出调查表的 HTML。

对响应进行解析

为了向客户端提交调查数据,并将这些数据插入到数据库中,您为 POST 方法类型创建了一种简单的包装方法,如清单 4 中所示。

清单 4. 对响应进行处理

          
public void doPost(HttpServletRequest request,
         HttpServletResponse response)
  throws ServletException, IOException {
  response.setContentType("text/html");
  ResultSet rs;
  Statement s;
  PreparedStatement ps;
  Integer responseid = -1;
  PrintWriter out = response.getWriter();
  out.println("<h1>Results</h1>");
  
  try {
    s = conn.createStatement();
    s.executeUpdate(
            "INSERT INTO survey_response (responseid) "
            + "values (0)",
            Statement.RETURN_GENERATED_KEYS);
    
    rs = s.getGeneratedKeys();
    
    if (rs.next()) {
      responseid = rs.getInt(1);
    } else {
      System.out.println("Can't get auto incremement data");
      out.println("Sorry, we couldn't write your responses into the DB");
    }
    
    rs.close();
    s.close ();
  } catch (Exception ex) {
    System.out.println("SQLException (getting responseid): " + ex.getMessage());
  }
  Integer fieldid = 1;
  for(Iterator<SurveyQuestion> i = this.survey.iterator(); i.hasNext(); ) {
    SurveyQuestion question = (SurveyQuestion) i.next();
    question.showquestion(out,false);
    out.println("<p>" + request.getParameter("field" + fieldid));
    try {
      ps = conn.prepareStatement (
                    "INSERT INTO survey_response_detail
                    (responseid, question,
                    responsestring) VALUES(?,?,?)");
      ps.setString (1,responseid.toString());
      ps.setString (2,fieldid.toString());
      ps.setString (3,request.getParameter("field" + fieldid));
      int count = ps.executeUpdate ();
      ps.close ();
    } catch (Exception ex) {
      System.out.println("SQLException (adding question result): "
      + ex.getMessage());
    }   
    fieldid++;
  }
}

其中的处理过程是从数据库中获得唯一的 ID,然后根据调查表中的条目,将这些行插入到响应表中。

要在 PHP 中对其进行重新部署,您必须重新考虑这个过程。

PHP 中进行重新部署

对于 PHP 应用程序,Web 应用程序由一个通过 Web 客户端进行访问的页面组成。Apache 接受 Web 请求,将页面内容的处理传递给 PHP,然后 PHP 逐字地输出 HTML 元素,并且解析 PHP 代码,以生成或者处理所需的输出。

实际上,PHP 页面的工作方式更像 JSP 页面,其中将构成页面的 HTML 和 PHP 代码混合在同一个文档中。

在使用 PHP 重新部署应用程序时,存在大量不同的解决方案和替代方法可供使用。对于当前的 Java 类,您需要进行少量的更改,以便可以在 PHP 和 Java 类之间,通过 PHP Java Bridge 正确地进行集成。

事实上,存在大量您可以使用的潜在解决方案:

要为表格生成 HTML,您可以对 Java 代码进行修改,以便仅使用一个方法调用,在 HTML 中返回整个表格的预先设定格式的版本。

或者,通过调用 HTML 生成器的经过更改的版本,您可以为每个问题输出 HTML 表格。

为了对响应信息进行解析,您需要修改 Java 类以接受单独的响应细节。这需要通过 Java 类直接进行处理,因为是 Java 类提供了到数据库的接口。

另一种可选方法(这里没有列出)是直接访问 SurveyQuestion 类,然后在 PHP 中直接输出所需的 HTML。这个特定的解决方案并不完美,因为实际上它丧失了在 PHP 中使用了 Java 类的一个优点。然而,在某些应用程序和环境中,直接访问 Java 类属性可能是合适的解决方案。

让我们首先了解基本的部署备选方法。

为 Java 问卷调查数据创建一个 PHP 接口

现在,您了解了可供使用的几种不同的解决方案,因此,接下来就要创建几种不同的解决方案,这些解决方案在前端使用 PHP,在后端使用核心 Java 类。

创建问卷调查应用程序的新实例

要使用 PHP Java Bridge 在 PHP 中创建问卷调查应用程序的新实例,您需要创建一个问卷调查应用程序的实例、或者至少创建一个或者多个 SurveyQuestion 类的实例。

Tomcat 实例和 PHP Java Bridge 必须可以访问您所加载的 Java 类。首先,您需要创建一个 JAR 文件,其中包含您希望使用的所有类文件:

$ jar cf survey.jar Survey*.class

现在,当 PHP 脚本请求根据 Java 代码创建类时,您可以将这个 JAR 文件复制到 Tomcat 服务器可以找到该文件的某个位置。PHP Java 接口可以从各种不同的位置(包括本地文件或者 URL)加载 JAR 文件和类。

使用 java_require() 函数,您可以在 PHP 脚本中指定 JAR 文件的需求。有趣的是,如果您指定了某个文件位置,那么该文件位置是提供 PHP Java Bridge 接口的远程服务器上的某个位置,而不是正在执行 PHP 脚本的计算机中的某个位置。

例如,清单 5 中的示例脚本从名为 Sulaco 的计算机中导入 PHP Java Bridge。它指定了需要 survey.jar,在这个示例中,已经将 survey.jar 复制到了名为 Sulaco 的计算机的 /usr/share/java 中。

然后,您实例化 SurveyQuestionText 的一个实例,并且调用该类中定义的、名为 ashtml() 的新方法(它将返回包含该问题的 HTML 的字符串)。

清单 5. 导入 PHP/Java bridge

          
<?
try { require_once("http://sulaco.mcslp.pri:8080/JavaBridge/java/Java.inc"); }
    catch (JavaException $e) { echo "Couldn't load java",$e; }
try { java_require("/usr/share/java/survey.jar"); }
    catch (JavaException $e) { echo "Couldn't load class",$e; }
$question = new Java("SurveyQuestionText","Name","Enter your full name");
$boolean = new Java("java.lang.Boolean",1);
print $question->htmlquestion($boolean);
?>

如果您访问这个 PHP 脚本,那么您应该获得在先前的行中所创建的 SurveyQuestionText 类实例的 HTML 格式文本问题。

通过单个方法生成调查表

正如您在前面的部分中所看到的,与 Web 服务解决方案不同(在这种方案中,您必须使用 PHP Java Bride 公开特定的类和接口),您可以自动地公开所有的 Java 类。

这将产生各种可能的情况。对于原始的类,它们用于非常特定的环境,一个命令行接口和带 HTML 接口的 Servlet,但它们都将信息直接写入到合适的接口。

在使用 PHP 类时,您需要对 Java 类进行修改以生成 HTML、并以字符串形式返回信息,或者需要直接访问 Java 类实例的各种属性。

对于前一种解决方案,通过创建返回输入字段信息的 ashtml() 方法,您可以对 Java 类进行修改。例如,清单 6 显示了 SurveyQuestionText 类的经过修改的版本。

清单 6. SurveyQuestionText 类的经过修改的版本

          
import java.io.*;
import java.util.*;
public class SurveyQuestionText extends SurveyQuestion {
  public SurveyQuestionText(String qtext,
               String qhelp) {
    this.question_text = qtext;
    this.question_help = qhelp;
    this.question_type = "text";
  }
  public void askspecific() {
    this.question_response.add(this.getresponse());
  };
  public String ashtml(Integer fieldid) {
    String qtext = this.questionhtml(true) +
      "<input type="text" size="80" name="field" + fieldid + ""><br/>";
    return(qtext);
  }
}

清单 7 显示了 SurveyQuestionRadio 方法的 ashtml() 方法。

清单 7. 将问卷调查问题信息公开为 HTML

          
public String ashtml(Integer fieldid) {
    String qtext = "";
    qtext = qtext + this.questionhtml(true);
    for(Iterator<String> i = this.question_options.iterator(); i.hasNext(); ) {
      String option = i.next();
      qtext = qtext + "<input type="radio" name="field" + fieldid + ""
      value="" +
        option + "">" + option + "<br/>";
    }
    return(qtext);
  }

请注意,在这两个示例中,您返回了该信息的字符串,并且在这两种情况下,您仍然必须提供唯一的字段 ID 以标识字段信息,因为在发送回 HTML 表格时,由字段 ID 来分隔每个字段值。

如果要在单个类中使用这个信息,那么您需要创建一个新的包装类 PHPSurvey,该类创建了一个问卷调查对象,然后返回预定义格式的 HTML 表格,可以将其插入到您的 PHP 页面中。您可以在清单 8 中看到这个类。

清单 8. 为 Survey 类构建一个前端

          
import java.io.*;
import java.util.*;
public class PHPSurvey {
  Collection<SurveyQuestion> survey = new ArrayList<SurveyQuestion>();
  public PHPSurvey () {
    survey.add(new SurveyQuestionText("Name",
                     "Enter your full name"));
    survey.add(new SurveyQuestionRadio("Favourite colour",
              "Enter your favourite colour",
              new String[] {"Red", "Blue", "Green"}));
  }
  public String generate() {
    String surveyform = "";
    Integer count = 0;
    for(Iterator<SurveyQuestion> i = this.survey.iterator();
        i.hasNext(); ) {
      count++;
      SurveyQuestion question = (SurveyQuestion) i.next();
      String text = question.ashtml(count);
      surveyform = surveyform + text;
    }
    return (surveyform);
  }
}

现在,使用清单 9 中的 PHP,您可以访问整个类以获得表格的一致表现形式(与通过后端 Java 组件所生成的形式一致)。这个示例中并没有什么附加的内容;您只需要输出一个原始表格,以说明其工作方式。

清单 9. 使用 PHP 访问我们的 Survey 类

          
<?
try { require_once("http://sulaco.mcslp.pri:8080/JavaBridge/java/Java.inc"); }
    catch (JavaException $e) { echo "Couldn't load java",$e; }
try { java_require("/usr/share/java/survey.jar"); }
    catch (JavaException $e) { echo "Couldn't load class",$e; }
$survey = new Java("PHPSurvey");
print $survey->generate();
?>

按照这种方式创建并且生成问卷调查有些令人费解,因为 PHP 接口仅完成很少的工作,并且后端 Java 组件仍然负责采用一种用户可以提交数据的形式来呈现问卷调查信息。您所希望的是使得表示层和后端组件分离开来。

通过直接使用 SurveyQuestion 方法来生成表格

因为您可以使用 PHP Java Bridge 在 PHP 组件中实例化任何 Java 类,所以您应该在 PHP 中直接创建自己的问卷调查。

可以直接使用各个 SurveyQuestion 类,并且您可以直接访问一个经过实例化的类的不同组成部分。对于最简单的应用,您可以在 PHP 中创建问卷调查,然后调用 ashtml() 生成相应的代码,如清单 10 中所示。

清单 10. 一个完整的 PHP 问卷调查

          
<html>
<head>
<title>Survey</title>
</head>
<body>
<h1>Please answer the following questions:</h1>
<form action="PHPJava4.php" method="POST">
<?
try { require_once("http://sulaco.mcslp.pri:8080/JavaBridge/java/Java.inc"); }
    catch (JavaException $e) { echo "Couldn't load java",$e; }
try { java_require("/usr/share/java/survey.jar"); }
    catch (JavaException $e) { echo "Couldn't load class",$e; }
$survey = array(
        new Java("SurveyQuestionText",
             "Name","Enter your fullname"),
        new Java("SurveyQuestionRadio",
          "Favorite color","What is your favorite color?",
          array("Red","Green","Blue"))
        );
foreach ($survey as $i => $value) {
  print $survey[$i]->ashtml($i);
}
?>
<input type="submit">
</form>

这是一个完整的页面,并且您可以在图 2 中看到输出的内容。

图 2. 基于 HTML 的调查表

在 AIX Version 5.3 中使用 Java 和 <a target=PHP 技术进行开发 (6)" onload="return imgzoom(this,550);" onclick="javascript:window.open(this.src);" style="cursor:pointer;"/>

执行过程通过为每个问题类型创建 Java 类的 PHP 实例来进行工作。正如您可以看到的,您已经创建了一个与您在 Java 本地示例中所生成的问卷调查完全相同的问卷调查。

在创建 SurveyQuestionText 类型时,需要提供给类实例创建器的参数包括问卷调查问题和帮助文本。

对于 SurveyQuestionRadio,您必须提供问题和帮助文本,然后再提供构成每个单选按钮的数组值。通过使用 PHP array() 函数创建一个标准的(非关联的)数组,您可以在 PHP 中显式地进行这项工作。

从理论上讲,您可以直接访问该类的属性(question_text、question_help),但是正如刚刚所提到的,许多使用这种方法的应用程序可能破坏使用 PHP 和 Java 接口的目的。对于这个应用程序和其他应用程序,Java 类应该是核心的内容,并且 PHP 仅仅是它的一个接口。

对于您的问卷调查应用程序,在 Java 类中生成 HTML 可能是多余的,并且它将对信息的格式化产生一定的限制。从原始 Java 类的 PHP 中访问本地 Java 属性,有时是无法实现的,但是对于简单的文本表现形式(比如您的问卷调查应用程序所需的文本表现形式),您可以创建一些在调用时返回文本属性信息的简单方法。

对于您的应用程序,最后一部分工作是通过 Java 类将响应提交到用于存储该信息的数据库中。

将问卷调查响应提交到 Java 类

如果您可以在 PHP 中直接创建 SurveyQuestion 类的实例,那么要将问题的响应提交到服务器,而不使用附加的函数来确定标识这组响应的唯一标识,这是很困难的。

您可以采用多种方式来完成这项工作,包括用于会话管理的内置 PHP 函数。然而,还有一种更简单的方式,使用您在为 Java Servlet 添加数据库支持时所开发的代码。在本示例中,您在单个步骤中执行了整个提交过程,该步骤包括从数据库中获得唯一的 ID(通过使用自动递增字段来生成 ID)、然后将数据提交到 survey_response_detail 表中。

通过使用通用的 PHPJava 类定义两种方法(其中一种方法用来生成唯一的 ID,而另一种方法用来将响应写入到 survey_response_detail 表中),您可以增强系统的灵活性。

唯一的问卷调查响应 ID 可用于填充 HTML 表格中的隐藏字段,也可以在处理表格时使用。在清单 11 中,您可以看到 PHP Java 类原始方法的经过修改的版本。

清单 11. 通过 Java 接口创建一个唯一的 ID,以便在 PHP 中使用

          
public Integer get_response_id () {
  ResultSet rs;
  Statement s;
  PreparedStatement ps;
  Integer responseid = -1;
  Connection conn = null;
  try {
    Class.forName("com.ibm.db2.jcc.DB2Driver");
    conn =
      DriverManager.getConnection("jdbc:db2://localhost:50000/SURVEY",
                    "survey","surveypw");
  } catch (Exception ex) {
    System.out.println("SQLException: " + ex.getMessage());
  }
  try {
    s = conn.createStatement();
    s.executeUpdate(
            "INSERT INTO survey_response (responseid) "
            + "values (0)",
            Statement.RETURN_GENERATED_KEYS);
    rs = s.getGeneratedKeys();
    if (rs.next()) {
      responseid = rs.getInt(1);
    } else {
      System.out.println("Can't get auto incremement data");
    }
    rs.close();
    s.close ();
  } catch (Exception ex) {
    System.out.println("SQLException (getting responseid): " +
              ex.getMessage());
  }
  return(responseid);
}

在您的 PHP 脚本中,现在可以通过创建该类的一个实例(如果该实例还没有存在的话)、然后调用 get_response_id() 来获得唯一的 ID,如清单 12 中所示。

清单 12. 在 PHP 中获得唯一的 ID

          
$survey = new Java("PHPSurvey");
$responseid = $survey->get_response_id();

现在有了唯一的 ID,剩下的处理工作是将响应写入到表中。为此,您需要使用另一个方法。

提交问卷调查响应

将问卷调查响应信息插入到 survey_response_detail 表中,该表仅包含三个字段:response ID(您在前面的部分中所获得的唯一值)、field ID(在问卷调查中为每个问题所添加的唯一的数值)和 response。

要将这些信息写入到数据库中,您可以使用通过 PHPJava 类公开的另一个方法,PHPJava 类接受三个信息片断作为其参数,然后使用预编译的语句将该信息写入到数据库中。在清单 13 中,您可以看到这种方法。

清单 13. 在 Java 中将响应保存到数据库中

          
public void save_response(Integer responseid,
             Integer fieldid,
             String response) {
  Connection conn = null;
  PreparedStatement ps;
  try {
    Class.forName("com.ibm.db2.jcc.DB2Driver");
    conn =
      DriverManager.getConnection("jdbc:db2://localhost:50000/SURVEY",
                    "survey","surveypw");
  } catch (Exception ex) {
    System.out.println("SQLException: " + ex.getMessage());
  }
  try {
    ps = conn.prepareStatement (
                  
        "INSERT INTO survey_response_detail (responseid,
                  question,
        responsestring) VALUES(?,?,?)");
    ps.setString (1,responseid.toString());
    ps.setString (2,fieldid.toString());
    ps.setString (3,response);
    int count = ps.executeUpdate ();
    ps.close ();
  } catch (Exception ex) {
    System.out.println("SQLException (adding question result): " +
              ex.getMessage());
  }
}

请注意,在上面的方法中,您每次提交响应时都建立了一个连接,这将为该进程增加相当的负载。这与 Web 服务解决方案是不同的,在 Web 服务解决方案中,需要在每次提交响应时建立一个连接(因为 Web 服务不是持久的)。对于 PHP Java Bridge,您可以将初始连接和预编译语句的构造放入该类的实例方法中。这将极大地改善处理过程的效率。在清单 14 中显示了这种情况的一个示例。

清单 14. 使用持久的数据库连接,以获得更好的性能

          
public class PHPSurvey {
  Collection<SurveyQuestion> survey = new ArrayList<SurveyQuestion>();
  Connection conn = null;
  PreparedStatement ps;
  public PHPSurvey () {
    survey.add(new SurveyQuestionText("Name","Enter your full name"));
    survey.add(new SurveyQuestionRadio("Favourite colour",
                      "Enter your favourite colour",
                      new String[] {"Red", "Blue", "Green"}));
    try {
      Class.forName("com.ibm.db2.jcc.DB2Driver");
      conn =
        DriverManager.getConnection("jdbc:db2://localhost:50000/SURVEY",
                      "survey","surveypw");
      ps = conn.prepareStatement (
                    "INSERT INTO survey_response_detail " +
                    "(responseid, question, responsestring)
                      VALUES(?,?,?)");
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
    } catch (Exception ex) {
      System.out.println("SQLException: " + ex.getMessage());
    }
  }
...
public void save_response(Integer responseid,
             Integer fieldid,
             String response) {
  try {
    this.ps.setString (1,responseid.toString());
    this.ps.setString (2,fieldid.toString());
    this.ps.setString (3,response);
    int count = ps.executeUpdate ();
  } catch (Exception ex) {
    System.out.println("SQLException (adding question result): " + ex.getMessage());
  }
}

PHP 端来看,您需要确定提交表格的时间,然后提交每个响应。每个字段的名称为 'field#',其中 # 是表格中的唯一字段编号,它是处理表格中每个问题的 HTML 时所生成的。在确定已经提交了表格之后,您只需要获得唯一的响应 ID,然后遍历响应表格中的各个字段,并且在您的远程问卷调查接口中调用 save_response()。清单 15 显示了这个情况的实际应用,其中使用全局 PHPJava 类和 generate() 方法来创建表格。

清单 15. Java PHPSurvey 类的最终 PHP 接口

          
<html>
<head>
<title>Survey</title>
</head>
<body>
<?
try { require_once("http://sulaco.mcslp.pri:8080/JavaBridge/java/Java.inc"); }
    catch (JavaException $e) { echo "Couldn't load java",$e; }
try { java_require("/usr/share/java/survey.jar"); }
    catch (JavaException $e) { echo "Couldn't load class",$e; }
$surveyint = new Java("PHPSurvey");
if (isset($_REQUEST['field0'])) {
  print "<h2>Submitting responses</h2>";
  $responseid = $survyeint->get_response_id();
  for ($i = 0;$i <= sizeof($survey);$i++) {
    if (isset($_REQUEST['field' . $i])) {
      print "Submitting response for field $i<br/>";
      $surveyint->save_response($responseid,$i,$_REQUEST['field' . $i]);
    }
  }
}
else {
  print "<h1>Please answer the following questions:</h1>";
  print '<form action="PHPJava5.php" method="POST">';
  print $surveyint->generate();
  print '<br/><input type="submit"/></form>';
}
?>
</body>
</html>

正如您可以从这个示例中看到的,PHP 部分负责显示和处理用户界面信息,后端 Java 类仍然负责所有的具体工作。我们的想法是:在继续使用原始 Java 类完成后端工作的同时,使用 PHP 来完成用户界面部分。

总结

正如您在本教程中所看到的,只需要进行很少的调整,您就可以更改您的原始 Java 类,以使得它们可以通过 PHP Java Bridge 进行访问。这些更改不会影响您的原始类;事实上,您在 PHP 中直接创建了原始类的实例。该方法非常简单,这正是 PHP Java Bridge 解决方案的强大之处。

通过一些附加的更改(主要是更改您在本系列文章的前面部分中所开发的代码),您可以为原始 Java 类创建基本的、基于 PHP 的接口。其结果是提供了完善的接口,以便从 PHP 中直接访问 Java 应用程序,并且得到了比 Web Services 更加灵活的解决方案。使用 Web Services,您必须开发提供相同功能的接口。

通过本系列文章的学习,您已经完成了原始 Java 类,并且对核心部分(SurveyQuestion 和相关的 SurveyQuestion* 类)进行了很少的更改。通过这个过程,您已经添加了一个到数据库的接口,并且开发了一个 Web 服务解决方案,以允许对原始类进行灵活的访问。所得到的结果是原始类的基于 PHP 的接口。您可以将这里介绍的基本原则应用于其他的应用程序,以便通过 PHP 将现有的 Java 类公开为 Web 接口。

Tags:AIX Version 使用

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接