32、基于 Web 的应用程序部署指南

基于 Web 的应用程序部署指南

1. 引言

在网络应用开发中,构建一个功能完善且易于维护的 Web 应用是众多开发者的目标。本文将围绕一个推荐代理的 Web 应用展开,介绍如何使用 Java Servlet API、Tomcat 引擎以及 Jess 规则引擎来开发和部署这样的应用。

2. Java Servlet API

Servlet 类似于设备驱动程序,是一段实现服务并提供少量入口点的代码,通过这些入口点,主机系统可以访问该服务。Servlet 通常用 Java 编写,最常见的类型由 Web 服务器托管,并通过 HTTP 或 HTTPS 协议进行访问。

以下是一个简单而完整的 Servlet 示例:

import java.io.*;
import javax.servlet.http.*;
public class Hello extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
    throws IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println(" <head>");
        out.println("    <title>Hello World!</title>");
        out.println(" </head>");
        out.println(" <body>");
        out.println("    <h1>Hello World!</h1>");
        out.println(" </body>");
        out.println("</html>");
    }
}

这个 Servlet 只是在 HTML 页面上显示 “Hello World!”,但实际上页面可以更加复杂,还可以包含动态计算的数据。Servlet 不仅可以显示页面,还可以接收用户的查询数据并做出响应,加载配置数据,并且可以被其他 Servlet 调用或调用其他 Servlet。

HttpServletRequest 对象为 Servlet 提供输入,例如来自 HTML 表单的查询数据; HttpServletResponse 对象表示正在生成的页面。在上述示例中,使用了 setContentType 方法指定返回数据的 MIME 类型,使用 getWriter 方法获取一个 PrintWriter 对象,用于发送构成 HTML 页面的文本。

3. J2EE 和 Tomcat 引擎

要使 Servlet 在 Web 上可访问,需要将其编译并部署到 Servlet 容器中。Servlet 容器就像操作系统对于设备驱动程序一样,为 Servlet 提供必要的服务,如网络通信、查询数据和配置信息的检索以及与其他 Servlet 的通信机制。

Tomcat 是 Apache 项目的一个 Servlet 引擎,是 Java Servlet 和 JavaServer Pages 规范的参考实现,也是 JavaSoft 的 Java 2 Enterprise Edition (J2EE) 实现的一部分。可以在 Apache 软件许可证的条款下免费下载和使用 Tomcat。

3.1 部署 Hello Servlet

部署 Hello Servlet 需要以下五个步骤:
1. 编译 Servlet
要编译 Servlet,需要将 $(TOMCAT)/common/lib/servlet.jar 文件包含在类路径中。使用以下命令行进行编译:
sh javac -classpath $(TOMCAT)/common/lib/servlet.jar Hello.java
2. 创建部署描述符
部署描述符是一个名为 web.xml 的简短 XML 文件,用于描述容器应如何配置 Servlet。以下是一个基本的 web.xml 文件示例:
xml <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>Hello</servlet-name> <servlet-class>Hello</servlet-class> </servlet> </web-app>
3. 创建目录结构
每个 Web 应用应在 $(TOMCAT)/webapps 中有自己的子目录,该应用目录应包含一个 WEB-INF 子目录,而 WEB-INF 应包含一个 classes 子目录。
4. 复制文件
web.xml 文件复制到 WEB-INF 目录,将 Hello.class 文件复制到 classes 目录。最终的目录结构如下:
plaintext $(TOMCAT)/ webapps/ Hello/ WEB-INF/ web.xml classes/ Hello.class
5. 重启 Tomcat
最简单和最可靠的方法是关闭并重新启动 Tomcat,以加载新应用或在更改后重新加载应用。可以使用 $(TOMCAT)/bin 中的 startup shutdown 脚本,也可以编写一个名为 restart 的脚本将这两个功能结合起来。

部署完成后,在浏览器中访问 http://127.0.0.1:8080/Hello/servlet/Hello 即可看到 Servlet 的运行结果。

以下是部署过程的 mermaid 流程图:

graph TD;
    A[编译 Servlet] --> B[创建部署描述符];
    B --> C[创建目录结构];
    C --> D[复制文件];
    D --> E[重启 Tomcat];
