vlambda博客
学习文章列表

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

Chapter 4. Using Ajax

异步 JavaScript 和 XMLAJAX Ajax) 是 一种在浏览器和服务器之间异步传输数据的技术。 “异步”意味着在请求从浏览器发送到服务器并收到响应的同时继续处理网页。 Ajax 基于 JavaScript,文档对象模型 (DOM) , 和 XMLHttpRequest。 Ajax 提供浏览器和服务器之间的动态交互,可用于多种类型的应用程序,例如验证需要唯一标识符而不提交的表单表单,根据部分输入自动完成输入字段,并定期刷新网页上的信息,而无需重新加载网页,从而减少带宽使用。

在本章中,我们将在 Eclipse IDE 中创建一个 Ajax 应用程序,使用 Maven 编译和打包应用程序,并在带有 MySQL 数据库的 WildFly 8.1 上运行 Web 应用程序。在本章中,我们将介绍以下主题:

  • 设置环境

  • 创建 Java EE Web 项目

  • 创建用户界面

  • 创建一个 servlet

  • 使用 Maven 部署 Ajax 应用程序

  • 运行 Ajax 应用程序

Setting up the environment


我们需要安装以下软件:

设置JAVA_HOMEJBOSS_HOMEMAVEN_HOMEMYSQL_HOME 环境变量。添加 %JAVA_HOME%/bin, %MAVEN_HOME%/bin, %JBOSS_HOME%/bin %MYSQL_HOME%/binPATH 环境变量。

创建 WildFly 8.1.0 运行时,如 第 1 章EJB 3.x 入门

Create a MySQL database CATALOG with the following SQL script:CREATE TABLE Catalog(CatalogId VARCHAR(255), Journal VARCHAR(255), Publisher Varchar(255), Edition VARCHAR(255), Title Varchar(255), Author Varchar(255));

INSERT INTO Catalog VALUES('catalog1', 'Oracle Magazine',  'Oracle Publishing', 'September-October 2010', 'Using Oracle Essbase Release 11.1.2 Aggregate Storage Option Databases', 'Mark Rittman and VenkatakrishnanJanakiraman');

INSERT INTO Catalog VALUES('catalog2', 'Oracle Magazine',   'Oracle Publishing', 'July-August 2010', 'Infrastructure Software and Virtualization', 'David Baum');

我们将使用与前面章节相同的 MySQL 数据源。 第 1 章EJB 3.x 入门

Creating a Java EE web project


在本节中,我们将在 Eclipse 中创建一个 Java EE Web 项目。选择文件 | | 其他。在 New 中,选择 JBoss Central | Java EE Web Project并点击Next,如图以下屏幕截图:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

Java EE Web 项目向导开始。针对要求运行测试,其中包括 m2em2eclipse-wtp JBoss Maven 工具 插件。选择 Create a blank project 复选框和 Target Runtime 为 < code class="literal">WildFly 8.x Runtime,如下图所示。然后点击下一步

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

指定 项目名称 (jboss- ajax),Package (org.jboss.ajax),然后点击下一步,如下截图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

指定 组 ID (org. jboss.ajax), 工件 ID (jboss-ajax), 版本1.0.0)和包< /strong> (org.jboss.ajax),如以下屏幕截图所示。之后,点击 Finish

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

jboss-ajax Java EE web 项目被创建,如下面的 Project Explorer 所示截屏。删除 //jboss-ajax/src/main/resources/META-INF/persistence.xml 配置文件,因为它没有在 Ajax 应用程序中使用:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

Creating a user interface


Ajax 请求 在浏览器中从网页发起。在本节中,我们将为 Ajax 应用程序创建用户界面。要发起 Ajax 请求,需要 JavaScript,我们将为此创建一个 JSP 页面。我们使用了 JSP,但也可以使用另一种用户界面技术,例如 JSF。选择文件 | | Other,并在 New 中选择 网络 | JSP 文件 并点击下一步

