servlet基礎

1.1,servlet的基本結構html

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
  }
}

這是一個基本的servletservlet通常擴展自HttpServlet,依據數據發送方式的不一樣(GET或POST),覆蓋doGet或doPost方法,若是但願servlet對GET和POST採起一樣的行動,只須要讓doGet調用doPost便可,反之亦然。java

doGet和doPost都接受2個參數,HttpServletRequest和HttpServletResponse,經過HttpServletRequest能夠得到全部的輸入數據:表單數據,HTTP請求報頭,客戶主機名等。HttpServletResponse能夠指定輸出信息,如HTTP狀態碼和響應報頭,最重要的是,經過它能夠得到PrintWriter,用它將文檔內容發給用戶。數據庫

 

1.2,生成純文本的servlet瀏覽器

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

 public class HelloWorld extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {
    PrintWriter out = response.getWriter();
    out.println("Hello World");
  }
}

直接用out輸出文本形式的頁面服務器



1.3 生成HTML的servlet
1)告知瀏覽器,要生成HTMLcookie

2)修改println,輸出html格式的內容多線程

3)用形式語法驗證器檢查生成的hmtl(後面講述)併發

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

 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>Hello111</H1>\n" +
                "</BODY></HTML>");
  }
}

1.4 簡單的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>");
  }
}

1.5 理解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列表和點擊數寫入磁盤等收尾工做。


1.6 SingleThreadModel接口

一般狀況下,系統只生成servlet的單一實例,以後爲每一個用戶請求建立新的線程,這意味着,若是新的請求到來,而前面的請求還在執行,那麼可能會出現多個線程併發執行的狀況,所以doGet和doPost必須當心的同步對共享數據的訪問(注意doGet和doPost內部的局部變量並不擔憂這一點)。,原則上能夠這麼作:

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

阻止多線程訪問servlet,一般這不是一個好的解決方案。缺點:同步對servlet的訪問對性能形成極大影響。
下例試圖爲每一個user指定一個惟一的id,

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

 public class UserIDs extends HttpServlet {
 private int nextID = 0;
 public void doGet(HttpServletRequest request,
HttpServletResponse response)
 throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String title = "Your ID";
String docType =
 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +
 "Transitional//EN\">\n";
out.println(docType +
 "<HTML>\n" +
 "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n" +
 "<CENTER>\n" +
 "<BODY BGCOLOR=\"#FDF5E6\">\n" +
 "<H1>" + title + "</H1>\n");
 //關鍵代碼,在多請求狀況下並不能正常運行
 String id = "User-ID-" + nextID;
out.println("<H2>" + id + "</H2>");
nextID = nextID + 1;
out.println("</BODY></HTML>");
}
}

三種解決方案:

1,減小競爭 並不能徹底解決

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

2,使用SingleThreadModel,上面已說,不推薦
3,明確對代碼塊的同步訪問。推薦

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

相關文章
相關標籤/搜索