搜索

2.5. 回顾快速启动示例

download PDF

2.5.1. 浏览 helloworld 快速启动

helloworld 快速入门演示了如何将简单的 Servlet 部署到 JBoss EAP。业务逻辑封装在服务中,作为上下文和依赖注入(CDI) Bean 提供,并注入到 Servlet 中。此快速入门是一个起点,可确保您已正确配置和启动服务器。

使用命令行构建和部署此快速启动的详细说明,请参见 helloworld 快速启动目录根目录下的 README.html 文件。本主题展示了如何使用 JBoss 工具来运行快速启动,并假设您已安装了 JBoss 工具、配置了 Maven,导入并成功运行了 helloworld 快速启动。

注意

JBoss 工具在 JBoss EAP 8.0 中已弃用。不会对这个功能进行任何增强,它可能会在以后的版本中删除。

2.5.1.1. 检查目录结构

helloworld 快速启动的代码可以在 QUICKSTART_HOME/helloworld/ 目录中找到。helloworld 快速启动由 Servlet 和一个 CDI bean 组成。它还包含应用的 WEB-INF/ 目录中的 beans.xml 文件,其版本号为 1.1,并且 bean-discovery-modeall。此标志文件将 WAR 识别为 bean 存档,并告知 JBoss EAP 在此应用程序中查找 bean ,并激活 CDI。

src/main/webapp/ 目录包含快速启动的文件。本例的所有配置文件都位于 src/main/webapp/ 中的 WEB-INF/ 目录中, 包括 beans.xml 文件。src/main/webapp/ 目录还包括 index.html 文件,该文件使用简单的 meta refresh 将用户的浏览器重定向到 Servlet,它位于 http://localhost:8080/helloworld/HelloWorld。quickstart 不需要 web.xml 文件。

2.5.1.2. 回顾 HelloWorldServlet.java 代码

软件包声明和导入已从这些列表中排除。Quickstart 源代码中提供了完整的列表。

注意

JBoss 工具在 JBoss EAP 8.0 中已弃用。不会对这个功能进行任何增强,它可能会在以后的版本中删除。

先决条件

  • 安装 JBoss 工具。具体说明请查看 JBoss 工具安装指南中的 安装方法
  • 运行 helloworld 快速入门。
  • 打开 Web 浏览器并在 http://localhost:8080/helloworld 访问应用,以验证 helloworld quickstart 已成功部署到 JBoss EAP。

流程

  1. 查看 HelloWorldServlet 代码。

    HelloWorldServlet.java 文件位于 src/main/java/org/jboss/as/quickstarts/helloworld/ 目录中。此 servlet 将信息发送到浏览器。

    示例:HelloWorldServlet 类代码

    42 @SuppressWarnings("serial")
    43 @WebServlet("/HelloWorld")
    44 public class HelloWorldServlet extends HttpServlet {
    45
    46     static String PAGE_HEADER = "<html><head><title>helloworld</title></head><body>";
    47
    48     static String PAGE_FOOTER = "</body></html>";
    49
    50     @Inject
    51	   HelloService helloService;
    52
    53     @Override
    54     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    55         resp.setContentType("text/html");
    56         PrintWriter writer = resp.getWriter();
    57         writer.println(PAGE_HEADER);
    58         writer.println("<h1>" + helloService.createHelloMessage("World") + "</h1>");
    59         writer.println(PAGE_FOOTER);
    60         writer.close();
    61     }
    62
    63 }

2.5.1.2.1. HelloWorldServlet 详情

此 servlet 会向您的浏览器发送信息。

表 2.1. HelloWorldServlet 详情
备注

43

您只需要添加 @WebServlet 注释,并提供用于访问 servlet 的 URL 映射。

46-48

每个网页都需要正确构成 HTML。这个快速入门使用静态字符串来编写最小标头和页脚输出。

50-51

这些行注入生成实际消息的 HelloService CDI bean。只要我们不更改 HelloService 的 API,这种方法允许我们以后在不更改视图层的情况下更改 HelloService 的实施。

58

此行调用 服务以生成消息"Hello World",并将它写入到 HTTP 请求。

  1. 检查 HelloService 代码。

    HelloService.java 文件位于 src/main/java/org/jboss/as/quickstarts/helloworld/ 目录中。此服务只需返回一条消息。不需要 XML 或注解注册。

    示例:HelloService 类代码

    public class HelloService {
    
        String createHelloMessage(String name) {
            return "Hello " + name + "!";
        }
    }

其他资源

2.5.2. 探索 numberguess 快速启动

numberguess 快速启动演示了如何将简单的非持久性应用创建和部署至 JBoss EAP。使用 JSF 视图显示信息,业务逻辑被封装到两个 CDI bean 中。在 numberguess 快速启动中,您有十次尝试猜测 1 到 100 之间的数字。在每次尝试后,您都会被告知您的猜测过高还是过低。