New JSP File 向导中,选择 webapp 文件夹,指定 文件名 (ajaxJBoss.jsp),然后点击下一步,< /strong> 如以下屏幕截图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

Select JSP Template中,选择新建 JSP 文件 (html) 模板,然后点击 FinishajaxJBoss.jsp 文件被添加到 webapp 文件夹中。在 ajaxJBoss.jsp 中,添加 HTML 表单以创建目录条目。输入表单由目录 ID、期刊、出版商、版本、标题和作者的输入字段组成。 目录 ID 字段需要唯一的字段值。在没有 Ajax 的表单中,我们将指定目录 ID 值和其他字段值,然后使用 Submit 按钮提交表单。如果目录 ID 是唯一的,则会创建一个新的目录条目,但如果目录 ID 已存在于数据库中,则会显示一条错误消息,并且需要重新填写并重新提交表单。使用 Ajax,可以在指定值时验证目录 ID 值,从而避免重新提交表单的需要。在 Ajax 应用程序中,输入目录 ID 值被发送到服务器,因为该值是使用 Ajax 请求指定的,并且 HTTP servlet 立即返回 XML 消息关于输入数据的有效性。

要发送 XMLHttpRequest 并接收响应,我们将使用以下过程:

  1. 从 HTML 事件调用 JavaScript 函数,例如 onkeyup

  2. 在 JavaScript 函数中创建一个 XMLHttpRequest 对象。

  3. 打开一个 XMLHttpRequest 请求。

  4. 使用 XMLHttpRequest 对象注册一个回调事件处理程序,该处理程序在请求完成时被调用。

  5. 向服务器异步发送 XMLHttpRequest 请求。

  6. 在服务器上处理请求;对于服务器来说,异步请求就像任何其他 HTTP 请求一样。

  7. 将 XML 消息响应发送回浏览器。

  8. 接收 XML 响应并在网页上显示一条消息,而无需重新加载网页。

ajaxJBoss.jsp 中,添加一个带有目录条目输入字段的 HTML 表单。将表单的操作设置为 AjaxFormServlet,它被映射为调用 servlet,稍后将讨论。在 <form/> 中添加 <table/> 并添加一个 <目录 ID 的 ;input/> 字段。添加 Submit 按钮以使用 HTTP POST 方法将表单提交到服务器。在 <input/> 字段中,将 onkeyup 事件处理程序设置为 validateCatalogId () JavaScript 函数,我们将其添加到 ajaxJBoss.jsp。在目录 ID 输入字段的表格行中包含 <div/><div/> 将用于显示有关目录 ID 有效性的消息。这是封装本段讨论的代码:

<table>
  <tr>
    <td>Catalog Id:</td><td><input type="text" size="20" id="catalogId" name="catalogId" onkeyup="validateCatalogId()">
    </td>
    <td>
<div id="validationMessage"></div>
    </td>
  </tr></table>

同样,为目录添加其他输入字段。每次生成 onkeyup 事件时,都会调用 validateCatalogId 函数。

接下来,创建 一个 validateCatalogId JavaScript 函数。在 validateCatalogId() JavaScript 函数中,创建一个新的 XMLHttpRequest 对象。如果浏览器支持 XMLHttpRequest 对象作为 ActiveX 对象(如在 IE 6 中),则创建 XMLHttpRequest 对象的过程是如果 XMLHttpRequest 对象是本机对象,则与过程不同; window 对象属性(如在 IE 7 及更高版本以及其他浏览器中)。在 validateCatalogId 函数中创建一个 init() 函数并创建一个 XMLHttpRequest两种浏览器的对象(支持/不支持 XMLHttpRequest 作为本机对象的浏览器)。以下是本段讨论的代码:

