简介
Servlet是运行在web服务器或应用服务器上的程序,他是作为来自web浏览器或其他http客户端的请求和HTTP服务器上的数据库或应用程序之间的中间层。
使用Servlet可以手机来自网页表单的用户输入,呈现来自数据库或者其他源记录,还可以动态创建网页。
Servlet生命周期
Servlet生命周期可被定义为从创建到毁灭的整个过程。以下是Servlet遵循的过程:
servlet通过调用init()方法进行初始化
servlet通过service()方法来处理客户端的请求
servlet通过调用destroy()方法终止
最后,servlet是由JVM的垃圾回收器进行垃圾回收的
init()方法
init方法被设计成只调用一次。他在第一次创建Servlet时被调用,在后续每次用户请求时不在调用。因此,它是用于一次性初始化。
当用户调用一个Servlet时,就会创建一个Servlet实例,每个用户都会产生一个新的线程,适当的时候移交给doGet或doPost方法。init()方法简单地创建或加载一些数据,这些数据将被用于Servlet的整个生命周期。
init方法定义如下:
public void init() throws ServletException {
// 初始化代码...
}
service()方法
service()方法是执行实际任务的主要方法。Servlet容器调用service()方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
每次服务器接收到一个Servlet请求时,服务器会产生一个新的线程并调用服务。service()方法检查Http请求类型(GET、POST、PUT、DELETE等),并在适当的时候调用doGet、doPost、doPut、doDelete等方法。
下面是该方法的特征:
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException{
//......
}
service()方法由容器调用,service方法在适当的时候调用doGet等方法,所以,可以不用对service()方法做任何动作,只需要根据来自客户端的请求类型来重载doGet()或doPost()即可。
doGet()方法
GET请求来自于一个URL的正常请求,或者来自一个未指定METHOD的HTML表单,它由doGet()方法处理。
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Servlet 代码
}
doPost()方法
POST请求来自于一个特定指定了METHOD为POST的HTML表单,它由doPost()方法处理。
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Servlet 代码
}
destroy()方法
destroy()方法只会被调用一次,在Servlet生命周期结束时被调用。destroy()方法可以让Servlet关闭数据库连接、停止后台线程、把cookie列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
在调用destroy()方法后,servlet对象被标记为垃圾回收。destroy方法定义如下:
public void destroy() {
// 终止化代码...
}
Servlet实例
Servlet是服务Http请求并实现Servlet接口的Java类,Web应用程序开发人员通常编写Servlet来拓展HttpServlet,并直线Servlet接口的抽象类专门来处理Http请求。
Hello World示例代码
// 导入必需的 java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
// 扩展 HttpServlet 类
public class HelloWorld extends HttpServlet {
private String message;
public void init() throws ServletException
{
// 执行必需的初始化
message = "Hello World";
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// 设置响应内容类型
response.setContentType("text/HTML");
// 实际的逻辑是在这里
PrintWriter out = response.getWriter();
out.println("<h1>" + message + "</h1>");
}
public void destroy()
{
// 什么也不做
}
}
其次,需要一个web目录,如下所示(如果没有就自己创建一个)
在web.xml文件中创建以下条目:
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>HelloWorld</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorld</servlet-name>
<url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>
然后只需要在idea中配置并启动Tomcat,最后在浏览器的地址栏中输入http://localhost:8080/HelloWorld,会出现以下结果
Servlet表单数据
当需要传递一些信息,从浏览器到web服务器最后到后台程序时,浏览器提供了两种方法实现传递,分别为GET方法和POST方法。
GET方法
GET方法向页面请求发送已编码的用户信息。页面和已编码的信息中间用?字符分割,如下所示:
Http://www.test.com/hello?key1=value1&key2=value2
GET方法是默认的从浏览器向web服务传递信息的方法,它会产生一个很长的字符串,出现在浏览器的地址栏中。如果要向服务器传递的时密码或其他敏感信息时,不要使用GET方法。GET方法有大小限制:请求字符串中最多只能有1024个字符。
这些信息使用QUERY_STRING头传递,并可以通过QUERY_STRING环境变量访问,Servlet使用doGet()方法处理这种类型的请求。
POST方法
另一个向后台程序传递信息的比较可靠的方法是POST方法。POST方法打包信息的方式于GET方法基本相同,但是POST方法不是把信息作为URL中?字符后的文本字符串进行发送,而是把这些信息作为一个单独的消息。消息以标准输出的形式传到后台程序,可以解析和使用这些标准输出。Servlet使用doPost()方法处理这种类型的请求。
使用Servlet读取表单数据
Servlet处理表单数据,这些数据会根据不同的情况使用不同的方法自动解析:
getParameter():可以调用request.getParameter()方法获取表单参数的值。
getParameterValues():如果参数出现一次以上,则调用该方法,并返回多个值,例如复选框。
getParameterNames():如果想要得到请求中的所有参数的完整列表,则调用该方法。
使用URL的GET方法实例
例如:使用GET方法向HelloForm程序传递两个值
http://localhost:8080/HelloForm?first_name=ZARA&last_name=ALI
下面是处理Web浏览器输入的HelloForm.java Servlet程序。使用getParameter()方法,可以很容易的访问传递的信息:
// 导入必需的 java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
// 扩展 HttpServlet 类
public class HelloForm extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// 设置响应内容类型
response.setContentType("text/HTML");
PrintWriter out = response.getWriter();
String title = "使用 GET 方法读取表单数据";
String docType =
"<!doctype html public \"-//w3c//dtd html 4.0 " + "transitional//en\">\n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor=\"#f0f0f0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n" +
"<ul>\n" +
" <li><b>名字</b>:"
+ request.getParameter("first_name") + "\n" +
" <li><b>姓氏</b>:"
+ request.getParameter("last_name") + "\n" +
"</ul>\n" +
"</body></html>");
}
}
同时还要在web.xml中配置相应的信息
<servlet>
<servlet-name>HelloForm</servlet-name>
<servlet-class>HelloForm</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloForm</servlet-name>
<url-pattern>/HelloForm</url-pattern>
</servlet-mapping>
启动Tomcat服务器,再在浏览器的地址栏中输入
http://localhost:8080/HelloForm?first_name=ZARA&last_name=ALI。
使用表单的GET方法实例
定义hello.html来利用表单和提交按钮传递两个值,使用Servlet HelloForm来处理。
<html>
<body>
<form action="HelloForm" method="GET">
名字:<input type="text" name="first_name">
<br />
姓氏:<input type="text" name="last_name" />
<input type="submit" value="提交" />
</form>
</body>
</html>
访问http://localhost:8080/hello.html,会出现表单的实际输出。
输入姓名和姓氏,然后点击提交按钮,可以在本机上查看输出结果。
使用表单的POST方法实例
对上述Servlet做一些修改,使其可以处理GET和POST方法。
// 导入必需的 java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
// 扩展 HttpServlet 类
public class HelloForm extends HttpServlet {
// 处理 GET 方法请求的方法
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// 设置响应内容类型
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "Using GET Method to Read Form Data";
String docType =
"<!doctype html public \"-//w3c//dtd html 4.0 " + "transitional//en\">\n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor=\"#f0f0f0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n" +
"<ul>\n" +
" <li><b>名字</b>:"
+ request.getParameter("first_name") + "\n" +
" <li><b>姓氏</b>:"
+ request.getParameter("last_name") + "\n" +
"</ul>\n" +
"</body></html>");
}
// 处理 POST 方法请求的方法
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
编写带有POST方法的Hello.html,进行测试。
<html>
<body>
<form action="HelloForm" method="POST">
名字:<input type="text" name="first_name">
<br />
姓氏:<input type="text" name="last_name" />
<input type="submit" value="提交" />
</form>
</body>
</html>
同样输入姓名和姓氏,点击提交后,可在本机上查看输出信息。
将复选框数据传递到Servlet程序
当需要选择一个以上的选项时,则使用复选框。
下面CheckBox.html是一个带有两个复选框的表单。
<html>
<body>
<form action="CheckBox" method="POST" target="_blank">
<input type="checkbox" name="maths" checked="checked" /> 数学
<input type="checkbox" name="physics" /> 物理
<input type="checkbox" name="chemistry" checked="checked" /> 化学
<input type="submit" value="选择学科" />
</form>
</body>
</html>
下面是一个CheckBox.java Servlet程序,用来处理web浏览器给出的复选框输入。
// 导入必需的 java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
// 扩展 HttpServlet 类
public class CheckBox extends HttpServlet {
// 处理 GET 方法请求的方法
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// 设置响应内容类型
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "读取复选框数据";
String docType =
"<!doctype html public \"-//w3c//dtd html 4.0 " + "transitional//en\">\n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor=\"#f0f0f0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n" +
"<ul>\n" +
" <li><b>数学标识:</b>: "
+ request.getParameter("maths") + "\n" +
" <li><b>物理标识:</b>: "
+ request.getParameter("physics") + "\n" +
" <li><b>化学标识:</b>: "
+ request.getParameter("chemistry") + "\n" +
"</ul>\n" +
"</body></html>");
}
// 处理 POST 方法请求的方法
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
读取所有表单参数
使用HttpServletRequest的getParameterNames()方法读取所有可用的表单参数。该方法返回一个枚举,其中包含未指定顺序的参数名。
可以用标准方式循环枚举,使用hasMoreElements()方法来确定何时停止,使用nextElement()方法来获取每个参数的名称。
// 导入必需的 java 库
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
// 扩展 HttpServlet 类
public class ReadParams extends HttpServlet {
// 处理 GET 方法请求的方法
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// 设置响应内容类型
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "读取所有的表单数据";
String docType =
"<!doctype html public \"-//w3c//dtd html 4.0 " + "transitional//en\">\n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor=\"#f0f0f0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n" +
"<table width=\"100%\" border=\"1\" align=\"center\">\n" +
"<tr bgcolor=\"#949494\">\n" +
"<th>参数名称</th><th>参数值</th>\n"+
"</tr>\n");
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String)paramNames.nextElement();
out.print("<tr><td>" + paramName + "</td>\n<td>");
String[] paramValues =
request.getParameterValues(paramName);
// 读取单个值的数据
if (paramValues.length == 1) {
String paramValue = paramValues[0];
if (paramValue.length() == 0)
out.println("<i>No Value</i>");
else
out.println(paramValue);
} else {
// 读取多个值的数据
out.println("<ul>");
for(int i=0; i < paramValues.length; i++) { out.println("<li>" + paramValues[i]);
}
out.println("</ul>");
}
}
out.println("</tr>\n</table>\n</body></html>");
}
// 处理 POST 方法请求的方法
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
通过以下表单尝试上面的Servlet:
<html>
<body>
<form action="ReadParams" method="POST" target="_blank">
<input type="checkbox" name="maths" checked="checked" /> 数学
<input type="checkbox" name="physics" /> 物理
<input type="checkbox" name="chemistry" checked="checked" /> 化学
<input type="submit" value="选择学科" />
</form>
</body>
</html>