Servlet

在開始前冶伞,先把Tomcat的/lib/servlet-api.jar加入到項目依賴庫中割坠。

Servlet類繼承HttpServlet類麻汰,提供以下方法相應客戶端請求:

  • doGet() 響應客戶端的get請求
  • doPost() 響應客戶端的post請求
  • doPut 和 doDelete落追,不常用,不去了解

另外偿洁,HttpServlet還有兩個方法:

  • init() 創(chuàng)建Servlet實例時調用該方法
  • destroy() 銷毀Servlet實例時調用該方法
練習######

配合JSP編寫一個小頁面撒汉,收集表單數(shù)據后打印在瀏覽器上。

form.jsp代碼如下

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>

<html>

<head>
    <title>收集參數(shù)的表單頁</title>
</head>

<body>
<form id="form1" method="post" action="firstServlet">
用戶名:<br />
男<input type="radio" name="gander" value="男">
女<input type="radio" name="gander" value="女">
喜歡的顏色:<br />
紅<input type="checkbox" name="color" value="紅">
綠<input type="checkbox" name="color" value="綠">
紅配綠<input type="checkbox" name="color" value="紅配綠">
國籍:<br />
<select name="country">
    <option value="China">China</option>
    <option value="Russia">Russia</option>
    <option value="Vietname">Vietname</option>
</select><hr />
<input type="submit" value="SUBMIT">
<input type="reset" value="RESET">
</form>
</body>

</html>

FIrstServlet.java代碼如下

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintStream;

/**
 * Created by FanXiao on 2017/5/11.
 */

@WebServlet(name="firstServlet",urlPatterns={"/firstServlet"})
public class FirstServlet extends HttpServlet{
    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //設置解碼方式
        request.setCharacterEncoding("GBK");
        response.setContentType("text/html;charSet=GBK");
        //獲取name涕滋、gender睬辐、color和country等請求參數(shù)值
        String name = request.getParameter("name");
        String gender = request.getParameter("gender");
        String[] color = request.getParameterValues("color");
        String country = request.getParameter("country");
        //獲取out
        PrintStream out = new PrintStream((response.getOutputStream()));
        //輸出html頁面
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Servlet測試");
        out.println("</head>");
        out.println("name:" + name + "<hr/>");
        out.println("gender:" + gender + "<hr/>");
        out.println("colors");
        for (String c : color){
            out.println(c + " ");
        }
        out.println("<hr/>");
        out.println("country:" + country + "<hr/>");
        out.println("</body>");
        out.println("</html>");
    }
}
Servlet的兩種配置方式######

a) 在注釋中配置

@WebServlet(name="firstServlet",urlPatterns={"/firstServlet"})

b) 在web.xml中配置

<!-- 配置Servlet的名字 -->
<servlet>
  <!-- 相當于@WebServlet中的name參數(shù) -->
  <servlet_name>firstServlet</servlet-name>
  <!-- Servlet的實現(xiàn)類 -->
  <servlet-class>包名.FirstServlet</servlet-class>
</servlet>

<!-- 配置Servlet的URL -->
<servlet-mapping>
  <servlet-name>firstServlet</servlet-name>
  <!-- 相當于@WebServlet中的urlPatterns參數(shù) -->
  <url-pattern>/aaaa</url-pattern>
</servlet-mapping>

注意,方式b的生效優(yōu)先級高于方式a的宾肺。

load-on-start Servlet######

通常在收到客戶端請求后才會創(chuàng)建Servlet實例溯饵,但通過下面兩種配置方式,可以在應用啟動時立即創(chuàng)建Servlet實例

  • @WebServlet(loadOnStartup=1)
  • web.xml中在<servlet>標簽內添加<load-on-startup>1</load-on-startup>
    該參數(shù)接收一個整數(shù)值锨用,值越小加載順序越靠前

比如需要每秒在控制臺輸出當前系統(tǒng)時間丰刊,可以這樣寫

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

@WebServlet(loadOnStartup = 1)
public class Clock extends HttpServlet{
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(new Date());
            }
        },0,1000);
    }
}
Servlet的配置參數(shù)######

用以下兩種方式為Servlet配置額外的參數(shù)

  • @WebServlet中的Initparams參數(shù)
  @WebServlet (name="testServlet", urlPatterns={"testServlet"},
            initParams={
                    @WebInitParam(name="driver", value="com.mysql.jdbc,Driver"),
                    @WebInitParam(name="url", value="jdbc:mysql://localhost:3306/javaee"),
                    @WebInitParam(name="user", value="root"),
                    @WebInitParam(name="password", value="123456")})  ```
* web.xml文件的<servlet>標簽內添加<init-param>子標簽
```<servlet>
  <init-param>
    <param-name>driver</param-name>
    <param-value>com.mysql.jdbc.Driver</param-value>
  </init-param>
