3 servlet基础

    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源码

                      单独检查请求数据

                      单独检查查响应数据

                      停止和重启服务器

 

                      

                     
                

    

                                                           

 

                                               

                                              

 

 

 

 

 

 

 

 

 

 

posted @ 2012-12-08 14:48  elite_2012  阅读(177)  评论(0编辑  收藏  举报