numberguess Quickstart 的代码可以在 QUICKSTART_HOME/numberguess/ 目录中找到,其中 QUICKSTART_HOME 是您下载并解压缩 JBoss EAP 快速入门的目录。numberguess 快速启动由多个 bean、配置文件和 Facelets (JSF)视图组成,并被打包为 WAR 模块。

使用命令行构建和部署此快速启动的详细说明,请参阅 numberguess quickstart 目录的 README.html 文件。以下示例使用 JBoss 工具来运行快速启动。

注意

JBoss 工具在 JBoss EAP 8.0 中已弃用。不会对这个功能进行任何增强,它可能会在以后的版本中删除。

2.5.2.1. 检查 numberguess 配置文件

本例的所有配置文件都位于 QUICKSTART_HOME/numberguess/src/main/webapp/WEB-INF/ 目录中。

先决条件

  • 安装 JBoss 工具。具体说明请查看 JBoss 工具安装指南中的 安装方法
  • 运行 numberguess Quickstart。
  • 打开 Web 浏览器并访问 URL http://localhost:8080/numberguess 来访问这个应用,以验证 numbergues quickstart 已成功部署到 JBoss EAP。
注意

JBoss 工具在 JBoss EAP 8.0 中已弃用。不会对这个功能进行任何增强,它可能会在以后的版本中删除。

流程

  1. 检查 face-config.xml 文件。

    该快速启动使用 faces-config.xml 文件名的 JSF 2.2 版本。Facelets 的标准化版本是 JSF 2.2 中的默认视图处理程序,因此不需要配置。此文件仅包含 root 元素,只是指示应用中应启用 JSF 的标志文件。

    <faces-config version="2.2"
       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
          http://xmlns.jcp.org/xml/ns/javaee
          http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
    
    </faces-config>
  2. 检查 beans.xml 文件。

    beans.xml 文件包含版本号 1.1,并且 bean-discovery-mode 包含 all。此文件是一种标志文件,将 WAR 识别为 bean 存档,并告知 JBoss EAP 在此应用程序中查找 Bean ,并激活 CDI。

    <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
          http://xmlns.jcp.org/xml/ns/javaee
          http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
        bean-discovery-mode="all">
    </beans>
注意

此快速入门不需要 web.xml 文件。

其他资源

2.5.2.2. 检查 JSF 代码

JSF 将 .xhtml 文件扩展用于源文件,但使用 .jsf 扩展提供呈现的视图。home.xhtml 文件位于 src/main/webapp/ 目录中。

示例:JSF 源代码

19<html xmlns="http://www.w3.org/1999/xhtml"
20	xmlns:ui="http://java.sun.com/jsf/facelets"
21	xmlns:h="http://java.sun.com/jsf/html"
22	xmlns:f="http://java.sun.com/jsf/core">
23
24	<head>
25	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
26	<title>Numberguess</title>
27	</head>
28
29	<body>
30	<div id="content">
31		<h1>Guess a number...</h1>
32		<h:form id="numberGuess">
33
34		<!-- Feedback for the user on their guess -->
35	<div style="color: red">
36		<h:messages id="messages" globalOnly="false" />
37		<h:outputText id="Higher" value="Higher!"
38 		  rendered="#{game.number gt game.guess and game.guess ne 0}" />
39		<h:outputText id="Lower" value="Lower!"
40		   rendered="#{game.number lt game.guess and game.guess ne 0}" />
41	</div>
42
43	<!-- Instructions for the user -->
44	<div>
45	I'm thinking of a number between <span
46	id="numberGuess:smallest">#{game.smallest}</span> and <span
47	id="numberGuess:biggest">#{game.biggest}</span>. You have
48	#{game.remainingGuesses} guesses remaining.
49	</div>
50
51	<!-- Input box for the users guess, plus a button to submit, and reset -->
52	<!-- These are bound using EL to our CDI beans -->
53	<div>
54	Your guess:
55	<h:inputText id="inputGuess" value="#{game.guess}"
56		required="true" size="3"
57		disabled="#{game.number eq game.guess}"
58		validator="#{game.validateNumberRange}" />
59		<h:commandButton id="guessButton" value="Guess"
60			action="#{game.check}"
61			disabled="#{game.number eq game.guess}" />
62	</div>
63	<div>
64	<h:commandButton id="restartButton" value="Reset"
65	action="#{game.reset}" immediate="true" />
66	</div>
67	</h:form>
68
69	</div>
70
71	<br style="clear: both" />
72
73	</body>
74</html>

下面的行号与在 JBoss 工具中查看文件时看到的行号相对应。

注意

JBoss 工具在 JBoss EAP 8.0 中已弃用。不会对这个功能进行任何增强,它可能会在以后的版本中删除。

表 2.2. JSF 详情
备注

36-40

这些消息可以发送给用户:"Higher!"和"Lower!"。

45-48

用户猜测,可以猜到的数字范围会较小。这一句子会改变,确保他们知道有效猜测的范围。

55-58

此输入字段绑定至使用值表达式的 bean 属性。

58

验证器绑定用于确保用户不会意外输入他们可能猜到的范围之外的数字。如果验证器不在此处,用户可能会对不限号使用一个猜测。