4. 第一个 Jess Servlet

在开发推荐代理 Web 应用时,第一步是编写一个简单嵌入 Jess 的 Servlet。下面是一个修改后的 HelloJess Servlet 示例:

import jess.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloJess extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
    throws IOException, ServletException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        Rete engine = new Rete();
        engine.addOutputRouter("page", out);
        try {
            print("<html>", engine);
            print("<head>", engine);
            print("<title>Hello World!</title>", engine);
            print("</head>", engine);
            print("<body>", engine);
            print("<h1>Hello World from Jess!</h1>", engine);
            print("</body>", engine);
            print("</html>", engine);
        } catch (JessException je) {
            throw new ServletException(je);
        }
    }
    private void print(String message, Rete engine)
    throws JessException {
        engine.executeCommand("(printout page \"" + message +
                             "\" crlf)");
    }
}

这个 Servlet 与之前的 Hello Servlet 类似,主要区别在于创建了一个 Rete 类的实例,将 Servlet 的输出 Writer 安装为一个名为 page 的 Jess 路由器,然后使用 Jess 的 printout 函数生成 HTML 页面。

4.1 部署 Jess Servlet

HelloJess Servlet 需要访问 Jess 库才能运行,因此需要将 Jess 安装在 Tomcat 下。可以将 Jess 打包成 JAR 文件并放在 $(TOMCAT)/lib 目录中,这样所有安装的 Web 应用都可以自动访问它。如果是从源代码编译的 Jess,可以使用以下命令在 Linux 上构建 JAR 文件:

