当前页面: 开发资料首页 → Netbeans 专题 → 使用 NetBeans IDE 5.0 开发 Web 应用程序教程
摘要: 使用 NetBeans IDE 5.0 开发 Web 应用程序教程 反馈 本教程中构建的 Midnight Cookie Company 应用程序将向您介绍如何执行以下操作: 从现有源创建 web 项...
本教程中构建的 Midnight Cookie Company 应用程序将向您介绍如何执行以下操作:
下面是本教程中所使用的一些术语的解释。
当创建合成视图时,您既可以包含静态的内容,也可以包含动态的内容。静态内容由 HTML 文件组成。动态内容是 JSP 页面的一部分。可以在 JSP 安装时或运行时决定具体的内容。
该应用程序使用 JavaServer Pages Standard Tag Library (JSTL) 获取该应用程序中使用的动态数据以及国际化 JSP 页面。
当您构建 Midnight Cookie Company 应用程序时,本教程将带您浏览在 IDE 中的整个 web 开发过程。
完成本教程大约要花两个小时的时间。
开始编写代码之前,必须确保您具备所有必要的软件,并且保证正确设置项目。
开始之前,需要在您的计算机上安装以下软件:
也可以下载并使用 Sun Java System (SJS) Application Server(下载)、JBoss 或 WebLogic。但是,与 IDE 绑定在一起的 Tomcat Web Server 可以提供两层 Web 应用程序(如本快速入门指南中描述的)所需的全部支持。仅当您要开发企业应用程序时才需要应用服务器(如 SJS Application Server、Jboss 或 WebLogic)。
绑定的 Tomcat Web Server 会自动在 IDE 中注册。但是,在部署到 SJS Application Server、Jboss 或 WebLogic 之前,必须在 IDE 中注册一个本地实例。如果安装了 NetBeans IDE 5.0/SJS Application Server 包,则自动注册 SJS Application Server 的本地实例。否则,请执行以下步骤:
要创建 Midnight Cookie Company 应用程序,您需要 midnight.zip 文件,该文件包含您构建应用程序的源文件。源文件包含 WEB-INF 文件夹,该文件夹包含您将在本教程中使用的 classes、docs、tlds 和 lib 文件夹。
$UNZIPHOME 现在有 WEB-INF 文件夹,该文件夹包含以下文件和文件夹:
文件或文件夹
|
描述
|
web.xml | web 应用程序的部署描述符。 |
classes | 包含用于国际化页面的资源包属性文件,还包含 com/midnightcookies/taghandlers 文件夹。taghandlers 文件夹包含 ContentHandler 标记句柄、ButtonHandler 标记句柄和 LinksHandler 标记句柄的类文件。ContentHandler 包含指定 JSP 文件的内容。ButtonHandler 打印具有本地化的消息的提交按钮。LinksHandler 显示标记属性中的一组链接,包括分隔符。 |
docs | 包含 header.jsp 文件、index.jsp 文件和 nonesuch.jsp 文件。在本教程期间,您将创建 main.jsp 页面并将其放在该文件夹中。还包含 cookies 文件夹,该文件夹包含 CookieCutter.jsp 文件和 CookieMake.jsp 文件。在本教程期间,您将创建 Tray.jsp 页面并将其放在该文件夹中。about 文件夹包含 about.jsp 文件,该文件概述了该 web 应用程序的架构。 |
lib | 包含 standard.jar 文件和 jstl.jar 文件。这两个文件包含 JSTL 的实现。standard.jar 包含 TLD 和标记句柄。jstl.jar 文件包含所需的其他应用程序界面 (API)。 |
tlds | 包含专用的 midnight.tld。 |
将提示您让 IDE 删除您的类文件,因为当构建项目时,它们将自动编译到您项目的 build 文件夹。单击 Delete 以允许 IDE 这样做。
IDE 在 IDE 中导入源、删除类文件并创建 Midnight 项目。可以在 Projects 窗口中查看其逻辑结构,在 Files 窗口中查看其文件结构。
前端控制器负责路由传入用户请求并在 web 应用程序中实施导航。前端控制器提供一个入口点,通过该入口点在 web 应用程序通道中请求几个资源。前端控制器可以减少在 JSP 页面中复制代码,尤其是在几个资源都需要进行相同的处理时更是如此。有关前端控制器的详细信息,请参阅构建 Web 组件 编程系列书中的“前端控制器”部分,该书位于 Sun!" ONE Studio Developer Resources 网站的文档页面中。
/docs/*, /注意上面一行中的“,”是两个 URL 映射之间的分隔符。它允许您为每个 servlet 创建多个 URL 映射。
servlet 映射“/docs/*”表示从前面页面转到自己的 FrontController servlet,而 servlet 映射“/”为 FrontController servlet 提供了一个处理请求(如 http://hostname:portnumber/midnight/)的 servlet 映射。
单击编辑器顶部的 XML。部署描述符文件的内容便以 XML 格式显示。servlet 映射如下:
现在,您将编辑 FrontController.java 文件以包含处理 web 应用程序接收到的请求所需的逻辑。您将修改 processRequest 方法并创建一个名为 createCookie 的新方法,该方法演示如何创建在 web 应用程序中使用的 cookie。
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getRequestURI(); id = id.substring(request.getContextPath().length()); getServletContext().log ("Midnight Cookies FrontController received a request for " + id); // The page variable holds the path to the page that will be included // in the content area of the template page /WEB-INF/docs/main.jsp. // It is passed to the template in a request attribute. String page; // If no request is received or if the request received is // for the root, serve /WEB-INF/docs/index.jsp if (id == null || id.trim().equals("") || id.equals("/")){ page = "/WEB-INF/docs/index.jsp"; } // If a request received is for a file that does not end in // .jsp or .html, there was an error. Include the // error page (nonesuch.jsp) and set the nonesuch attribute with // the path requested. else if (!id.endsWith(".jsp") && !id.endsWith(".html")) { page = "/WEB-INF/docs/nonesuch.jsp"; request.setAttribute("nonesuch", id); } else { page = "/WEB-INF".concat(id); if (id.equals("/docs/cookies/CookieMake.jsp")) { Cookie cookie = createCookie(request); if (cookie == null) { page = "/WEB-INF/docs/cookies/CookieCutter.jsp"; } else { response.addCookie(cookie); request.setAttribute("cookie", cookie); } } } request.setAttribute("page", page); try { request.getRequestDispatcher("/WEB-INF/docs/main.jsp").forward(request, response); } catch(Throwable t) { getServletContext().log(t.getMessage()); } }
注意: 在 Source Editor 中输入代码(或者通过输入、复制和粘贴),将光标放在 Source Editor 中并按 Ctrl-Shift-F 可自动重新格式化该代码。要显示行号,请右键单击右边空白处并从上下文菜单中选择 Show Line Numbers。
调用 createCookie 方法的行带有下划线并标记为错误,类似于以下说明。这是因为该方法尚不存在。
在有错误的行中单击 Alt-Enter,注意 IDE 提供了一条如何解决该错误的建议。
private Cookie createCookie(HttpServletRequest request) { String name = (String)request.getParameter("name"); if (name == null || name.trim().equals("")) { request.setAttribute("noname", "noname"); request.setAttribute("error", "true"); return null; } String value = (String)request.getParameter("value"); if (value == null || value.trim().equals("")) { request.setAttribute("novalue", "novalue"); request.setAttribute("error", "true"); return null; } System.out.println(name); System.out.println(value); Cookie cookie = null; try { cookie = new Cookie(name, value); } catch(IllegalArgumentException ex) { // Probably an illegal name ex.printStackTrace(); request.setAttribute("error", "true"); request.setAttribute("noname", "badname"); return null; } String maxage = request.getParameter("maxage"); if (maxage != null && !maxage.trim().equals("")) { try { cookie.setMaxAge(Integer.parseInt(maxage)); } catch(NumberFormatException nfe) { nfe.printStackTrace(); request.setAttribute("badnumber", "badnumber"); request.setAttribute("error", "true"); return null; } } String domain = request.getParameter("domain"); if (domain != null && !domain.trim().equals("")) { cookie.setDomain(domain); } String path = request.getParameter("path"); if (path != null && !path.trim().equals("")) { cookie.setPath(path); } String secure = request.getParameter("secure"); if (secure != null && secure.equals("on")) { cookie.setSecure(true); } else { cookie.setSecure(false); } return cookie; }
按 Ctrl-S 保存文档。Source Editor 顶部该文件的选项卡中的星号便消失。
main.jsp 页面接收 FrontController servlet 处理的所有请求。动态页面包括用于创建该页面的语句和 LinksHandler。
main.jsp 将在 Source Editor 中打开。
<%@page contentType="text/html;charset=UTF-8"%> <%@page buffer="none"%> <%-- The <midnight:content/> tag which handles the contents section is simplistically implemented to use an include. Hence this page cannot be buffered --%> <%@taglib prefix="midnight" uri="http://www.midnightcookies.com/midnight"%> <html> <head><title>The Midnight Cookie Company</title></head> <body text="#996633" link="#cc6600" vlink="#993300" alink="#000000"> <span font-style="sans-serif"> <TABLE border="0"> <tr> <table border="0"> <tr><td width="80" height="100"> </td> <td width="500" height="100" text="#996633" bgcolor="#ffff99" valign="center"halign="center"> <jsp:include page="/WEB-INF/docs/header.jsp" flush="true"/> </td> </tr> <tr><td width="90" height="300" text="#996633" bgcolor="#ffff99" valign="top"> <midnight:links separator="<br>"/> </td> <td width="500" height="300" valign="top"cellpadding="15" cellspacing="15"> <midnight:content/> </td> </tr> </table> </tr> <tr><td width="580" height="50" text="#996633" bgcolor="#ffff99" valign="top"> <midnight:links separator="|"/> </td> </tr> </span> </TABLE> </body> </html>
注意: 在 Source Editor 中输入代码(或者通过输入、复制和粘贴),将光标放在 Source Editor 中并按 Ctrl-Shift-F 可自动重新格式化该代码。
在本部分中创建的参数文件演示使用标记库中的标记处理国际化。它们还显示如何通过 Request 参数,特别是通过 JSP 表达式语言 (EL) 表达式 ${param.input} 传递输入,该表达式是在 Input.jsp 页面的输入字段中设置的。
<%@page contentType="text/html;charset=UTF-8"%> <%@taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %> <%@taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <%@taglib prefix="midnight" uri="/WEB-INF/tlds/midnight.tld"%> <fmt:setBundle basename="com.midnightcookies.Midnight" var="bundle" scope="page"/> <h3><fmt:message key="provide_input" bundle="${bundle}"/></h3> <form method="POST" action="Output.jsp"> <table> <tr> <td><fmt:message key="type_input" bundle="${bundle}"/>:<td> <%-- The value of the Input field will be placed in a request parameter named "input" and it will be passed to Output.jsp --%> <td><input type="text" size="20" name="input" value=""></td> </tr> <tr> <td><fmt:message key="submit" bundle="${bundle}" var="buttonLabel" scope="page"/> <midnight:button/> </td> <td></td> </tr> </table> </form>
<%@page contentType="text/html;charset=UTF-8"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <fmt:setBundle basename="com.midnightcookies.Midnight" var="bundle" scope="page"/> <h3><fmt:message key="display_input" bundle="${bundle}"/></h3> <fmt:message key="datareceived" bundle="${bundle}"/>: <!--The following line gets the value of the request parameter named "input". This is a demo application. For security reasons, one should never echo user input without parsing first. --> <c:out value="${param.input}"/>
您在本部分创建的 Tray.jsp 页面演示使用 JSTL 国际化页面,而不是使用脚本。CookieCutter.jsp 文件、CookieMaker.jsp 文件和资源包属性文件都已和 midnight.zip 文件一起提供。您可以仔细看看这些文件和演示在该应用程序中如何处理国际化的示例文件 Tray.jsp。
<%@page contentType="text/html;charset=UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %> <fmt:setBundle basename="com.midnightcookies.Midnight" var="bundle" scope="page"/> <h3><fmt:message key="cookies" bundle="${bundle}"/></h3> <table border="1"> <tr> <th halign="center">#</th> <th align="left"> <fmt:message key="name" bundle="${bundle}"/> </th> <th align="left"> <fmt:message key="value" bundle="${bundle}"/> </th> <tr> <%-- We have to use expression to get at an array. If we use ${cookie} then we get a map and the entries are not automatically cast --%> <% request.setAttribute("cookies", request.getCookies()); %> <c:set var="i" value="0"/> <c:forEach var="ck" items="${cookies}"> <c:set var="i" value="${i+1}"/> <tr> <td><c:out value="${i}"/></td> <td><c:out value="${ck.name}"/></td> <td><c:out value="${ck.value}"/></td> </tr> </c:forEach> </table>
完成了上述的开发阶段之后,Projects 窗口和 Files 窗口中的视图将如下所示:
注意: 将上面演示的应用程序部署到 Tomcat Web Server。如果您注册并选择了不同的目标服务器,则您将不会有 META-INF/context.xml 文件。例如,如果您的服务器是 Sun Java System Application Server,则您的部署描述符文件为 WEB-INF/sun-web.xml 文件。
对于 Tomcat Web Server,默认情况下启用 HTTP 监视器。但是,对于其他服务器,您必须手动启用 HTTP 监视器。此外,必须启动 HTTP Server,HTTP 监视器才能为其他服务器工作。
执行以下操作以准备使用 HTTP 监视器:
通过将 URL 设置为 http://hostname:port/Midnight 来启动 web 浏览器。以下示例显示在 Microsoft Windows 平台上运行的 web 浏览器。
如果在尝试执行该应用程序时收到一个错误,请参阅执行问题的故障排除以获得一些可能的解决方案。
以下部分演示您如何使用 HTTP 监视器监视请求、会话和 cookie。
最后一个条目表示 Midnight web 应用程序的请求。
您的 web 浏览器显示类似以下内容的信息。
您的 web 浏览器显示 Output.jsp 页面的内容,类似以下内容。
HTTP 监视器显示类似以下内容的信息。
您的 web 浏览器显示 CookieCutter.jsp 页面。
您的 web 浏览器显示类似以下内容的信息。
HTTP 监视器显示类似以下内容的信息。
注意显示 nonesuch.jsp 页面的内容,而不是不存在的 Bake.jsp 页面。
注意,您必须将这两种语言添加到当前您的 web 浏览器可用的语言列表中。
注意,左侧导航栏中的链接、页面底部的链接以及一些应用程序的 JSP 页面的内容如何转换为您所选择的语言。
web 应用程序使用资源包属性文件帮助转换该 web 应用程序中使用的一些页面。因此,转换和资源包属性文件的内容一样广泛。
如果在执行 Midnight Cookie Company 应用程序时收到一个错误,下面是有关这些问题的一些可能解决方案的提示:
检查您指定的要与 IDE 一起使用的浏览器的路径是否正确配置:
如果将您的 web 浏览器设置为使用代理服务器,则您的 web 浏览器将试图路由您想通过代理服务器查看的所有文件,包括本地文件。您需要向 web 浏览器的设置中的忽略主机列表中添加 localhost 和您的机器名。有关详细信息,请参阅 IDE 帮助系统中标题为“Accessing Local Files Through a Proxy”的在线帮助主题。(选择 > Help Contents,展开“Servers and Databases node”,然后展开“Web Browsers”节点。)
单击在本教程中创建的 JSP 文件的名称。确保在 New File 向导中输入对象的名称时,不要输入 .jsp 文件扩展名。如有必要,重新命名文件。
关键字 | 默认值 | 法语 | 瑞典语 |
exit | Exit | Sortie | Utgång |
closingRemark | Goodbye | Au revoir | Hej då |
Use å to display the å character.
下面是您可能研究的一些其他 web 应用程序功能。
展开 tlds/Midnight 节点可在库中看到标记列表。查看 Source Editor 中的 Links 标记及其 Attributes,看它是否带有分隔符属性。
在 Source Editor 打开 docs/main.jsp 文件,通过在大约第 32 行(调用 midnight:content 的行)的位置单击空白处设置一个断点。在 Projects 窗口或 Files 窗口中右键单击项目节点,并从上下文菜单中选择 Debug Project。该 web 应用程序将在您设置断点的位置停止。按 F7 可再次运行代码。只要由于缺少源出现对话框,就按 OK 以选择在具有源的第一行停止这个默认设置。继续按 F7 直到您进入 ContentHandler 类中的 otherDoStartTagOperations() 函数。在第 50 行设置断点 (request.getRequestDispatcher(page).include(request, response)) 并按 Ctrl-F5(继续)。将光标放在“page”、“request”和“response”上以查看这些值。您也可以在 Local Variables 选项卡中查看这些值。注意 Call Stack 选项卡显示 JSP 代码和生成的 servlet 方法之间的关系。尝试设置其他断点。右键单击一个变量,然后从上下文菜单中选择 New Watch。当您在 web 应用程序中执行各种页面时,单击 Watches 选项卡可以查看这些值的变化。选择 Debug > Finish Session 以推出调试会话。
要运行公共的 JSP 文件(不在 WEB-INF 文件夹下),只需右键单击该文件的节点,然后从上下文菜单中选择 Execute。如果加载页面,则单击浏览器的 reload 按钮将显示您所做的所有修改。私有的 JSP 文件,比如本教程中的这个文件,执行起来有点困难。在不重新启动 web 应用程序和导航到该页面的情况下,测试已修改的 JSP 文件的一种方法是使用 HTTP 监视器的 replay 操作。通过将表的边界设置为 10 并保存更改来修改 docs/cookies/Tray.jsp 文件。在 HTTP 监视器中,右键单击 GET Tray.jsp 记录并从上下文菜单中选择 Replay。Tray.jsp 页面应该显示在浏览器中,并且表的边界比较大。
下面是本教程中所使用的一些术语的解释。
用于演示 JSP 页面中信息的设计模式。该设计模式从组件视图中创建一个组合视图。组件视图可能包括页面的动态部分和模块部分。当您从多个子视图中创建视图时,合成视图设计模式与 web 应用程序设计模式有关。合成的 web 页面通常来自各种资源的内容组成。页面的布局由其子视图的内容独立管理。例如,一个视图的子视图可能为 Navigation、Search、Feature Story 和 Headline。
当创建合成视图时,您既可以包含静态的内容,也可以包含动态的内容。静态内容由 HTML 文件组成。动态内容是 JSP 页面的一部分。可以在 JSP 安装时或运行时决定具体的内容。
前端控制器负责路由传入请求并在 web 应用程序中实施导航的组件。有关使用前端控制器设计模式的详细信息,请参阅构建 Web 组件 编程系列书中的“前端控制器”部分,该书位于 Sun!" ONE Studio Developer Resources 网站的文档页面中。
在 web 应用程序中用来向用户提供信息并能够使数据从终端用户流回服务器的页面。JSP pages 必须放置在 web 应用程序中以便可以在 IDE 中执行 JSP pages。
Servlet 是在 servlet 容器内执行的 Java 类,通常在 web 服务器内运行。Servlet 用于执行以下操作:
有关使用 NetBeans IDE 5.0 的更多信息,请参见以下参考资料:
要发送评论和建议、获得支持和随时获得关于 NetBeans IDE J2EE 开发特性的最新发展情况,请加入 nbj2ee@netbeans.org 邮件列表。有关 NetBeans IDE 中即将到来的 J2EE 开发特性的更多信息,请参见 j2ee.netbeans.org .