59-61

必须有办法让用户将其猜测发送到服务器。在这里,我们绑定了 Bean 的操作方法。

2.5.2.3. 检查 numberguess 类文件

所有 numberguess 快速启动源文件都可在 QUICKSTART_HOME/numberguess/src/main/java/org/jboss/as/quickstarts/numberguess/ 目录中找到。软件包声明和导入已从这些列表中排除。Quickstart 源代码中提供了完整的列表。

流程

  1. 查看 Random.java Qualifier Code

    限定符用于消除两个 Bean 之间的不确定性,两者都有资格根据其类型注入。@Random 限定符用于注入随机数字。

    @Target({ TYPE, METHOD, PARAMETER, FIELD })
    @Retention(RUNTIME)
    @Documented
    @Qualifier
    public @interface Random {
    
    }
  2. 查看 MaxNumber.java Qualifier Code

    @MaxNumber qualifier 用于注入允许的最大数量。

    @Target({ TYPE, METHOD, PARAMETER, FIELD })
    @Retention(RUNTIME)
    @Documented
    @Qualifier
    public @interface MaxNumber {
    }
  3. 查看 Generator.java Code

    Generator 类通过制作者方法创建随机数,并通过相同方式公开可能的最大数量。此类为应用范围,因此每次都不会出现不同的随机值。

    @SuppressWarnings("serial")
    @ApplicationScoped
    public class Generator implements Serializable {
    
        private java.util.Random random = new java.util.Random(System.currentTimeMillis());
    
        private int maxNumber = 100;
    
        java.util.Random getRandom() {
            return random;
        }
    
        @Produces
        @Random
        int next() {
            // a number between 1 and 100
            return getRandom().nextInt(maxNumber - 1) + 1;
        }
    
        @Produces
        @MaxNumber
        int getMaxNumber() {
            return maxNumber;
        }
    }
  4. 查看 Game.java 代码

    会话范围的 Game 类是应用的主要入口点。它负责设置或重置游戏,捕获和验证用户的猜测,并通过 FacesMessage 向用户提供反馈。它使用构建后生命周期方法从 @Random Instance<Integer> bean 检索随机数来初始化游戏。

    注意类中的 @Named 注释。只有在您希望使用 Jakarta Expression Language (在本例中为 #{game} )使 bean 可访问 JSF 时,才需要此注释。

    @SuppressWarnings("serial")
    @Named
    @SessionScoped
    public class Game implements Serializable {
    
        /**
         * The number that the user needs to guess
         */
        private int number;
    
        /**
         * The users latest guess
         */
        private int guess;
    
        /**
         * The smallest number guessed so far (so we can track the valid guess range).
         */
        private int smallest;
    
        /**
         * The largest number guessed so far
         */
        private int biggest;
    
        /**
         * The number of guesses remaining
         */
        private int remainingGuesses;
    
        /**
         * The maximum number we should ask them to guess
         */
        @Inject
        @MaxNumber
        private int maxNumber;
    
        /**
         * The random number to guess
         */
        @Inject
        @Random
        Instance<Integer> randomNumber;
    
        public Game() {
        }
    
        public int getNumber() {
            return number;
        }
    
        public int getGuess() {
            return guess;
        }
    
        public void setGuess(int guess) {
            this.guess = guess;
        }
    
        public int getSmallest() {
            return smallest;
        }
    
        public int getBiggest() {
            return biggest;
        }
    
        public int getRemainingGuesses() {
            return remainingGuesses;
        }
    
        /**
         * Check whether the current guess is correct, and update the biggest/smallest guesses as needed. Give feedback to the user
         * if they are correct.
         */
        public void check() {
            if (guess > number) {
                biggest = guess - 1;
            } else if (guess < number) {
                smallest = guess + 1;
            } else if (guess == number) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Correct!"));
            }
            remainingGuesses--;
        }
    
        /**
         * Reset the game, by putting all values back to their defaults, and getting a new random number. We also call this method
         * when the user starts playing for the first time using {@linkplain PostConstruct @PostConstruct} to set the initial
         * values.
         */
        @PostConstruct
        public void reset() {
            this.smallest = 0;
            this.guess = 0;
            this.remainingGuesses = 10;
            this.biggest = maxNumber;
            this.number = randomNumber.get();
        }
    
        /**
         * A JSF validation method which checks whether the guess is valid. It might not be valid because there are no guesses left,
         * or because the guess is not in range.
         *
         */
        public void validateNumberRange(FacesContext context, UIComponent toValidate, Object value) {
            if (remainingGuesses <= 0) {
                FacesMessage message = new FacesMessage("No guesses left!");
                context.addMessage(toValidate.getClientId(context), message);
                ((UIInput) toValidate).setValid(false);
                return;
            }
            int input = (Integer) value;
    
            if (input < smallest || input > biggest) {
                ((UIInput) toValidate).setValid(false);
    
                FacesMessage message = new FacesMessage("Invalid guess");
                context.addMessage(toValidate.getClientId(context), message);
            }
        }
    }
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.