Java Web应用中可以包含HTML文档、servlet、JSP和相关的Java类等。为了让Servlet容器能顺利地找到Java Web应用中的各个组件,Servlet规范规定,Java Web应用必须采用固定的目录结构,每种类型的组件在Web应用中都有固定的存放目录。Servlet规范还规定Java Web应用的配置信息放在WEB-INF/web.xml文件中,Servlet容器从该文件中读取配置信息。
Java Web应用的目录结构
假定开发一个名为helloapp的Java Web应用,目录结构如下:
目录 | 描述 |
---|---|
/helloapp | Web应用的根目录,所有JSP和HTML文件都存放于此目录或子目录下 |
/helloapp/WEB-INF | 存放Web应用的配置文件 web.xml |
/helloapp/WEB-INF/classes | 存放各种.class 文件,Servlet 类的.class文件也存放于此目录下 |
/helloapp/WEB-INF/lib | 可以存放 Web应用所需的各种JAR包 |
在运行时,Servlet容器优先加载classes目录下的类,再加载lib下的JAR文件中的类。因此,classes目录下的类覆盖JAR包中的同名类。另外,浏览器不能直接请求访问WEB-INF目录下的文件,这些文件只能被服务器端的组件访问。
helloapp 应用的完整目录结构如下图:
上图中有一个 src 目录,这是在开发helloapp应用阶段,开发人员自定义的目录,该目录用来存放所有的Java类源码。到了 Web 应用产品正式发布阶段,一般都不希望对外公开 Java 源代码,所以届时应该将 src 目录转移到其他地方。
创建HTML文件
在helloapp目录下加入login.htm文件,它包含一个名为“loginForm”的登录表单
login.htm
<html>
<head>
<title>helloapp</title>
</head>
<body>
<form name="loginForm" method="post" action="dispatcher">
<table>
<tr>
<td><div align="right">User Name:</div></td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td><div align="right">User Name:</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>
创建 Servlet 类
DispatcherServlet.java
package mypack;
import javax.servlet.*;
import java.io.IOException;
public class DispatcherServlet extends GenericServlet {
private String target = "/hello.jsp";
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// 读取表单中的用户名
String username = servletRequest.getParameter("username");
// 读取表单中的密码
String password = servletRequest.getParameter("password");
// 在 request 对象中添加 USER 属性
servletRequest.setAttribute("USER", username);
// 在 request 对象中添加 PASSWORD 属性
servletRequest.setAttribute("PASSWORD", password);
// 把请求转发给 hello.jsp
ServletContext servletContext = getServletContext();
RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher(target);
requestDispatcher.forward(servletRequest, servletResponse);
}
}
编译 Servlet类时,需要将 Servlet API 的 JAR 文件(servlet-api.jar)加入classpath中。servlet-api.jar 文件位于 <CATALINA_HOME>/lib 目录下。
在DOS下先转到 helloapp 目录下,然后用javac 命令编译 DispatcherServlet类:
F:\tomcat\helloapp>javac -sourcepath src -classpath c:\tomcat\lib\servlet-api.jar
-d WEB-INF\classes src\mypack\DispatcherServlet.java
以上命令编译 DispatcherServlet.java 文件,生成的 DispatcherServlet.class 文件的存放位置为 helloapp/WEB-INF/classes/mypack/DispatcherServlet.class。
java编译器编译java类时,编译出来的.class文件的存放路径与类的包名存在对应关系。例如DispatcherServlet.java类声明位于 mypack 包下,因此 DispatcherServlet.class 文件存放目录为helloapp/WEB-INF/classes/mypack。
创建JSP文件
hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>helloapp</title>
</head>
<body>
<b>Hello: <%= request.getAttribute("USER")%></b>
</body>
</html>
仅仅在一处使用了JSP语法:
<b>Hello: <%= request.getAttribute("USER")%></b>
该段代码作用是从request(即ServletRequest)对象中获得 USER 属性值,然后输出。
创建 web.xml文件
web.xml文件也称为 Java Web应用的发布描述符文件,Servlet容器在加载和启动 Java Web应用时会读取它的 web.xml 文件。
在web.xml文件中可以包含如下配置信息:
- Servlet的定义。
- Servlet的初始化参数
- Servlet以及JSP的映射
- 安全域配置参数
- welcome文件清单
- 资源引用
- 环境变量的定义
在WEB-INF目录中创建一个web.xml文件
web.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="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>mypack.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/dispatcher</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>login.htm</welcome-file>
</welcome-file-list>
</web-app>
以上 web.xml 文件的第一行指定了 XML 的版本和字符编码,接下来声明了一个<web-app>
元素,它是根元素。
<servlet>
元素的子元素
- servlet‐name : 指定servlet的名称, 该属性在web.xml中唯一。
- servlet‐class : 用于指定servlet完整类名(包括包名)。
- init‐param: 用于指定servlet的初始化参数,一个
<servlet>
中可以有多个<init-param>
在应用中可以通过 HttpServlet.getInitParameter 获取。 - load‐on‐startup: 用于控制在Web应用启动时,Servlet的加载顺序,优先加载数值小的Servlet。 值小于0或没有设定,web应用启动时,不加载该servlet,当第一次访问时加载。
- enabled: true , false 。 若为false ,表示Servlet不处理任何请求。
- url‐pattern: 用于指定URL表达式,一个 servlet‐mapping可以同时配置多个 url‐pattern。
元素为Web应用设置默认的主页,当客户端访问http://localhost:8080/helloapp时,服务端自动返回 login.htm 页面。