URL 查询字符串由CGI 程序位置,参数以及值构成。例如,下面的 URL 将使 CGI 程序 getBalance 在服务器端被调用。
http://www.webserverhost.com/cgi-bin/ getBalance.cgi?accountId=scott+smith&password=tiger
? 符号分隔程序与参数,= 关联参数名和参数值,& 符号分隔参数对,+ 符号代表空格。这里 accountId 为 scott smith。
GET 和 POST 方法的区别:GET 请求附加在URL字符串之后,如果web 浏览器有缓存,网页不会更新。POST方法将请求打包为请求文件的一部分,比POST更安全,且会每次触发CGI程序更新网页。如果有速度的要求,考虑用GET,如果有实时更新的要求,用POST。
CGI 的致命缺点:每当收到用户请求,web server 启动一个独立CGI 进程创建动态web应用程序处理请求并将响应发给web browser,方法看似简单,但进程数多了的时候,系统资源会迅速耗尽,导致服务器crash。Java Servlets 的出现就是为了解决CGI程序的性能问题。
Servlet 在 Servlet Container 或 Servlet Engine中以线程方式执行,Servlet container 在JVM 中以单一进程方式执行。两种常见的container有 TomCat 和 GlassFish,TomCat由Apache开发,GlassFish由Sun开发,GlassFish支持更多特征,但同时也占用更多系统资源。
用于处理HTTP请求的方法:
所有这些方法使用下列数字签名:
protected void doXxx(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException
除了GET和POST外,其他method不常用。虽然HttpServlet中的所有方法为非抽象方法,但是HttpServlet类被定义为抽象类,因此,要使用HttpServlet,必须用extends继承。
HttpServletRequest是ServletRequest接口的子接口,HttpServletResponse是ServletResponse接口的子接口, ServletRequest 和 ServletResponse 都定义了更为通用的接口。
Servlet与 Applet 相反, Applet 在客户端的浏览器上执行, 要写Applet程序,要定义一个类继承Applet类。同理,要写Servlet 程序,要定义一个类继承HttpServlet。Servlet 容器运行并通过定义在HttpServlet 类中的方法控制Servlet的执行。类似于Applet,Servlet也没有main方法。Servlet依赖于Servlet引擎调用方法,每一个Servlet都有类似下面的结构:
package chapter42; // The current chapter of the book: chapter 42
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class MyServlet extends HttpServlet {
/** Called by the servlet engine to initialize servlet */
public void init() throws ServletException { //... }
/** Process the HTTP Get request */
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { //... }
/** Process the HTTP Post request */
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { //... }
/** Called by the servlet engine to release resource */
public void destroy() { //... }
// Other methods if necessary
}
servlet engine 通过 init, doGet, doPost, destroy, 以及其他一些方法控制着 servlet。默认情况下 doGet, doPost 方法什么也不做,所以如果要处理GET和POST请求,就要重写doGet和doPost方法。用名为CurrentTime的Servlet显示当前时间:
package chapter42; // 示例, 当前章节
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class CurrentTime extends HttpServlet {
/** Process the HTTP Get request */
public void doGet(HttpServletRequest request HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html"); // Content type
PrintWriter out = response.getWriter();
out.println("The current time is " + new java.util.Date()); // Output to browser
out.close(); // Close stream
}
执行结果:
HttpServlet 类有一个doGet方法,当浏览器用GET方法发出请求给servlet时,doGet方法被调用。所以,servlet 类必须重写 doGet 方法以响应GET请求。
servlet 通过 HttpServletResponse 对象返回响应给浏览器。因为setContentType("text/html") 方法设置 MIME 类型为 "text/html",浏览器将以HTML显示响应。getWriter 方法返回 PrintWriter 对象,用于传送 HTML 给客户端。
如果浏览器使用了web 页缓存,那么使用GET方法不一定能得到当前时间,必须用POST以保证获取的时间是当前时间。
如果使用表单,可以一次性地提交所有数据
对应HTML code如下:
Student Registration Form
Student Registration Form
定义表单体,属性action指定web server上执行的服务器程序,method要么是get,要么是post
servlet 可以通过JDBC连接任何关系数据库,servlet连接数据库和java 应用程序或applet连接数据库方法相同。
web server使用HTTP协议,HTTP是无状态协议,将单一请求视为独立的请求,但是,有些request是相互关联的,例如:
request 1: 客户端填写注册数据并提交给 web server,web server 返回一个一页面让用户确认
request 2: 客户端确认提交的数据
以上两个 request 即以 session (会话) 的形式相互关联,session 可以定义为,在一个时间段内,某一客户端和服务器之间的相关联的一系列交互。
进行会话追踪的三种方法:
servlet 不限于只生成动态HTML文本并发送给浏览器,servlet 还可以发送图像,图像可存储于文件,或由程序创建。
Introduction to Java programming 9th edition chapter 42 Servlets