function validateCatalogId(){
  var xmlHttpRequest=init();
  function init(){
    if (window.XMLHttpRequest) {
      return new XMLHttpRequest();
    } else if (window.ActiveXObject) {
      return new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
}

接下来,使用 open() 方法打开 XMLHttpRequesturl [, async = true [ , 用户 = null [, 密码 = null]]])。将 HTTP 方法设置为 GET 以便浏览器接收来自服务器的响应。 XMLHttpRequest 将被发送到的服务器 URL 包含一个 servlet 映射以调用一个 servlet 来处理请求和 CatalogId请求参数。在示例应用程序中,我们将调用 AjaxFormServlet,它映射到 web 中的 /AjaxFormServlet .xml 。使用 encodeURIComponent(string) 方法对请求参数 CatalogId 进行编码,该方法对 CatalogId< /code> 值为 UTF-8 (https ://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURIComponent)。默认情况下,用户和密码设置为空字符串。以下代码显示了在示例应用程序上执行的此操作:

varcatalogId=document.getElementById("catalogId");
xmlHttpRequest.open("GET", "AjaxFormServlet?catalogId="+ encodeURIComponent(catalogId.value), true);

我们需要知道请求何时完成,以便我们可以处理响应。使用 onreadystatechangeXMLHttpRequest 对象注册回调事件处理程序 processRequest > 财产。我们稍后将添加的 JavaScript 回调函数 processRequest 会在 readyState 属性的值发生变化时被调用,如下所示以下代码行:

xmlHttpRequest.onreadystatechange=processRequest;

使用 send() 方法发送 Ajax 请求(因为 HTTP 方法是 GETsend方法发送的数据设置为null),如下图代码行:

xmlHttpRequest.send(null);

对于异步请求,send() 方法会立即返回。每次 readyState 属性的值发生变化时,都会调用 processRequest 函数。在 processRequest 函数中,检索 readyState 属性值。当请求完全加载后,对应 readyState 属性值 4 和 HTTP 状态 OK ,调用 processResponse JavaScript 函数来处理来自服务器的响应:

function processRequest(){
  if(xmlHttpRequest.readyState==4){
    if(xmlHttpRequest.status==200){
      processResponse();
    }
  }
}

XMLHttpRequest 请求调用 AjaxFormServlet。 servlet 处理请求并以以下格式的 XML 消息的形式返回响应:

<catalog>
  <valid></valid>
  <journal></journal>
  <publisher></publisher>
  <edition></edition>
  <title></title>
  <author></author>
</catalog>

我们将在 创建 Servlet 部分讨论请求的服务器端处理。处理来自服务器的 XMLHttpRequest 请求的响应,如果指令表明 CatalogId 输入有效,则消息 目录 ID 有效 显示。 XMLHttpRequest 将被发送到服务器,并且在 catalogId 输入字段中的每次修改都会收到响应。

接下来,添加 JavaScript 函数来处理响应 processResponse()。在 processRequest() JavaScript 函数中,当 HTTP 请求完全加载后,对应 readyState 属性值 4 和 HTTP 状态 OK,依次对应状态属性值 200processResponse() JavaScript 函数被调用。在processResponse()函数中,获取responseXML 属性的值,该属性包含从服务器返回的XML字符串。这显示在以下代码行中:

Var xmlMessage=xmlHttpRequest.responseXML;

responseXML 属性 包含 <valid/> 元素,指示输入表单中指定的 CatalogId 值的有效性。使用 getElementsByTagName(string) 方法获取 <valid/> 元素的值。这显示在以下代码行中:

var
valid=xmlMessage.getElementsByTagName("valid")[0].firstChild.nodeValue;

如果 <valid/> 元素值为 true,则设置 validationMessage div 标签到 Catalog Id is Valid,并在输入表单中启用提交按钮。此外,将表单字段的值设置为空字符串,以便可以指定新的输入值:

if(valid=="true"){
  varvalidationMessage=document.getElementById("validationMessage");
  validationMessage.innerHTML = "Catalog Id is Valid";
  document.getElementById("submitForm").disabled = false;
……
}

如果商品 ID 值有效,则可以通过为商品的不同值添加值来创建新商品。使用 Submit 按钮提交表单。如果 <valid/> 元素值为 false,则设置 validationMessage CatalogID 字段行中的 code> div 标签到 Catalog Id is not Valid,并禁用 提交按钮。将其他输入字段的值设置为服务器 XML 消息中返回的值。例如journal字段值设置如下,设置其他字段值作为Ajax自动补全的例子:

if(valid=="false"){

  var validationMessage=document.getElementById("validationMessage");
  validationMessage.innerHTML = "Catalog Id is not Valid";
  document.getElementById("submitForm").disabled = true;

  var journal=xmlMessage.getElementsByTagName("journal")[0].firstChild.nodeValue;
…
  var journalElement=document.getElementById("journal");
  journalElement.value = journal;

}

ajaxJBoss.jsp 文件列出如下:

<html>
  <head>
    <script type="text/javascript"> function validateCatalogId(){ var xmlHttpRequest=init(); function init(){ if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else if (window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP"); } } var catalogId=document.getElementById("catalogId"); xmlHttpRequest.open("GET", "AjaxFormServlet?catalogId="+ encodeURIComponent(catalogId.value), true); xmlHttpRequest.onreadystatechange=processRequest; xmlHttpRequest.send(null); function processRequest(){ if(xmlHttpRequest.readyState==4){ if(xmlHttpRequest.status==200){ processResponse(); } } } function processResponse(){ var xmlMessage=xmlHttpRequest.responseXML; var valid=xmlMessage.getElementsByTagName("valid")[0].firstChild.nodeValue; if(valid=="true"){ var validationMessage=document.getElementById("validationMessage"); validationMessage.innerHTML = "Catalog Id is Valid"; document.getElementById("submitForm").disabled = false; var journalElement=document.getElementById("journal"); journalElement.value = ""; var publisherElement=document.getElementById("publisher"); publisherElement.value = ""; var editionElement=document.getElementById("edition"); editionElement.value = ""; var titleElement=document.getElementById("title"); titleElement.value = ""; var authorElement=document.getElementById("author"); authorElement.value = ""; } if(valid=="false"){ var validationMessage=document.getElementById("validationMessage"); validationMessage.innerHTML = "Catalog Id is not Valid"; document.getElementById("submitForm").disabled = true; var journal=xmlMessage.getElementsByTagName("journal")[0].firstChild.nodeValue; var publisher=xmlMessage.getElementsByTagName("publisher")[0].firstChild.nodeValue; var edition=xmlMessage.getElementsByTagName("edition")[0].firstChild.nodeValue; var title=xmlMessage.getElementsByTagName("title")[0].firstChild.nodeValue; var author=xmlMessage.getElementsByTagName("author")[0].firstChild.nodeValue; var journalElement=document.getElementById("journal"); journalElement.value = journal; var publisherElement=document.getElementById("publisher"); publisherElement.value = publisher; var editionElement=document.getElementById("edition"); editionElement.value = edition; var titleElement=document.getElementById("title"); titleElement.value = title; var authorElement=document.getElementById("author"); authorElement.value = author; } } } </script>
  </head>
  <body>
    <h1>Form for Catalog Entry</h1>
    <form name="AjaxFormServlet" action="AjaxFormServlet" method="post">
      <table>
        <tr>
          <td>Catalog Id:</td>
          <td><input type="text" size="20" id="catalogId" name="catalogId" onkeyup="validateCatalogId()"></td>
          <td>
            <div id="validationMessage"></div>
          </td>
        </tr>
        <tr>
          <td>Journal:</td>
          <td><input type="text" size="20" id="journal" name="journal"></td>
        </tr>
        <tr>
          <td>Publisher:</td>
          <td><input type="text" size="20" id="publisher" name="publisher"></td>
        </tr>
        <tr>
          <td>Edition:</td>
          <td><input type="text" size="20" id="edition" name="edition"></td>
        </tr>
        <tr>
          <td>Title:</td>
          <td><input type="text" size="20" id="title" name="title"></td>
        </tr>
        <tr>
          <td>Author:</td>
          <td><input type="text" size="20" id="author" name="author"></td>
        </tr>
        <tr>
          <td><input type="submit" value="Create Catalog" id="submitForm" name="submitForm"></td>
        </tr>
      </table>
    </form>
  </body>
</html>

添加一个 catalog.jsp JSP 以输出一条消息,表明已创建目录条目且没有错误,如如下:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Catalog entry created without error</title>
  </head>
  <body>
    Catalog entry created without error
  </body>
</html>

添加另一个 error.jsp JSP 以指示错误消息,如下所示:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Error page</title>
  </head>
  <body>
    Error Page
  </body>
</html>

Creating a servlet


在本节中,我们将创建一个servlet 来处理Ajax 请求。选择文件 | |其他,在新建,选择Web | Servlet,如下图所示。然后,点击下一步

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

Create Servlet 向导 启动。选择 Project 作为 jboss-ajax, Source文件夹src\main\javaJava包org.jboss.ajax.controller, 类名 as AjaxFormServlet,以及超类javax.servlet.http.HttpServlet,如图在下面的屏幕截图中。然后点击下一步

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

指定 URL mappings 为 AjaxFormServlet 并点击 Next< /strong>,如下图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

选择 doGetdoPost 方法来创建servlet,如以下屏幕截图所示。完成后,点击 Finish

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

AjaxFormServlet 创建 并在 web.xml< 中配置 servlet /code>,包括到 /AjaxFormServlet 的 URL 映射。我们在 URL 中包含 /AjaxFormServlet 以发送 XMLHttpRequest 请求以调用 AjaxFormServletweb.xml 文件列举如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="..." version="3.1">
  <display-name>jboss-ajax</display-name>
  <servlet>
    <description></description>
    <display-name>AjaxFormServlet</display-name>
    <servlet-name>AjaxFormServlet</servlet-name>
    <servlet-class>org.jboss.ajax.controller.AjaxFormServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>AjaxFormServlet</servlet-name>
    <url-pattern>/AjaxFormServlet</url-pattern>
  </servlet-mapping>
</web-app>

由于 HTTP 方法GET,所以 < servlet 的 code class="literal">doGet() 方法被调用。在 doGet 方法中,获取 catalogId 参数的值,如以下代码行所示:

String catalogId = request.getParameter("catalogId");

catalogId 值应用业务逻辑以验证该值。我们使用了值必须唯一才能有效的业务逻辑,这意味着相同的值必须不在数据库中。在 java:jboss/ 上使用带有 InitialContext 对象的 JNDI 查找创建一个 DataSource 对象datasources/MySQLDS 数据源。

使用 getConnection() 方法从 DataSource 对象创建一个 Connection 对象.使用输入表单中指定的 CatalogId 值,创建 SQL 查询以从数据库中检索数据。使用 prepareStatement(String)Connection 对象创建一个 PreparedStatement 对象方法。使用 executeQuery() 方法运行 SQL 查询以获得 ResultSet 对象。如果 ResultSet 对象为空,则表示 CatalogId 字段值未在 目录 数据库表; CatalogId 字段值有效。如果 ResultSet 对象包含数据,则暗示 CatalogId 值已经存在于数据库中; CatalogId 字段值无效。

接下来,构造一个 XML 字符串以返回到服务器。如果 CatalogId 无效,请构造一个 XML 字符串,该字符串包括作为 XML 元素的商品的不同字段值。 XML 字符串需要有一个根元素,例如 catalog。包含 <valid> </valid> 元素用 boolean 值指定 CatalogId 字段值的有效性。如果 CatalogId 值有效,则仅添加 <valid> </有效> 元素到XML字符串,如下代码片段所示(变量rs代表ResultSet):

if (rs.next()) {
  out.println("<catalog>" + "<valid>false</valid>" + "<journal>" +
  rs.getString(2) + "</journal>" + "<publisher>" +
  rs.getString(3) + "</publisher>" + "<edition>" +
  rs.getString(4) + "</edition>" + "<title>" +
  rs.getString(5) + "</title>" + "<author>" +
  rs.getString(6) + "</author>" + "</catalog>");
} else {
  out.println("<valid>true</valid>");
}

HttpServletResponse 的 content 类型设置为 text/xml 因为 Ajax 请求的响应是 XML 格式的,所以将 Cache-Control 标头设置为 no-cache 为防止 JSP 和 servlet 被缓存。由于每次请求都会更新 Ajax 响应,因此必须禁用缓存以防止保留缓存的响应,如下所示:

response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");

如果数据库中不存在 CatalogId 字段值,则可以使用 POST< 提交具有新目录条目字段值的输入表单/代码>方法。在 servlet 的 doPost 方法中,像在 doGet 方法中一样创建到 MySQL 数据库的 JDBC 连接,并添加一个目录带有 INSERT SQL 语句的条目。

FormServlet.java Ajax 列举如下:

package org.jboss.ajax.controller;

import java.io.*;
import java.sql.*;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

public class AjaxFormServlet extends HttpServlet {

doGet 方法是通过使用 HTTP GET 方法发送的异步请求调用的。使用在输入表单中指定的目录 ID 运行 SQL 查询以生成结果集。为 HttpServletResponse 对象设置标题,并从 HttpServletResponsePrintWriter 对象> 对象。将输出构造为 XML 响应,如以下代码所示:

public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    try {
      // Obtain value of Catalog Id field to be validated.
      String catalogId = request.getParameter("catalogId");
      
      // Obtain Connection
      InitialContext initialContext = new InitialContext();
      DataSource ds = (DataSource)initialContext.lookup("java:jboss/datasources/MySQLDS");
      java.sql.Connection conn = ds.getConnection();
      
      // Obtain result set
      PreparedStatement pstmt = conn.prepareStatement("SELECT * from CATALOG WHERE CatalogId = ?");
      pstmt.setString(1, catalogId);
      
      ResultSet rs = pstmt.executeQuery();
      
      // set headers before accessing the Writer
      response.setContentType("text/xml");
      response.setHeader("Cache-Control", "no-cache");
      
      PrintWriter out = response.getWriter();
      
      // then send the response
      // If result set is empty set valid element to true
      if (rs.next()) {
        out.println("<catalog>" + "<valid>false</valid>" + "<journal>"
        + rs.getString(2) + "</journal>" + "<publisher>"
        + rs.getString(3) + "</publisher>" + "<edition>"
        + rs.getString(4) + "</edition>" + "<title>"
        + rs.getString(5) + "</title>" + "<author>"
        + rs.getString(6) + "</author>" + "</catalog>");
      } else {
        out.println("<valid>true</valid>");
      }
      
      rs.close();
      stmt.close();
      conn.close();
      
    } catch (javax.naming.NamingException e) {System.err.println(e.getMessage());
    } catch (SQLException e) {System.err.println(e.getMessage());
    }
  }

doPost() 方法用于创建新的目录条目。创建一个 InitialContext 对象。使用 JNDI 查找,创建一个 DataSource 对象。使用 getConnection() 方法从 DataSource 对象中获取一个 Connection 对象.使用 Connection 类的 createStatement() 方法创建一个 Statement 对象. PreparedStatement 可以用来代替 Statement。根据从输入表单中检索到的值创建 SQL 字符串。使用 execute() 方法运行 SQL 语句。如果 SQL 语句运行没有错误,则将响应重定向到 catalogentrycreated.jsp。如果产生错误,将响应重定向到error.jsp,如下代码所示:

public void doPost(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    try {
      // Obtain Connection
      InitialContext initialContext = new InitialContext();
      DataSource ds = (DataSource) initialContext.lookup("java:jboss/datasources/MySQLDS");
      java.sql.Connection conn = ds.getConnection();
      
      String catalogId = request.getParameter("catalogId");
      String journal = request.getParameter("journal");
      String publisher = request.getParameter("publisher");
      String edition = request.getParameter("edition");
      String title = request.getParameter("title");
      String author = request.getParameter("author");
      
      Statement stmt = conn.createStatement();
      String sql = "INSERT INTO Catalog VALUES(" + "\'" + catalogId
      + "\'" + "," + "\'" + journal + "\'" + "," + "\'"
      + publisher + "\'" + "," + "\'" + edition + "\'" + ","
      + "\'" + title + "\'" + "," + "\'" + author + "\'" + ")";
      
      stmt.execute(sql);
      
      response.sendRedirect("catalogentrycreated.jsp");
      
      stmt.close();
      conn.close();
      
    } catch (javax.naming.NamingException e) {
      response.sendRedirect("error.jsp");
    } catch (SQLException e) {
      response.sendRedirect("error.jsp");
    }
  }
}

AjaxFormServlet 类显示在以下屏幕截图中的 Package Explorer 中。一旦通过 Maven 满足依赖关系,清单 中显示的错误将在下一部分中删除。

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

Deploying the Ajax application with Maven


在本节中,我们将编译、打包并将Ajax应用程序部署到WildFly 8.1 使用 Maven 构建工具。有关项目的信息和配置详细信息在 Ajax 应用程序根目录的 pom.xml 中指定。

由于我们使用的是 MySQL 数据库,所以在 MySQL JDBC Java 连接器上添加一个依赖,如下:

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.22</version>
</dependency>

添加 Servlet 3.1 API 的依赖项,如下所示:

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
</dependency>

build 元素中添加 Maven 编译器插件和 Maven WAR 插件。在Maven WAR插件的配置中,指定输出目录为WildFly 8.1的deployments目录。 pom.xml 文件列举如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.jboss.ajax</groupId>
  <artifactId>jboss-ajax</artifactId>
  <version>1.0.0</version>
  <packaging>war</packaging>
  <name>WildFly Ajax</name>
  <description>A starter Java EE 7 webapp project for use on JBoss WildFly / WildFly, generated from the jboss-javaee6-webapp archetype</description>
  <url>http://wildfly.org</url>
  <licenses>
    <license>
      <name>Apache License, Version 2.0</name>
      <distribution>repo</distribution>
      <url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
    </license>
  </licenses>
  <properties>
    <!-- Explicitly declaring the source encoding eliminates the following message: -->
    <!-- [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- JBoss dependency versions -->
    <version.wildfly.maven.plugin>1.0.2.Final</version.wildfly.maven.plugin>
    <!-- Define the version of the JBoss BOMs we want to import to specify tested stacks. -->
    <version.jboss.bom>8.1.0.Final</version.jboss.bom>
    <version.arquillian.container>8.0.0.Final</version.arquillian.container>
    <!-- other plugin versions -->
    <version.compiler.plugin>3.1</version.compiler.plugin>
    <version.surefire.plugin>2.16</version.surefire.plugin>
    <version.war.plugin>2.1.1</version.war.plugin>
    <!-- maven-compiler-plugin -->
    <maven.compiler.target>1.7</maven.compiler.target>
    <maven.compiler.source>1.7</maven.compiler.source>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.wildfly.bom</groupId>
        <artifactId>jboss-javaee-7.0-with-tools</artifactId>
        <version>${version.jboss.bom}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>org.wildfly.bom</groupId>
        <artifactId>jboss-javaee-7.0-with-hibernate</artifactId>
        <version>${version.jboss.bom}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <!-- First declare the APIs we depend on and need for compilation. All of them are provided by JBoss WildFly -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.22</version>
    </dependency>
  </dependencies>
  <build>
    <!-- Maven will append the version to the finalName (which is the name given to the generated war, and hence the context root) -->
    <finalName>${project.artifactId}</finalName>
    <plugins>
      <!-- Compiler plugin enforces Java 1.6 compatibility and activates annotation processors -->
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${version.compiler.plugin}</version>
        <configuration>
          <source>${maven.compiler.source}</source>
          <target>${maven.compiler.target}</target>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>${version.war.plugin}</version>
        <configuration>
          <outputDirectory>C:\wildfly-8.1.0.Final\standalone\deployments</outputDirectory>
          <!-- Java EE 7 doesn't require web.xml, Maven needs to catch up! -->
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
      <!-- The WildFly plugin deploys your war to a local WildFly container -->
      <!-- To use, run: mvn package wildfly:deploy -->
      <plugin>
        <groupId>org.wildfly.plugins</groupId>
        <artifactId>wildfly-maven-plugin</artifactId>
        <version>${version.wildfly.maven.plugin}</version>
      </plugin>
    </plugins>
  </build>
</project>

依赖项 被添加到 pom 之后.xml,JSP 和 servlet 中的错误将被删除,如以下屏幕截图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

pom.xml 上右键单击 选择运行方式 | Maven 安装,如下图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

jboss-ajax 应用程序 被编译和打包jboss-ajax.war 中,它将输出到 deployments 目录。 Maven 构建输出消息 BUILD SUCCESS,如以下屏幕截图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

如果 WildFly 8.1 尚未启动,请启动它。 jboss-ajax.war 得到 部署到 WildFly 8.1 和 web 上下文根 |jboss-ajax 被注册。 jboss-ajax.war 被部署并列在 WildFly 8.1 中。 管理控制台,如下图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

Running the Ajax application


在本节中,我们将运行 Ajax 应用程序。使用 URL http://localhost:8080/jboss-ajax/ajaxJBoss.jsp 运行 ajaxBoss.jsp。将显示目录条目的输入表单,如以下屏幕截图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

开始指定 Catalog Id 值。由于 一个 Ajax 请求被发送到服务器,每次修改 Catalog Id< /span> 值,从服务器返回响应并显示有关 Catalog Id 有效性的消息,如以下屏幕截图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

用于 Catalog Id 的业务逻辑 是有效的值应该是唯一的,但可以使用另一种逻辑。 Catalog Id(目录)仍然有效,如下图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

指定一个已经在 MySQL 数据库中的 Catalog Id,<例如 code class="literal">catalog1。将显示一条消息 Catalog Id is not Valid,并且输入字段将填充目录条目的字段值,如下所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

catalog2 指定为 Catalog Id,其中 也是无效的,如下面的截图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

catalog3 指定为 目录 ID。由于 catalog3 值尚未在数据库中,Catalog Id 有效,如下图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

新目录条目添加字段值并单击提交,如如以下屏幕截图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

一个新的目录条目 被创建,如以下屏幕截图所示的消息所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

如果 catalog3 被重新添加到 Catalog Id 字段,显示Catalog Id is not Valid消息,如下图所示:

读书笔记《advanced-java-ee-development-with-wildfly》使用AJAX

Summary


在本章中,我们学习了如何在 Eclipse 中开发 Ajax 应用程序。我们使用 Maven 构建工具对应用程序进行编译和打包,并将应用程序部署到 WildFly 8.1。我们在带有 MySQL 数据库的浏览器中运行 Ajax 应用程序。我们只讨论了 XMLHttpRequest 对象的一些方法和属性。有关 XMLHttpRequest 的完整信息,请参阅 http://www.w3.org/TR/XMLHttpRequest/https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest?redirectlocale=en-US&redirectslug=XMLHttpRequest

在下一章中,我们将讨论 GWT Web 框架,它在 UI 组件中作为内置特性提供 Ajax 支持。