第3章
Java Web开发
3.1环境配置
3.1.1安装和配置Tomcat
1. 下载网址
从http://tomcat.apache.org下载Tomcat压缩包,这里下的版本是9.0.45,如图3.1所示。
2. 解压
将Tomcat压缩包解压缩到任意路径下,这里的解压缩路径为D:\apachetomcat9.0.41,该目录下的文件结构,如图3.2所示。
图3.1Tomcat下载网址
图3.2Tomcat解压后的
目录结构
(1) bin: 保存启动和关闭Tomcat的命令脚本。
(2) conf: 保存Tomcat的配置文件。
(3) lib: 保存Tomcat服务器的核心类库(JAR包)。
(4) logs: 保存Tomcat每次运行后产生的日志。
(5) temp: 保存Web应用运行过程中生成的临时文件。
(6) webapps: 部署Web应用。将Web应用复制在该路径下,Tomcat会将该应用自动部署在容器中。
(7) work: 保存Web应用运行过程中编译生成的class文件。该文件夹可以删除,但每次启动Tomcat服务器时,系统将再次建立该路径。
3. 配置JDK环境变量
配置环境变量JAVA_HOME,该变量指向JDK的安装路径,如图3.3所示,在第1章中已详细介绍过。
图3.3JAVA_HOME环境变量配置
4. 启动Tomcat
打开cmd窗口,进入(tomcat路径)\bin\目录下,运行startup.bat,如图3.4所示。
图3.4启动Tomcat
之后会弹出另一个窗口,提示Tomcat启动的日志信息,如图3.5所示。
图3.5Tomcat启动日志
5. 在浏览器中打开Tomcat服务首页
打开浏览器,输入http://localhost:8080或http://127.0.0.1:8080,这里8080是Tomcat默认使用的端口,如图3.6所示。
图3.6在浏览器中打开Tomcat服务首页
3.1.2运行第一个Web程序
在tomcat/webapps/ROOT路径下新建new.html,代码如下。
New
Hello World!
运行startup.bat后在浏览器中输入路径: http://localhost:8080/new.html,运行效果如图3.7所示。
图3.7第一个Web程序运行效果
3.2Servlet
Web应用程序访问过程就是请求和响应的过程,用户在浏览器中输入网址并按Enter键后,浏览器会向服务器发送一个HTTP请求,服务器接收到请求后会做相应的处理,并对用户做出恰当的响应。该访问过程是基于HTTP的,HTTP提供了GET、POST、HEAD、DELETE、TRACE、PUT和OPTIONS共7种访问方式,其中GET和POST两种访问方式是最常用的。
3.2.1HTTP简介
HTTP(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。HTTP基于TCP/IP通信协议来传递数据(HTML文件、图片文件、查询结果等)。
1. HTTP 工作原理
HTTP工作于客户端/服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端(即Web服务器)发送所有请求。Web服务器有Apache服务器、IIS(Internet Information Services)服务器等。Web服务器根据接收到的请求,向客户端发送响应信息。
HTTP默认端口号为80,但是也可以改为8080或者其他端口。
2. HTTP注意事项
1) HTTP是无连接
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接,采用这种方式可以节省传输时间。后来,KeepAlive被用来解决效率低的问题,KeepAlive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,KeepAlive 功能避免了建立或者重新建立连接。市场上的大部分 Web 服务器,包括IIS和Apache Tomcat,都支持HTTP KeepAlive。对于提供静态内容的网站来说,这个功能通常很有用。
2) HTTP是媒体独立的
这意味着,只要客户端和服务器知道如何处理数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIMEtype内容类型。
3) HTTP是无状态
HTTP是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样一方面可能导致每次连接传送的数据量增大,但另一方面,在服务器不需要先前信息时它的应答较快。
3.2.2Servlet简介
Servlet是Java Web应用程序的核心,它能够处理所有的请求和响应,Servlet中定义了很多方法,开发人员仅需要实现恰当的方法来响应用户请求即可,它并没有main方法,Tomcat服务器会自动调用Servlet的相应方法完成响应过程。
1. Servlet工作流程
①用户使用浏览器提交一个请求,该请求遵循HTTP; ②Tomcat接收到请求后,对请求进行解析,并封装成HttpServletRequest类型的request对象,可通过此对象获得HTTP头数据; ③Tomcat也会把输出流封装成HttpServletResponse类型的response对象,可通过此对象输出响应内容; ④Tomcat会将这两个对象作为输入参数调用Servlet的相应方法,如doGet(request, response)或doPost(request, response)方法等,我们就可以在调用的方法中实现程序的业务逻辑。Servlet的典型请求响应过程如图3.8所示。
图3.8Servlet请求响应过程
2. Servlet接口与实现类
Servlet接口位于包javax.servlet内,所有servlet都需要直接实现这一接口或者继承实现了该接口的类。该接口有两个实现类: GenericServlet和HttpServlet,这两个类均为抽象类。大多数情况下,开发人员只需要在这两个类的基础上进行扩展即可实现各自功能,其中最常用的是HttpServlet。HttpServlet类位于javax.servlet.http 包内,HttpServlet类中常用的方法如表3.1所示,其他方法可查阅J2EE文档进行学习。
表3.1HttpServlet类的常用方法
方法名方法描述
protected void doGet(HttpServletRequest req,HttpServletResponse resp)
throws ServletException, IOException当浏览器以GET方式访问时被触发
protected void doPost(HttpServletRequest req,
HttpServletResponseresp)
throws ServletException, IOException当浏览器以POST方式访问时被触发
protected long
getLastModified(HttpServletRequest req)返回HttpServletRequest最后修改的时间
3.2.3编写Servlet
HttpServlet类是Servlet接口的一个实现类,是由系统提供的。一般情况下,用户自定义编写的Servlet类只需要继承这个HttpServlet类,达到重用的目的,并覆盖其中的方法。一般只覆盖doGet方法和doPost方法,就能满足功能的实现。
1. 编写自定义Servlet类
开发人员只需要定义一个继承HttpServlet类的普通Java类,并覆盖doGet方法和doPost方法,一个能够处理请求和响应的Servlet类就定义好了,具体的代码如下。
public class UserServletextends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
System.out.println("UserServlet: doGet方法启动");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponseresp)throws ServletException, IOException {
System.out.println("UserServlet: doPost方法启动");
}
}
2. 配置标签
在定义好Servlet类文件之后,还要告知Web容器该类文件的位置,该配置信息必须放在web.xml中,具体的配置代码如下所示。
UserServlet
com.servlet.UserServlet
name
tom
encoding
utf-8
1
与分别表示开始标签和结束标签,中间内容则为Servlet的配置信息。
与标签是必须配置的,代表Servlet的名字,名字可以任意指定,但必须保证在web.xml文件中的唯一性。
与标签也是必须配置的,代表Servlet类名。由于类名较长,容易书写错误,因此在写好类名后,可以在按住Ctrl键的同时,单击类名,若能够跳转到类中,证明书写正确,否则书写错误。
与标签是可选的,用于配置初始化参数。该标签包含两个子标签,与标签用于指定参数名称,与标签用于指定参数值。在Servlet类中可以通过getServletConfig().getInitParameter(paramName)来获取初始化参数,标签可以配置多个。
与标签用于标记是否在容器启动时就加载这个servlet,当值为0或者大于0时,表示容器在应用启动时就加载这个servlet,当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载。正数的值越小,启动该servlet的优先级越高。
3. 配置标签
Web容器不仅需要知道类文件的位置,也需要知道此Servlet能够拦截或处理的路径。该配置信息必须放在web.xml中,具体的配置代码如下所示。
UserServlet
/UserServlet
/UserServlet.jsp
/UserServlet.php
与分别表示开始标签和结束标签,中间内容则为servletmapping的配置信息。
与标签是必须配置的,代表Servlet的名字,与前面配置信息中的一致。
与标签是必须配置的,代表此servlet能够处理的URL路径,一个标签可以配置多个标签。用户通过浏览器访问任何一个已经配置的中的URL,Tomcat都会自动跳转到对应的servlet内执行doXXX方法,XXX取决于用户的访问方式。若以Get方式访问,则执行doGet方法; 若以Post方式访问,则执行doPost方法。前面加上服务器域名和端口号即为该servlet的访问网址,本例中的servlet访问网址如下。
(1) http://localhost:8080/servlet/UserServlet。
(2) http://localhost:8080/servlet/UserServlet.jsp。
(3) http://localhost:8080/servlet/UserServlet.php。
访问这三个网址中的任意一个,都会跳转到UserServlet中,从而实现隐藏编程语言的目的,用户无法从URL判断程序代码是用Java还是PHP编写的。
一个完整的Servlet由Servlet类、配置和配置组成,三者缺一不可,在Servlet编写完成之后,就可以部署Web程序了。
4. 部署Web程序
部署完毕后启动Tomcat服务器,分别在浏览器输入配置好的三个URL,运行结果如图3.9所示。
图3.9Servlet运行结果
3.2.4请求与响应
用户通过浏览器向Tomcat服务器发送请求,Tomcat会根据配置信息分配给相应的Servlet的特定方法,一般方法的输入参数有两个,即HttpServletRequest和HttpServletResponse。
1. 请求(HttpServietRequest)
浏览器发送的请求被封装成为一个HttpServletRequest类型的对象,HttpServletRequest接口位于包javax.servlet.http内,通过该对象可以获取请求的地址、请求的参数、提交的数据、上传的文件、客户端的IP地址甚至是客户端操作系统等信息。HttpServletRequest中的常用方法如表3.2所示,其他方法可查阅Java EE文档进行学习。
表3.2HttpServletRequest的常用方法
方法名方 法 描 述
Object getAttribute(String name)获取名为name的属性值,若不存在则返回null
void setAttribute(String name, Object o)向request中存储属性name,值为对象o
void removeAttribute(String name)从request中移除属性name
String getParameter(String name)获取名为name的请求参数值,若不存在则返回null
String[] getParameterValues(String name)获取名为name的属性值数组,若不存在则返回null
RequestDispatcher getRequestDispatcher(String path)获取路径path对应的RequestDispatcher对象,用于向一个资源转发请求
void setCharacterEncoding(Stringenv)throws UnsupportedEncodingException设置request的编码格式
Cookie[] getCookies()获取客户端发送的Cookie数组
2. 响应(HttpServietResponse)
服务器对浏览器的响应被封装成为一个HttpServletResponse类型的对象,HttpServletResponse接口位于包javax.servlet.http内,HttpServletResponse中的常用方法如表3.3所示,其他方法可查阅Java EE文档进行学习。
表3.3HttpServletResponse的常用方法
方法名方 法 描 述
ServletOutputStream getOutputStream()throws
IOException获取ServletOutputStream对象,用于响应二进制数据
PrintWriter getWriter() throws IOException获取PrintWriter对象,用于响应字符数据
void sendRedirect(String location) throws IOException向客户端发送一个临时重定向响应消息
void setCharacterEncoding(String charset)设置response的编码格式
void setContentType(String type)设置response的内容类型
void addCookie(Cookie cookie)向response中添加Cookie对象
下面代码展示了在servlet中使用request获取客户端的信息,并通过response响应客户端的请求。
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String requestUrl = request.getRequestURL().toString(); //请求的URL地址
String requestUri = request.getRequestURI(); //请求的资源
String queryString = request.getQueryString();//请求的URL地址中的参数
String remoteAddr = request.getRemoteAddr(); //来访者的IP地址
String remoteHost = request.getRemoteHost();
int remotePort = request.getRemotePort();
String method = request.getMethod(); //请求URL时用的方法
String localAddr = request.getLocalAddr();//Web服务器的IP地址
String localName = request.getLocalName();//Web服务器的主机名
response.setHeader("content-type", "text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.write("获取到的客户机信息如下: ");
out.write("
");
out.write("请求的URL地址: "+requestUrl);
out.write("
");
out.write("请求的资源: "+requestUri);
out.write("
");
out.write("请求的URL地址中附带的参数: "+queryString);
out.write("
");
out.write("来访者的IP地址: "+remoteAddr);
out.write("
");
out.write("来访者的主机名: "+remoteHost);
out.write("
");
out.write("使用的端口号: "+remotePort);
out.write("
");
out.write("请求使用的方法: "+method);
out.write("
");
out.write("localAddr: "+localAddr);
out.write("
");
out.write("localName: "+localName);
}
在浏览器中输入http://127.0.0.1:8080/servlet/UserServlet.php?name=tom并按Enter键后,运行的结果如图3.10所示。
图3.10客户机信息展示页面
3.2.5Servlet生命周期
当服务器启动时,会检查web.xml中配置的Servlet的标签的值。若没有配置或者为负数时,那么服务器会在第一次使用时才初始化一个Servlet对象,否则会在服务器启动时就初始化一个Servlet对象,然后服务器会用这个Servlet对象处理所有客户端的请求,无论请求多少次,最多只存在一个Servlet实例。当多个客户端并发请求Servlet时,服务器会启动多个线程,分别执行该Servlet的service()方法。
Servlet生命周期包括三个阶段,分别执行三个方法,即init(ServletConfig conf)、service(ServletRequest request, ServletResponse response)和destroy()。
1. init()方法
当没有配置标签的值或者值为负数时,则第一次使用此Servlet时才执行此方法,否则服务器启动时就会执行此方法。除了提供了带参数的init(ServletConfig conf)方法外,HttpServlet实现类还提供了一个更简单的、不带参数的init()方法,该方法在Servlet生命周期中只会执行一次,因此可以将初始化资源的代码放在该函数中执行。
2. service()方法
HttpServlet实现类提供了service(HttpServletRequest request, HttpServletResponse response)方法。客户端每次请求Servlet时,都会运行service方法,service方法会根据访问类型决定需要执行的方法,如doGet方法、doPost方法、doPut方法。
3. destroy()方法
当容器关闭时,会先卸载所有的Servlet,卸载Servlet时就会执行destroy()方法,该方法在Servlet生命周期中只会执行一次,因此可以将销毁资源的代码放在该函数中执行。
下面通过继承HttpServlet类并覆盖生命周期的方法来体会Servlet的生命周期,具体代码如下。
package com.servlet;
public class UserServlet extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("init()方法开始执行");
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("service()方法开始执行");
super.service(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet()方法开始执行");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost()方法开始执行");
}
@Override
public void destroy() {
System.out.println("destroy()方法开始执行");
}
}
启动Tomcat服务器并在浏览器中访问http://127.0.0.1:8080/servlet/UserServlet.php后,关闭Tomcat服务器,在控制台会打印如图3.11所示的信息。
图3.11Servlet生命周期测试结果
3.2.6Servlet之间的跳转
Servlet之间可以相互跳转,通过跳转可以将一项任务进行分解。比如用一个Servlet,专门接收用户的请求和响应,获取用户提交的参数并为用户产生恰当的响应,然后跳转到另外一个Servlet专门处理业务逻辑。比如操作数据库,然后再跳转到一个Servlet,专门为用户显示处理结果。MVC(ModelViewControl)框架就是基于Servlet之间的跳转而实现的,MVC框架把程序分成了三个部分: 业务逻辑模块(Model)、视图模块(View)和控制模块(Control),其中视图模块可以通过JSP技术实现,JSP本质也是Servlet,控制模块可以使用Servlet实现。
1. 转向
转向(Forward)是通过RequestDispatcher类实现的,RequestDispatcher可通过request的getRequestDispatcher()方法获得,getRequestDispatcher()方法接收要跳转的路径,该路径必须以“/”开始,“/”表示Web程序的根目录。比如要跳转的Servlet为http://localhost:8080/servlet/UserServlet.php,则参数应该为“/UserServlet.php”。Forward允许跳转的路径包括JSP页面、Servlet,甚至是WEBINF目录下的文件。下面的代码实现从Servlet跳转到另一个Servlet。
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/UserServlet");
requestDispatcher.forward(req, resp);
转向属于服务器端跳转,跳转后,地址栏会显示跳转前的访问地址。因为跳转过程是在服务器内部完成的,客户端并不知道,因此转向对于客户端浏览器是透明的。
2. 重定向
重定向(Redirect)是通过response的sendRedirect()方法实现的。sendRedirect()方法接收要跳转的路径,如果该路径以“/”开始,则“/”表示Web站点的根目录。比如要跳转的Servlet为http://localhost:8080/servlet/UserServlet.php,则路径中的“/”表示http://localhost:8080/。下面的代码实现从Servlet重定向到另一个Servlet。
response.sendRedirect(request.getContextPath() + "/UserServlet");
重定向跳转属于客户端跳转,跳转后地址栏会显示跳转后的访问地址。因为代码执行到Redirect时,会先回到客户端浏览器,再利用新地址发送新的请求,因此跳转是在客户端进行的。
3.3小结
本章介绍了Java Web开发的知识,主要包括环境配置和Servlet,环境配置主要包括Tomcat安装与配置以及运行第一个Web程序。Servlet主要包括HTTP简介、Servlet简介、编写Servlet、请求与响应、Servlet生命周期以及Servlet之间的跳转等内容。
3.4习题
一、 单选题
1. 在Tomcat解压后的目录中,存放启动和关闭Tomcat的命令脚本的目录是()。
A. binB. libC. confD. log
2. HTTP提供的两种最常用的访问方式是()。
A. GET和PUTB. GET和POST
C. GET和DELETED. POST和PUT
3. HttpServletRequest类所属的包是()。
A. java.mathB. java.util
C. java.sqlD. javax.servlet.http
4. HTTP默认端口号为()。
A. 21B. 23C. 80D. 3306
5. 设置response的编码格式的方法是()。
A. getOutputStream()B. getWriter()
C. setCharacterEncodingD. addCookie()
二、 填空题
1. http://localhost:8080或http://127.0.0.1:8080,这里8080是Tomcat默认使用的。
2. Servlet生命周期包括三个阶段,分别执行三个方法,即init()、和。
3. MVC(ModelViewControl)框架把程序分成了三个部分: 业务逻辑模块(Model)、视图模块和控制模块。
4. Servlet的doPost()方法中的参数有request和response两个,它们的类型分别是HttpServletRequest和。
5. Servlet之间的跳转方式一般有两种,分别是转向(Forward)和。
三、 编程题
1. 编程实现图3.7所示的第一个Web程序,发布并运行。
2. 编写一个Servlet自定义类,配置并运行该Servlet。
3. 编写两个Servlet类AServlet和BServlet,并实现在AServlet中服务器端跳转(转向),打开BServlet的内容。
4. 编写两个Servlet类AServlet和BServlet,并实现在AServlet中客户端跳转(重定向),打开BServlet的内容。