您的位置:首页 > 其它

3 servlet基础

2012-12-08 14:48 253 查看
1 servlet基本结构

清单3.1 给出一个基本的servlet,它处理GET请求。

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ServletTemplate extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Use "request" to read incoming HTTP headers
// (e.g., cookies) and query data from HTML forms.
// Use "response" to specify the HTTP response status
// code and headers (e.g., the content type, cookies).
PrintWriter out = response.getWriter();
// Use "out" to send content to browser.
}


DOgeT和doPost都接受两个参数:httpserletRequest 和HttpServletResponse.通过HttpSevletRequest,可以得到所有的输入数据; 通过这些方法可以找出诸如表单数据,HTTP请求报头 ,HTTPsevletReponse可以指定输出信息,比如HTTP状态代码和响应报头.由于DoGet和DoPost抛出两种异常

(servletException和IOException)所以必须在方法声名中包括它们.最后,还必须导入java.io ,javax.servlet javax.servlet.http中的类

2. 生成纯文本的servlet

3. 生成HTML的servlet

要生成HTML,需要在刚才介绍的过程中加入下面3步:

1. 告知浏览器,即将向它发送HTML.

2.修改println语句,构建合法的web页面

3.用形式语法验证器检查生成的HTML

第一步通过HttpServletResponse的setHeader方法来设置,

response.setcontentType("text/html");

清单3.3

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/** Simple servlet used to test server. */
public class HelloServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String docType =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
"Transitional//EN\">\n";
out.println(docType +
"<HTML>\n" +
"<HEAD><TITLE>Hello</TITLE></HEAD>\n" +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H1>Hello</H1>\n" +
"</BODY></HTML>");
}
}


4.servlet的打包

在将servlet放到了包中时,需要执行下面两个额外的步骤.

(1)将文件放到了与预定包名匹配的子目录中

(2)在类文件中插入包语句

清单3.4 coreservlets/HelloServlet2.java

package coreservlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/** Simple servlet for testing the use of packages. */
public class HelloServlet2 extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String docType =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
"Transitional//EN\">\n";
out.println(docType +
"<HTML>\n" +
"<HEAD><TITLE>Hello (2)</TITLE></HEAD>\n" +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H1>Hello (2)</H1>\n" +
"</BODY></HTML>");
}
}


5 简单的html构建工具

核心方法:

使用HTML验证器检查由你的servlet所生成的页面的语法.

清单3.5 coreservlets/ServletUtilities.java

package coreservlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/** Simple servlet for testing the use of packages. */
public class HelloServlet2 extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String docType =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
"Transitional//EN\">\n";
out.println(docType +
"<HTML>\n" +
"<HEAD><TITLE>Hello (2)</TITLE></HEAD>\n" +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H1>Hello (2)</H1>\n" +
"</BODY></HTML>");
}
}


清单3.6 coreservlets/HelloServlet3.java

package coreservlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/** Simple servlet for testing the use of packages
* and utilities from the same package.
*/
public class HelloServlet3 extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "Hello (3)";
out.println(ServletUtilities.headWithTitle(title) +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H1>" + title + "</H1>\n" +
"</BODY></HTML>");
}
}


编译完成后HelloServlet3.java之后,需要将这两个类文件移动到了服务器默认位置(.../web-inf/classes/

6 service 方法

如果让servlet中同地处理POST和GET请求,可用直接覆盖service方法.

doGet (or vice versa), as below.
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Servlet code
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}


6.2 DoGet\DoPost\Doxxxx

6.3 init方法

在servlet首次载入时,执行复杂的初始化任务进。但不想

每个请求都重复这些任务.init方法专为这种情况设计

init方法定义如下:

public void init() throws ServletException {
// Initialization code...
}


init方法执行两种类型的初始化,常规初始化,以及由初始化参数控制的初始化

1.常规初始化:首先,它构建一个由10个整数组成的数组。由于这些数学都 来源于复杂的计算

,我们不希望每次都重复这些计算。因此,DoGet查找init中计算得出的值 ,而

不是每次都生成它们.

清单3.7 coreservlets/LotteryNumbers.java(continued)

package coreservlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/** Example using servlet initialization and the
* getLastModified method.
*/
public class LotteryNumbers extends HttpServlet {
private long modTime;
private int[] numbers = new int[10];
/** The init method is called only when the servlet is first
* loaded, before the first request is processed.
*/
public void init() throws ServletException {
// Round to nearest second (i.e., 1000 milliseconds)
modTime = System.currentTimeMillis()/1000*1000;
for(int i=0; i<numbers.length; i++) {
numbers[i] = randomNum();
}
}
/** Return the list of numbers that init computed. */
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "Your Lottery Numbers";
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=\"#FDF5E6\">\n" +
"<H1 ALIGN=CENTER>" + title + "</H1>\n" +
"<B>Based upon extensive research of " +
"astro-illogical trends, psychic farces, " +
"and detailed statistical claptrap, " +
"we have chosen the " + numbers.length +
" best lottery numbers for you.</B>" +
"<OL>");
for(int i=0; i<numbers.length; i++) {
out.println(" <LI>" + numbers[i]);
}
out.println("</OL>" +
"</BODY></HTML>");
}
/** The standard service method compares this date against
* any date specified in the If-Modified-Since request header.
* If the getLastModified date is later or if there is no
* If-Modified-Since header, the doGet method is called
* normally. But if the getLastModified date is the same or
* earlier, the service method sends back a 304 (Not Modified)
* response and does <B>not</B> call doGet. The browser should
* use its cached version of the page in such a case.
*/
public long getLastModified(HttpServletRequest request) {
return(modTime);
}
// A random int from 0 to 99.
private int randomNum() {
return((int)(Math.random() * 100));
}
}


2.由初始化参数控制的初始化

要理解init参数的动机,你需要了解什么样的人可能希望对servlet的行为方式进行定制.

1)开发人员 2)最终用户 3)部署人员

开发人员通过改变代码改变servlet的行为.最终有户通过向html表单提供数据改变servlet

的行为.

由于servlet初始化参数所使用非常依赖于部署描述文件,所以我们将init参数的细节和例子

本书第二节介绍.在此仅给出简略的预览.

1.web.xml中的servlet元素可以为servlet赋予名称.

2.web.xml中的servlet-mapping元素可以为servlet指定一个URL.

3.通过向web.xml的servlet元素填加init-maram子元素,可以指定初始化参数的名称和值.

4.在servlet的init方法中,调用getServletConfig,获取ServletConfig的对象引用.

5.以init参数的名称为参数,调用servletConfig的getlnitParameter方法。返回值就是IN

init参数的值或NULL 的值。

7.SingleThreadModel 接口

通常,系统只生成servlet的单一实例后,为每个用户请求创建新的线程 。这意味着,如果新

的请求到来,而前面的请求依旧在执行,那么多个线程 会并发访问同一个servlet对象。因此

DoGET和Dopost方法必须小心地同步对字段和其他共享数据访问。

原则上,可以让servlet实现SingleTheadModel接口,阻止多线程访问

public class YourServlet extends HttpServlet
implements SingleThreadModel {
...
}


如果实现了这个接口,系统会保证不会有多个请求线程同时访问该servlet的单个实例

但这是不好的选择原因有二:

首先,如果你的servlet被频繁访问,那么同步对servlet的访问性造成极大的伤害(等待时

间。

其次,数据就不能正确共享。

警告:不要让高流量的servlet实现SingleTheadModel.

那么有什么可选方案吗?有三种。

1.减少竟争

2.使用singleThreadmodel:但这不是最终的解决方案。

3.明确地同步对代码的访问

synchronized(this) {
String id = "User-ID-" + nextID;
out.println("<H2>" + id + "</H2>");
nextID = nextID + 1;
}


这项技术告诉系统,一旦一个线程进入上面的代码块中,则直到了第一个

线程退出为止,不允许任何其他线程进入该代码。

8 servlet 调试

使用打印语句

使用IDE中的调试器

使用日志文件

使用apache log4j

编写独立的类。

预先做好数据缺失或异常的准备

检查HTML源码

单独检查请求数据

单独检查查响应数据

停止和重启服务器
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: