servlet基础

3.1,servlet的基本结构

1 import java.io.*;
2  import javax.servlet.*;
3  import javax.servlet.http.*;
4
5
6  public class ServletTemplate extends HttpServlet {
7 public void doGet(HttpServletRequest request,
8 HttpServletResponse response)
9 throws ServletException, IOException {
10
11 // Use "request" to read incoming HTTP headers
12 // (e.g., cookies) and query data from HTML forms.
13
14 // Use "response" to specify the HTTP response status
15 // code and headers (e.g., the content type, cookies).
16  
17 PrintWriter out = response.getWriter();
18 // Use "out" to send content to browser
19  
20 }
21 }

这是一个基本的servletservlet一般扩展自HttpServlet,依据数据发送方式的不同(GET或POST),覆盖doGet或doPost方法,如果希望servlet对GET和POST采取同样的行动,只需要让doGet调用doPost即可,反之亦然。

doGet和doPost都接受2个参数,HttpServletRequest和HttpServletResponse,通过HttpServletRequest可以获得所有的输入数据:表单数据,HTTP请求报头,客户主机名等。HttpServletResponse可以指定输出信息,如HTTP状态码和响应报头,最重要的是,通过它可以获得PrintWriter,用它将文档内容发给用户。




3.2,生成纯文本的servlet

1 import java.io.*;
2  import javax.servlet.*;
3  import javax.servlet.http.*;
4
5  public class HelloWorld extends HttpServlet {
6 public void doGet(HttpServletRequest request,
7 HttpServletResponse response)
8 throws ServletException, IOException {
9 PrintWriter out = response.getWriter();
10 out.println("Hello World");
11 }
12 }


直接用out输出文本形式的页面



3.3 生成HTML的servlet


1)告知浏览器,要生成HTML

2)修改println,输出html格式的内容

3)用形式语法验证器检查生成的hmtl(后面讲述)

1 import java.io.*;
2  import javax.servlet.*;
3  import javax.servlet.http.*;
4
5  public class HelloServlet extends HttpServlet {
6 public void doGet(HttpServletRequest request,
7 HttpServletResponse response)
8 throws ServletException, IOException {
9 response.setContentType("text/html");
10 PrintWriter out = response.getWriter();
11 String docType =
12 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
13 "Transitional//EN\">\n";
14 out.println(docType +
15 "<HTML>\n" +
16 "<HEAD><TITLE>Hello</TITLE></HEAD>\n" +
17 "<BODY BGCOLOR=\"#FDF5E6\">\n" +
18 "<H1>Hello111</H1>\n" +
19 "</BODY></HTML>");
20 }
21 }


3.5 简单的html构建工具

把html的DOCTYPE和HRAD部分放在一个使用工具中,避免每次重复

package coreservlets;

import javax.servlet.*;
import javax.servlet.http.*;


public class ServletUtilities {

//单独写在一个类里,以后直接引用
public static final String DOCTYPE =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
"Transitional//EN\">";

public static String headWithTitle(String title) {
return(DOCTYPE + "\n" +
"<HTML>\n" +
"<HEAD><TITLE>" + title + "</TITLE></HEAD>\n");
}

.........

}
package coreservlets;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;


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>");
}
}


3.6 理解servlet的生命周期

服务器只创建每个servlet的单一实例,每个用户请求都会引发新的线程,将用户请求交付给doGet或者doPost处理。

生命周期::首次创建servlet时,它的init对象得到调用,因此init是放置一次性设置代码的地方在这之后,针对每个用户请求都会创建一个线程,该线程调用前面创建的实例的service方法,多个并发请求一般会导致多个线程同时调用service(可以实现特殊的接口SingleThreadModel实现单线程运行),之后由service方法依据接收到的http请求类型,调用doGet,doPost或者其他doXxx方法最后如果服务器决定卸载某个servlet,调用servlet的destroy方法

1,service方法

服务器每次收到对servlet的请求,都会产生一个新的线程,调用service方法检查HTTP请求类型(GET,POST,PUT,DELETE等),从而调用相应的方法。

2,doGet,doPost,doXxx方法

servlet的主体。

3,init方法

可以在servlet开始时,完成初始化:

在一个servlet里写一个

public void init() thorws ServletException{

  //init code

}

来实现初始化。

4,destroy方法

服务器移除servlet之前可以调用destroy方法来完成一些工作,例如使得servlet有机会关闭数据库连接,停滞后台进程,将cookie列表和点击数写入磁盘等收尾工作。


3.7 SingleThreadModel接口

通常情况下,系统只生成servlet的单一实例,之后为每个用户请求创建新的线程,这意味着,如果新的请求到来,而前面的请求还在执行,那么可能会出现多个线程并发执行的情况,因此doGet和doPost必须小心的同步对共享数据的访问(注意doGet和doPost内部的局部变量并不担心这一点)。,原则上可以这么做:

1 public class YourServlet extends HttpServlet
2  implements SingleThreadModel {
3 ...
4 }

阻止多线程访问servlet,通常这不是一个好的解决方案。缺点:同步对servlet的访问对性能造成极大影响。


下例试图为每个user指定一个唯一的id,


1 import java.io.*;
2  import javax.servlet.*;
3  import javax.servlet.http.*;
4
5  public class UserIDs extends HttpServlet {
6  private int nextID = 0;
7  public void doGet(HttpServletRequest request,
8 HttpServletResponse response)
9  throws ServletException, IOException {
10 response.setContentType("text/html");
11 PrintWriter out = response.getWriter();
12 String title = "Your ID";
13 String docType =
14  "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
15  "Transitional//EN\">\n";
16 out.println(docType +
17  "<HTML>\n" +
18  "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" +
19  "<CENTER>\n" +
20  "<BODY BGCOLOR=\"#FDF5E6\">\n" +
21  "<H1>" + title + "</H1>\n");
22  //关键代码,在多请求情况下并不能正常运行
23  String id = "User-ID-" + nextID;
24 out.println("<H2>" + id + "</H2>");
25 nextID = nextID + 1;
26 out.println("</BODY></HTML>");
27 }
28 }



三种解决方案:

1,减少竞争 并不能完全解决

String id = "User-ID-" + nextID++;

2,使用SingleThreadModel,上面已说,不推荐


3,明确对代码块的同步访问。推荐

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



posted @ 2011-04-08 00:57  jinmengzhe  阅读(1010)  评论(0编辑  收藏  举报