jar cf jess.jar `find jess -name '*.class' -print` jess/*.clp

然后将 jess.jar 文件复制到 $(TOMCAT)/lib 目录。同时,需要修改 web.xml 文件以适应新的 Servlet 和应用名称,将应用安装为 HelloJess 并重启 Tomcat。访问 http://127.0.0.1:8080/HelloJess/servlet/HelloJess 即可看到由 Jess 生成的页面。

4.2 清理 URL

为了简化访问 Servlet 的 URL,可以对 web.xml 文件进行修改。在 </webapp> 标签之前添加以下代码:

<servlet-mapping>
    <servlet-name>
        HelloJess
    </servlet-name>
    <url-pattern>
    /*
    </url-pattern>
</servlet-mapping>

重新安装应用并重启 Tomcat 后,访问 http://127.0.0.1:8080/HelloJess 就可以看到 Jess Servlet 的页面,此时页面和 URL 看起来就像静态 HTML 文档一样。

5. 应用架构初步设计

推荐代理应用初步设计包含四个屏幕:
- 登录屏幕:客户提供用户名。
- 目录屏幕:客户选择要购买的产品。
- 推荐屏幕:客户选择额外推荐的商品进行购买。
- 购买屏幕:客户结账。

其中,目录屏幕和推荐屏幕是重点。在客户选择一些商品之前,推荐代理无法进行推荐,因此先从目录屏幕开始开发。每个屏幕背后都有一个 Servlet,后续将逐步开发这些 Servlet。

6. 启动目录 Servlet

目录 Servlet 应执行以下步骤:
1. 获取登录名(之前由登录 Servlet 存储)。
2. 调用 get-new-order-number 获取唯一的订单号。
3. 使用此登录名和订单号创建新的用户会话。
4. 使用 all-products 查询获取产品事实列表。
5. 显示一个 HTML 表单,让客户购买产品。

然而,使用 Java 代码生成 HTML 存在一些问题,代码会显得笨拙和冗长,并且如果需要对 HTML 进行更改,就需要 Java 程序员来编辑代码并重新编译 Servlet,这会带来很大的维护问题。

为了解决这个问题,可以采用模型 - 视图 - 控制器 (MVC) 范式。将控制器逻辑放在目录 Servlet 中,视图直接用 HTML 构建(数据将存储在 Rete 对象中,模型已经很好地封装)。这样,Web 设计师可以修改 HTML 页面,Java 程序员在必要时修改 Servlet,从而使网站的维护变得更加容易。

但是,HTML 页面不是静态的,会根据许多数据进行更改。例如,页面上会显示客户的姓名,产品列表和价格也会每天变化。为了编写能够响应 Servlet 中数据变化的 HTML 页面,可以使用 JavaServer Pages(JSP)。

以下是目录 Servlet 步骤的列表:
1. 获取登录名
2. 获取唯一订单号
3. 创建新用户会话
4. 获取产品事实列表
5. 显示 HTML 表单

通过以上内容,我们了解了如何使用 Java Servlet API、Tomcat 引擎和 Jess 规则引擎来开发和部署 Web 应用,以及如何采用 MVC 范式和 JSP 来解决 HTML 页面生成和维护的问题。后续将继续深入探讨 JSP 的使用和推荐代理应用的进一步开发。

基于 Web 的应用程序部署指南

7. JavaServer Pages(JSP)的使用

JavaServer Pages(JSP)是包含少量 Java 代码的 HTML 文档。J2EE 容器能够提取其中的 Java 代码,将 HTML 转换为更多的 Java 代码,并将 JSP 编译成一个能输出原始 HTML 的 Servlet。通过使用 JSP,可以解决使用 Java 代码生成 HTML 带来的维护难题,使得 HTML 页面的修改更加灵活。

下面以目录 Servlet 为例,展示如何使用 JSP 来优化 HTML 页面的生成。

首先,创建一个 JSP 文件,例如 catalog.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <title>产品目录</title>
</head>
<body>
    <h1>欢迎,<%= session.getAttribute("loginName") %>!</h1>
    <form action="Catalog" method="post">
        <table>
            <tr>
                <th>产品名称</th>
                <th>价格</th>
                <th>数量</th>
            </tr>
            <% 
                java.util.List<Product> products = (java.util.List<Product>) request.getAttribute("products");
                for (Product product : products) {
            %>
            <tr>
                <td><%= product.getName() %></td>
                <td><%= product.getPrice() %></td>
                <td><input type="number" name="quantity_<%= product.getId() %>" value="0"></td>
            </tr>
            <% 
                }
            %>
        </table>
        <input type="submit" value="购买">
    </form>
</body>
</html>

在上述代码中, <%= session.getAttribute("loginName") %> 用于显示客户的登录名, <% %> 之间的 Java 代码用于遍历产品列表并动态生成表格行。

然后,修改目录 Servlet 的代码,将数据传递给 JSP 页面:

import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class Catalog extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取登录名
        HttpSession session = request.getSession();
        String loginName = (String) session.getAttribute("loginName");

        // 调用 get-new-order-number 获取唯一订单号
        String orderNumber = getNewOrderNumber();

        // 创建新用户会话
        session.setAttribute("orderNumber", orderNumber);

        // 使用 all-products 查询获取产品事实列表
        List<Product> products = getAllProducts();

        // 将数据传递给 JSP 页面
        request.setAttribute("products", products);

        // 转发到 JSP 页面
        request.getRequestDispatcher("catalog.jsp").forward(request, response);
    }

    private String getNewOrderNumber() {
        // 实现获取唯一订单号的逻辑
        return "123456";
    }

    private List<Product> getAllProducts() {
        // 实现获取产品列表的逻辑
        return null;
    }
}

在这个 Servlet 中,将登录名、订单号和产品列表存储在 request session 中,并使用 request.getRequestDispatcher("catalog.jsp").forward(request, response) 将请求转发到 catalog.jsp 页面。

以下是使用 JSP 后目录 Servlet 流程的 mermaid 流程图:

graph TD;
    A[获取登录名] --> B[获取唯一订单号];
    B --> C[创建新用户会话];
    C --> D[获取产品事实列表];
    D --> E[将数据传递给 JSP];
    E --> F[转发到 JSP 页面];
8. 进一步开发推荐代理应用

在完成目录 Servlet 和 JSP 的开发后,接下来可以继续开发推荐屏幕和购买屏幕的 Servlet。

8.1 推荐屏幕 Servlet

推荐屏幕 Servlet 的主要功能是根据客户在目录屏幕选择的产品,使用 Jess 规则引擎生成推荐的产品列表,并显示给客户。

以下是一个简单的推荐屏幕 Servlet 示例:

import jess.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class Recommend extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        // 获取客户选择的产品列表
        List<Product> selectedProducts = (List<Product>) session.getAttribute("selectedProducts");

        // 创建 Jess 引擎
        Rete engine = new Rete();
        try {
            // 加载 Jess 规则文件
            engine.batch("recommend.clp");

            // 将客户选择的产品事实插入 Jess 引擎
            for (Product product : selectedProducts) {
                engine.assertString("(product " + product.getId() + ")");
            }

            // 运行 Jess 引擎
            engine.run();

            // 获取推荐的产品列表
            List<Product> recommendedProducts = getRecommendedProducts(engine);

            // 将推荐的产品列表传递给 JSP 页面
            request.setAttribute("recommendedProducts", recommendedProducts);

            // 转发到推荐页面
            request.getRequestDispatcher("recommend.jsp").forward(request, response);
        } catch (JessException e) {
            e.printStackTrace();
        }
    }

    private List<Product> getRecommendedProducts(Rete engine) throws JessException {
        List<Product> recommendedProducts = new ArrayList<>();
        // 实现从 Jess 引擎获取推荐产品的逻辑
        return recommendedProducts;
    }
}

在这个 Servlet 中,首先从 session 中获取客户选择的产品列表,然后创建 Jess 引擎,加载规则文件,将产品事实插入引擎并运行规则,最后获取推荐的产品列表并传递给 recommend.jsp 页面。

8.2 购买屏幕 Servlet

购买屏幕 Servlet 的主要功能是处理客户的购买请求,更新订单信息,并显示购买确认页面。

以下是一个简单的购买屏幕 Servlet 示例:

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class Purchase extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        // 获取订单号
        String orderNumber = (String) session.getAttribute("orderNumber");
        // 获取客户选择的产品列表
        List<Product> selectedProducts = (List<Product>) session.getAttribute("selectedProducts");
        // 获取客户选择的推荐产品列表
        List<Product> recommendedProducts = (List<Product>) session.getAttribute("recommendedProducts");

        // 处理购买逻辑,例如更新订单信息、扣除库存等
        processPurchase(orderNumber, selectedProducts, recommendedProducts);

        // 转发到购买确认页面
        request.getRequestDispatcher("purchase_confirm.jsp").forward(request, response);
    }

    private void processPurchase(String orderNumber, List<Product> selectedProducts, List<Product> recommendedProducts) {
        // 实现购买处理逻辑
    }
}

在这个 Servlet 中,从 session 中获取订单号、客户选择的产品列表和推荐的产品列表,然后处理购买逻辑,最后将请求转发到购买确认页面。

9. 总结

通过以上内容,我们详细介绍了如何使用 Java Servlet API、Tomcat 引擎、Jess 规则引擎和 JavaServer Pages 来开发和部署推荐代理 Web 应用。

在开发过程中,我们学习了以下关键知识点:
- 如何编写和部署简单的 Servlet。
- 如何使用 Tomcat 作为 Servlet 容器。
- 如何嵌入 Jess 规则引擎到 Servlet 中。
- 如何使用 MVC 范式和 JSP 来解决 HTML 页面生成和维护的问题。
- 如何设计和实现推荐代理应用的各个屏幕。

以下是推荐代理应用开发步骤的总结表格:
| 步骤 | 描述 |
| ---- | ---- |
| 1 | 编写和部署 Hello Servlet 了解基本 Servlet 开发和部署流程 |
| 2 | 编写和部署 Jess Servlet 学习如何嵌入 Jess 规则引擎 |
| 3 | 设计应用架构,确定四个屏幕的功能 |
| 4 | 开发目录 Servlet 和使用 JSP 解决 HTML 维护问题 |
| 5 | 开发推荐屏幕 Servlet,使用 Jess 生成推荐列表 |
| 6 | 开发购买屏幕 Servlet,处理购买请求 |

通过遵循这些步骤和技术,我们可以开发出一个功能完善、易于维护的 Web 应用。在实际开发中,可以根据具体需求对代码和规则进行进一步的优化和扩展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值