知道了Servlet的概念和功能后,先来了解Servlet的体系
对于上图做了三种标志,椭圆标志是最常用的,六边形标志的是不常用但很重要,方形标志的作为了解。
1、先从总接口Serlvet介绍:
Servlet的定义之前已经介绍,现在主要看看Servlet中的方法。这边介绍了生命周期的方法:
init()方法:用于初始化一些配置参数或是初始参数;
service()方法:处理客户请求
destroy()方法:销毁Servlet
这三个方法按照顺序构成了一个Servlet的生命周期。再介绍一个比较重要的方法getServletConfig():返回ServletConfig对象,包含了Servlet的初始化信息、配置信息。
2、GenericServlet抽象类
总结下:
1、GenericServlet抽象类为Servlet接口提供了通用实现,与任何网 络应用层协议无关。
2、编写Web的HTTPservlet继承HttpServlet即可。
3、HTTPServlet 抽象类
总结下:
(1)、HttpServlet 类是GenericServlet的子类,为Servlet接口提供了与HTTP协议相关的通用实现。
(2)、在开发javaweb应用时,自定义的Servlet类一般都扩展HttpServlet类。
(3)、不需要重写service,service会判断HTTP请求方式然后让相应doXXX方法处理。
4、ServletRequest接口
总结为:
(1)、ServletRequest封装了来自客户请求信息。
(2)、servlet容器(简单理解为tomcat)创建ServletRequest对象。
(3)、若是通过Http协议发送的请求,可用HttpServletRequest对象。
5、HttpServletRequest接口
HttpServletRequest对象更多还是作为参数传递给相应的方法。
说了这么多个接口,先做个测试:在网页输出有关Http请求方法的Servlet,定义一个RequestInfoServlet。
运行环境:JDK1.7 Tomcat7.x
开发环境:myeclipse10.7
新建一个web项目
有两个地方需要注意,一个是自己定义的Servlet类的位置,另一个是在WebRoot/WEB-INF/lib路径下web.xml文件位置,对于初学者先提倡用web.xml配置Servlet相关信息。
RequestInfoServlet的具体代码如下:
package com.java.web.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RequestInfoServlet extends HttpServlet {
private static final long serialVersionUID = 4542092585457779011L;
@SuppressWarnings("rawtypes")
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 设置HTTP响应的正文的数据类型
resp.setContentType("text/html;charset=UTF-8");
/* 输出HTML文档 */
PrintWriter out = resp.getWriter(); out.println("<html><head><title>RequestInfo</TITLE></head>");
out.println("<body>");
// 打印服务器端的IP地址
out.println("<br>LocalAddr: " + req.getLocalAddr());
// 打印服务器端的主机名
out.println("<br>LocalName: " + req.getLocalName());
// 打印服务器端的FTP端口号
out.println("<br>LocalPort: " + req.getLocalPort());
// 打印客户端与服务器端通信所用的协议的名称及版本号
out.println("<br>Protocol: " + req.getProtocol());
// 打印客户端的IP地址
out.println("<br>RemoteAddr: " + req.getRemoteAddr());
// 打印客户端的主机名
out.println("<br>RemoteHost: " + req.getRemoteHost());
// 打印客户端的FTP端口号
out.println("<br>RemotePort: " + req.getRemotePort());
// 打印HTTP请求方式
out.println("<br>Method: " + req.getMethod());
// 打印HTTP请求中的URI
out.println("<br>URI: " + req.getRequestURI());
// 打印客户端所请求访问的Web应用的URL入口
out.println("<br>ContextPath: " + req.getContextPath());
// 打印HTTP请求中的查询字符串
out.println("<br>QueryString: " + req.getQueryString());
/** 打印HTTP请求头 */
out.println("<br>***打印HTTP请求头***");
Enumeration eu = req.getHeaderNames();
while (eu.hasMoreElements()) {
String headerName = (String) eu.nextElement();
out.println("<br>" + headerName + ": " + req.getHeader(headerName));
}
out.println("<br>***打印HTTP请求头结束***<br>");
// 打印请求参数username
out.println("<br>username: " + req.getParameter("username"));
out.println("</body></html>");
// 关闭输出流
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
简单分析一下这个RequestInfoServlet
这是一个自定义的继承HttpServlet的Servlet,我们不需要继承GenericServlet,因为GenericServlet是与网络协议无关的通用接口,
而我们的Tomcat服务器是基于Http协议进行响应的服务器,所以只需继承GenericServlet抽象类的子类HttpServlet即可。
当我们定义完一个Servlet后,需要一般需要重写doPost()方法,doGet()方法。 因为来自客户端的请求方式几乎都是post或是get,所以我们需要重写与它们相关的处理方法。
从该类名称我们也能推测出这个类应该是与Http响应(response)有关,HttpServletRespose主要提供一些放回与Http协议有关的响应结果的方法,
本例子的MIME类型是html类型,通过HttpServletResponse对象的getWriter方法(返回一个字符流)向浏览器返回一个Html页面。
本例子主要在浏览器显示HttpServletRequest的一些方法的相关信息,其中有Http请求头的相关信息,与之对应的Http响应,这边不多做介绍,有兴趣百度都能找到详细的解释。
写完自定义的Servlet后,还有一项工作需要完成。我们是通过过在浏览器输入网址向tomcat服务器发送请求,那我们的请求URL如何能跳转到指定的Servlet呢?这时就需要提起过的配置web.xml文件。
简单分析下:两个住标签、两者是映射关系。就举个当前的例子来解释:
当前例子若想要访问到RequestInfo Servlet,它的URL得是:
http://localhost:8080/Servlet16_10_3/RequestInfoServlet
而URL路径由两部分组成:上下文路径(http://localhost:8080/Servlet16_10_3)+映射路径(/RequestInfoServlet)。
映射过程:
(1)浏览器通过URL向tomcat发送请求
(2)Tomcat接收请求,分析请求中URL信息,去掉上下文路径,找到映射路径
(3)根据映射路径找到标签的子标签中RequestInfoServlet(这个名称是可随意,但必须和的子标签中的名称一致),此时会自动寻找在子标签中是否有与之相同名称,若是有则将映射到子标签中的Serlvet。
至此RequestInfoServlet算是完成,将该项目部署到tomcat服务器,然后启动服务器,打开浏览器输入:
http://localhost:8080/Servlet16_10_3/RequestInfoServlet?Username=zhangsan
测试结果:
这边有个小知识点:QueringString(查询字符串)。URL?username=zhangsan,在?符号后面username就是请求参数,它将username=zhangsan 通过get请求方式发送到服务器上,由Servlet中的HttpServletRequest对象的getParameter(“username”)方法获取。