文章目录
第三章 第一个 Java Web 应用
Tomcat是服务Servlet规范的优秀Servelt容器。Java Web应用运行在Servlet容器中,Servlet容器能够动态的调用Java Web应用中的Servlet。
3.1 Java Web应用简介
Oracle公司的Servlet规范对Java Web应用做了如下定义:
“Java Web应用由一组Servlet/JSP、HTML文件、相关Java类,以及其他可以被绑定的资源个构成。它可以在各种供应商提供的符合Servlet规范的Servlet容器中运行。”
Java Web应用可以包含如下内容:
- Servelt组件:标准Servlet接口的实现类,运行在服务器端,包含了被Servlet容器动态调用的程序代码。
- JSP组件:包含Java程序代码的HTML文档。运行在服务器端,当客户端请求访问JSP文件时,Servlet容器先把它编译成Servlet类,然后动态调用它的程序代码。
- 相关的Java类:开发人员自定义的Web应用相关的Java类。
- 静态文档:存放在服务器端的文件系统中,如HTML文件、图片文件等。
- 客户端脚本程序:由客户端运行的程序,JavaScript时典型的客户端脚本程序。
- web.xml文件: Java Web应用的配置文件,该文件采用XML格式。该文件必须位于Web应用的WEN-INF子目录下。
3.2 创建Java Web应用
Servlet规范规定,Java Web应用必须采用固定的目录结构。还规定Java Web应用的配置信息存放在WEB-INF/web.xml文件中,Servlet容器从该文件中读取配置信息。
3.2.1 Java Web应用的目录结构
对于名为helloapp的一个JavaWeb应用。
目录 | 描述 |
---|---|
/helloapp | Web应能用的根目录,所有的JSP和HTLM文件都存放于此目录或子目录 |
/helloapp/WEB-INF | 存放web应用的配置文件web.xml |
/helloapp/WEB-INF/classes | 存放各种.class文件,servlet的.class文件也存放于此 |
/helloapp/WEB-INF/lib | 存放各种jar包 |
上图中,src目录是helloapp应用开发阶段开发人员自定义的目录,用于存放java类源文件。而到了应用发布阶段,一般是不会对外开放源代码的,所以会将src目录转移到其他地方。
helloapp应用包含如下组件:
- HTML组件:login.html。
- Servlet组件:DispacherServlet类。
- JSP组件:hello.jsp。
它们之间的关系:
3.2.2 创建HTML
<html>
<head>
<title>helloapp</title>
</head>
<body >
<form name="loginForm" method="POST" action="dispatcher"> //dispatcher为Servlet的URI
<table>
<tr>
<td><div align="right">User Name:</div></td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td><div align="right">Password:</div></td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td><input type="submit" name="submit" value="submit"></td>
<td><input type="reset" name="reset" value="reset"></td>
</tr>
</table>
</form>
</body>
</html>
3.2.3 创建Servlet类
package mypack;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class DispatcherServlet extends GenericServlet {
private String target = "/hello.jsp";
/** 响应客户请求*/
public void service(ServletRequest request,ServletResponse response)
throws ServletException, IOException {
//读取表单中的用户名
String username = request.getParameter("username");
//读取表单中的口令
String password = request.getParameter("password");
//在request对象中添加USER属性
request.setAttribute("USER", username);
//在request对象中添加PASSWORD属性
request.setAttribute("PASSWORD", password);
/*把请求转发给hello.jsp */
ServletContext context = getServletContext();
RequestDispatcher dispatcher =context.getRequestDispatcher(target);
dispatcher.forward(request, response);
}
}
创建好Servlet后需要在web.xml配置文件中配置,客户端才能访问Servlet。
3.2.4 创建JSP文件
<%@ taglib uri="/mytaglib" prefix="mm" %>
<html>
<head>
<title>helloapp</title>
</head>
<body>
<b><mm:hello/> : <%= request.getAttribute("USER") %></b>
</body>
</html>
3.2.5 创建web.xml文件
web.xml文件是Java Web应用的XML格式的配置文件。存放于WEB-INF子目录下。Servlet容器在加载和启动Java Web应用时会读取它的web.xml文件,从而获得当前Web应用的发布信息。
web.xml文件中可包含如下配置信息:
- Servlet的定义。
- Servlet的初始化参数。
- Servelt以及JSP的映射。
- 安全域配置参数。
- welcome文件清单。
- 资源引用。
- 环境变量的引用。
<?xml version="1.0" encoding="UTF-8"?> <!-- 指定xml的版本和字符编码-->
<web-app 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-app_4_0.xsd"
version="4.0" ><!--<web-app></web-app>根元素,所有关于Java Web应用的具体配置都加入到这个元素中-->
<servlet> <!--<servlet>元素,用于为servlet类定义一个名字-->
<servlet-name>dispatcher</servlet-name><!--定义servlet的名字-->
<servlet-class>mypack.DispatcherServlet</servlet-class><!--servlet的完整类名(包括包的名字)-->
<init-param><!--用于定义初始参数,可以有多个-->
<param-name></param-name><!--参数名-->
<param-value></param-value><!--参数值-->
</init-param>
<!--<load-on-startup>:指定当Servlet容器启动时,加载各个Servlet的顺序。当这
个值为0或为正数时,Servlet容器先加载数字小的,再一次加载数值大的。。如果没有
设定或这个值为负数,那么Servlet容器将在客户端首次访问这个Servlet时加载它。-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping> <!--用于为Servlet映射一个URL-->
<servlet-name>dispatcher</servlet-name><!--Servlet的名字,痛<servlet>标签中的相同-->
<url-pattern>/dispatcher</url-pattern><!--指定映射的路径-->
</servlet-mapping>
<welcome-file-list> <!--指定首页-->
<welcome-file>login.htm </welcome-file>
</welcome-file-list>
<jsp-config> //jsp配置
<taglib>
<taglib-uri>
/mytaglib
</taglib-uri>
<taglib-location>
chapter03/helloapp/WEB-INF/mytaglib.tld
</taglib-location>
</taglib>
</jsp-config>
</web-app>
3.3 在Tomcat中发布Java Web应用
3.3.1 Tomcat的目录结构
目录 | 描述 |
---|---|
/bin | 存放在Window平台以及Linux平台上启动和关闭Tomcat的脚本文件 |
/conf | 存放Tomcat服务器的各种配置文件,其中最重要的是server.xml |
/lib | 存放Tomcat服务器以及所有Web应用都可以访问的jar包 |
/logs | 存放Tomcat的日志文件 |
/webapps | 存放web应用文件 |
/work | Tomcat的工作目录,在Tomcat运行时吧生成的一些工作文件放于此目录下。如在默认情况下,Tocmat把编译JSP生成的Servlet类文件存放于此目录 |
以上lib目录用于存放JAR文件,Java Web应用下WEB-INF目录下也可以包含lib目录。区别在于:
- Tomcat的lib子目录存放的JAR文件不仅能被Tomcat访问,还能被所有在Tocmat中发布的Java Web应用访问。
- Java Web应用的lib目录只能被自己访问。
3.3.2 按照默认方式发布Java Web应用
直接把Java Web应用的所有文件复制到tomcat的webapps目录下。
3.3.3 Web组件的URL
Web应用的默认入口是web应用的根目录,如对helloapp应用,它的URL入口为“/hellapp”。
提示: 浏览器不能直接访问Web应用的WEB-INF目录文件,因此,如果处于安全的原因,不希望浏览器直接访问某个JSP,可以把它放到WEB-INF目录或其子目录下。在这种情况下,只有通过服务器端的组件才能访问该JSP文件,例如Servlet可以把请求转发个JSP文件。
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>mypack.DispatcherServlet</servlet-class>
<load-on-startup></load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/dispatcher</url-pattern>
</servlet-mapping>
对于以上配置,当浏览器需要请求访问mypack.DispatcherServlet时,其URL为:http:\localhost:8080\helloapp\dispacher。其步骤为:
- 参考web.xml文件,找到子元素的值为dispatcher的
<servlet-mapping>
元素。 - 根据
<servlet-mapping>
元素的<servlet-name>
的值确定其Servlet的名字,在这里为dispatcher。 - 根据serlet的名字找到对应的
<servlet>
元素。 - 读取
<servlet>
元素的子元素<servlet-class>
的值,确定其Servelt的类名,在这是mypack.DispacherServlet。 - 在WEB-INF/classes下找到对应的Servlet(DispacherServlet)。
提示:Tomcat在加载Web应用的时候就会把web.xml文件中的数据读取到内存中,因此,当Tomcat需要参考web.xml文件的时候,只需要从内存中读取就行了。
3.4 创建、配置和使用自定义JSP标签
创建、配置和使用hello标签的步骤:
(1)编写用于处理hello标签的类,名为HelloTag。
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
public class HelloTag extends TagSupport {
public int doEndTag() throws JspException{
try {
//打印字符串"hello"
pageContext.getOut().print("hello");
}catch (Exception e){
e.printStackTrace();
}
return EVAL_PAGE;
}
}
(2)创建一个TLD(Tag Library Descriptor,标签库描述符)文件。
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.1</tlib-version>
<jsp-version>2.1</jsp-version>
<short-name>mytaglib</short-name>
<uri>/mytaglib</uri>
<tag>
<name>hello</name> //标签名
<tag-class>com.whw.HelloTag</tag-class> //标签类
<body-content>empty</body-content> //标签正文
<description>Just Says Hello</description>//描述
</tag>
</taglib>
说明:Servlet规范规定,TLD文件在Web应用中必须存放在WEB-INF目录或其子目录下,但不放在WEB-INF/lib或WEB-INF/classes目录下。
(3)在web.xml中配置<taglib>
标签
<web-app 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-app_4_0.xsd"
version="4.0" >
<jsp-config>
<taglib>
<taglib-uri>/mytaglib</taglib-uri><!--指定标签库的URI-->
<!--用于设置标签描述文件(TLD)的存放路径。-->
<taglib-location>
/WEB-INF/mytaglib.tld
</taglib-location>
</taglib>
</jsp-config>
</web-app>
(4)在hello.jsp中使用hello标签
<%@taglib uri="/mytaglib" prefix="mm"%> <!--引用mytaglib标签库-->
<html>
<body>
<h2>Hello World!</h2>
</body>
<!--<mm:hello/>使用hello标签-->
<b><mm:hello/>:world</b>
</html>
当客户请求访问hello.jsp时,servlet处理<mm:hello>
标签的步骤如下:
<mm:hello>
前缀为mm,与taglib指令匹配
<%@ taglib uri="/mytaglib" prefix="mm"%>
由此得知标签来自于UR为/mytaglib的标签库。
- 根据URI找到web.xml文件中的taglib
<taglib>
<taglib-uri>/mytaglib</taglib-uri><!--指定标签库的URI-->
<!--用于设置标签描述文件(TLD)的存放路径。-->
<taglib-location>
/WEB-INF/mytaglib.tld
</taglib-location>
</taglib>
由此得知URI为“/mytaglib”的标签库为WEB-INF/mytaglib.tld。
- 在WEB-INF/mytaglib.tld文件中找到名为hello的标签的定义。
<tag>
<name>hello</name>
<tag-class>mypack.HelloTag</tag-class>
<body-content>empty</body-content>
<description>Just Says Hello</description>
</tag>
根据 <tag-class>com.whw.HelloTag</tag-class>
德奥heloo标签的处理类为mypack.HelloTag。就会加载它的class文件,遇到结束标签时,就会调用doEngTag()方法。