</servlet>```

當需要使用這些參數(shù)時,通過ServletConfig對象的getInitParameter(String name)方法獲取初始化參數(shù)

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

@WebServlet(name="testServlet", urlPatterns={"testServlet"},
initParams={
@WebInitParam(name="driver", value="com.mysql.jdbc.Driver"),
@WebInitParam(name="url", value="jdbc:mysql://localhost:3306/javaee"),
@WebInitParam(name="user", value="root"),
@WebInitParam(name="password", value="123456")})
public class TestServlet extends HttpServlet{
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
@Override
public void service(HttpServletRequest request, HttpServletResponse response){
try{
//獲取初始化參數(shù)
ServletConfig config = getServletConfig();
String driver = config.getInitParameter("driver");
String url = config.getInitParameter("url");
String user = config.getInitParameter("user");
String password = config.getInitParameter("password");

        //鏈接mysql
        Class.forName(driver);
        Connection conn = DriverManager.getConnection(url,user,password);
        Statement stmt = conn.createStatement();
        //執(zhí)行sql語句
        ResultSet rs = stmt.executeQuery("select * from table_1");
        //將查詢結果輸出到網頁
        response.setContentType("text/html;charSet=GBK");
        PrintStream out = new PrintStream((response.getOutputStream()));
        out.println("<html>");
        out.println("<head>");
        out.println("<title>訪問Servlet的初始化參數(shù)</titlet>");
        out.println("</head>");
        out.println("<body>");
        out.println("<table>");
        while(rs.next()){
            out.println("<tr>");
            out.println("<td>" + rs.getString(1) + "</td>");
            out.println("<td>" + rs.getString(2) + "</td>");
            out.println("</tr>");
        }
        out.println("</table>");
        out.println("</body>");
        out.println("</html>");
    }
    catch (Exception e){
        e.printStackTrace();
    }

}

}


######在MVC中黔酥,Servlet是Controller######
Servlet(Controller)類似于調度員藻三,將用戶請求分發(fā)給Model來處理洪橘,并調用JSP(View)展示結果跪者。
Model通常由JavaBean充當,所有業(yè)務邏輯熄求、數(shù)據訪問等工作都在Model中實現(xiàn)渣玲。

下面實現(xiàn)一個簡單的登陸驗證功能:

在登陸頁面輸入用戶名與密碼,login.jsp如下

<html>
<head>
<title>用戶登入</title>
</head>

<body>

<span>
<% if(request.getAttribute("err") != null){
out.println(request.getAttribut("err") + "</br>);
} %>
</span>

輸入用戶名與密碼
<form id="login" method="post" action="login">
用戶名:<input type="text" name="username"/>

密碼:<input type="password" name="pass"/>

<input type="submit" value="登入"/>

</form>
</body>
</html>

從login.jsp采集到用戶名和密碼后弟晚,調用JavaBean對比數(shù)據庫忘衍,根據結果不同轉發(fā)到不同的jsp。LoginServlet.java如下

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.ResultSet;

@WebServlet(name="login", urlPatterns = {"/login"},
initParams={
@WebInitParam(name="driver", value="com.mysql.jdbc,Driver"),
@WebInitParam(name="url", value="jdbc:mysql://localhost:3306/javaee"),
@WebInitParam(name="user", value="root"),
@WebInitParam(name="password", value="123456")})
public class LoginServlet extends HttpServlet{

@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String errMessage = "";
    //Servlet本身并不輸出響應到客戶端卿城,因此必須將請求轉發(fā)
    RequestDispatcher rd;
    //獲取請求參數(shù)
    String username = request.getParameter("uesrname");
    String pass = request.getParameter("pass");
    try{
        //獲取初始化參數(shù)
        ServletConfig config = getServletConfig();
        String driver = config.getInitParameter("driver");
        String url = config.getInitParameter("url");
        String user = config.getInitParameter("user");
        String password = config.getInitParameter("password");
        //調用JavaBean,查詢數(shù)據庫
        DbDao dd = new DbDao(driver, url, user, password);
        String sql = "select pass from user_table where name = ";
        ResultSet rs = dd.query(sql + username);
        //將結果轉發(fā)到不同的jsp
        if (rs.next()){
            if (rs.getString("pass").equals(pass)){
                //獲取session對象
                HttpSession session = request.getSession(true);
                //設置sessions屬性枚钓,跟蹤用戶會話狀態(tài)
                session.setAttribute("name",username);
                //獲取轉發(fā)對象
                rd = request.getRequestDispatcher("/welcom.jsp");
                //轉發(fā)請求
                rd.forward(request,response);
            }
            else{
                errMessage += "輸入的用戶名或密碼不正確";
            }
        }
        else{
            errMessage += "用戶名不存在";
        }
    }
    catch (Exception e){
        e.printStackTrace();
    }

    //如果出錯,轉發(fā)到重新登入
    if (errMessage != null && !errMessage.equals("")){
        rd = request.getRequestDispatcher("/login.jsp");
        request.setAttribute("err", errMessage);
        rd.forward(request,response);
    }
}

}

DbDao.java用于連接和操作數(shù)據庫

import java.sql.*;

/**

  • 封裝了數(shù)據庫的增刪改查功能
    */
    public class DbDao {
    private Connection conn;
    private String driver;
    private String url;
    private String username;
    private String pass;

    public DbDao(){

    }

    public DbDao(String driver, String url, String username, String pass){
    this.driver = driver;
    this.url = url;
    this.username = username;
    this.pass = pass;
    }

    public String getDriver() {
    return driver;
    }

    public void setDriver(String driver) {
    this.driver = driver;
    }

    public String getUrl() {
    return url;
    }

    public void setUrl(String url) {
    this.url = url;
    }

    public String getUsername() {
    return username;
    }

    public void setUsername(String username) {
    this.username = username;
    }

    public String getPass() {
    return pass;
    }

    public void setPass(String pass) {
    this.pass = pass;
    }

    //獲取數(shù)據庫連接
    public Connection getConnection() throws ClassNotFoundException, SQLException {
    if (conn == null){
    Class.forName(this.driver);
    conn = DriverManager.getConnection(url, username, pass);
    }
    return conn;
    }

    //插入
    public boolean insert(String sql, Object... args) throws SQLException, ClassNotFoundException {
    PreparedStatement pstmt = getConnection().prepareStatement(sql);
    for (int i = 0; i < args.length; i++ ){
    pstmt.setObject(i + 1, args[i]);
    }
    if (pstmt.executeUpdate() != 1){
    return false;
    }
    return true;
    }

    //查詢
    public ResultSet query(String sql, Object... args) throws SQLException, ClassNotFoundException {
    PreparedStatement pstmt = getConnection().prepareStatement(sql);
    for (int i = 0; i < args.length; i++ ){
    pstmt.setObject(i + 1, args[i]);
    }
    return pstmt.executeQuery();
    }

    //修改
    public void modify(String sql, Object... args) throws SQLException, ClassNotFoundException {
    PreparedStatement pstmt = getConnection().prepareStatement(sql);
    for (int i =0; i < args.length; i++ ){
    pstmt.setObject( i + 1, args[i]);
    }
    pstmt.executeUpdate();
    pstmt.close();
    }

    //關閉數(shù)據庫連接
    public void closeConn() throws SQLException {
    if (conn != null && !conn.isClosed()){
    conn.close();
    }
    }
    }

如果輸入的用戶名和密碼有錯誤瑟押,則轉發(fā)到login.jsp搀捷,并展示錯誤信息。
否則,登陸成功嫩舟,轉到welcom.jsp氢烘,如下

<html>
<head>
<title>登入成功</title>
</head>

<body>
<% out.print(request.getParameter("username") + ",歡迎回來家厌!"); %>
</body>
</html>

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末播玖,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子饭于,更是在濱河造成了極大的恐慌蜀踏,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掰吕,死亡現(xiàn)場離奇詭異脓斩,居然都是意外死亡,警方通過查閱死者的電腦和手機畴栖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門随静,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吗讶,你說我怎么就攤上這事燎猛。” “怎么了照皆?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵重绷,是天一觀的道長。 經常有香客問我膜毁,道長昭卓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任瘟滨,我火速辦了婚禮候醒,結果婚禮上,老公的妹妹穿的比我還像新娘杂瘸。我一直安慰自己倒淫,他們只是感情好,可當我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布败玉。 她就那樣靜靜地躺著敌土,像睡著了一般。 火紅的嫁衣襯著肌膚如雪运翼。 梳的紋絲不亂的頭發(fā)上返干,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天,我揣著相機與錄音血淌,去河邊找鬼矩欠。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的晚顷。 我是一名探鬼主播峰伙,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼该默!你這毒婦竟也來了瞳氓?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤栓袖,失蹤者是張志新(化名)和其女友劉穎匣摘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體裹刮,經...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡音榜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了捧弃。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赠叼。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖违霞,靈堂內的尸體忽然破棺而出嘴办,到底是詐尸還是另有隱情,我是刑警寧澤买鸽,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布涧郊,位于F島的核電站,受9級特大地震影響眼五,放射性物質發(fā)生泄漏妆艘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一看幼、第九天 我趴在偏房一處隱蔽的房頂上張望批旺。 院中可真熱鬧,春花似錦桌吃、人聲如沸朱沃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至搬卒,卻和暖如春瑟俭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背契邀。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工摆寄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓微饥,卻偏偏與公主長得像逗扒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子欠橘,可洞房花燭夜當晚...
    茶點故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內容