web開發(fā)日記-servlet

servlet

Servlet(Server Applet),全稱Java Servlet,暫無中文譯文。是用Java編寫的服務(wù)器端程序。其主要功能在于交互式地瀏覽和修改數(shù)據(jù),生成動態(tài)Web內(nèi)容。狹義的Servlet是指Java語言實(shí)現(xiàn)的一個接口,廣義的Servlet是指任何實(shí)現(xiàn)了這個Servlet接口的類,一般情況下,人們將Servlet理解為后者。
Servlet運(yùn)行于支持Java的應(yīng)用服務(wù)器中。從原理上講,Servlet可以響應(yīng)任何類型的請求,但絕大多數(shù)情況下Servlet只用來擴(kuò)展基于HTTP協(xié)議的Web服務(wù)器。
最早支持Servlet標(biāo)準(zhǔn)的是JavaSoft的Java Web Server,此后,一些其它的基于Java的Web服務(wù)器開始支持標(biāo)準(zhǔn)的Servlet。

servlet入門小實(shí)例

src下創(chuàng)建com.webtest.servlet.HelloServlet.java

package com.webtest.servlet;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Created by elijahliu on 2017/2/19.
 */
public class HelloServlet extends javax.servlet.http.HttpServlet {
    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {

    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("==========init with parameter=============");
        super.init(config);
    }

    @Override
    public void init() throws ServletException {
        System.out.println("================init without parameter");
        super.init();
    }

    @Override
    public void destroy() {

        System.out.println("========destroy============");
        super.destroy();
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("=============service===============");
        PrintWriter pw = resp.getWriter();//這三行用于將字符輸出到瀏覽器,PrintWriter是一個字符輸出流
        pw.println("Hellowworld");
        pw.close();//關(guān)閉輸出流對象
    }

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {

    }
}

這里繼承了 httpservlet ,使用PrintWriter輸出流輸出到頁面。

相應(yīng)的修改web.xml配置入口url

<servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.webtest.servlet.HelloServlet</servlet-class><!--servelt-class用于連接完全限定名,也就是name對應(yīng)的類的路徑-->
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/Hello</url-pattern><!--servlet mapping 通過name與servlet相連接,然后通過下面的url-pattern,當(dāng)瀏覽器路徑是這個的時(shí)候,訪問這個路徑,就會調(diào)用對應(yīng)的servlet來處理-->
    </servlet-mapping>

servelt-class用于連接完全限定名,也就是name對應(yīng)的類的路徑
servlet mapping 通過name與servlet相連接,然后通過下面的url-pattern,當(dāng)瀏覽器路徑是這個的時(shí)候,訪問這個路徑,就會調(diào)用對應(yīng)的servlet來處理

servlet處理流程分析

servlet處理流程

處理流程:客戶端發(fā)送request請求,到Tomcat webserver服務(wù)器,然后http服務(wù)器再再servlet容器中創(chuàng)建運(yùn)行servlet,也就是說,在沒有訪問的請求發(fā)起時(shí),servlet是不創(chuàng)建對象的。servlet的通過requset response對象來處理數(shù)據(jù),結(jié)束后,可以再調(diào)用其他servlet,或最后直接將數(shù)據(jù)傳輸?shù)綖g覽器返回響應(yīng)。

servlet執(zhí)行流程

servlet執(zhí)行流程

在創(chuàng)建servlet實(shí)例時(shí),會調(diào)用init()方法來進(jìn)行初始化,初始化后,servlet才會處于服務(wù)狀態(tài)。整個servlet生命周期中,只能進(jìn)行一次初始化。
service()方法可以多次調(diào)用,這個請求次數(shù)有關(guān),用來處理客戶端的請求。
destroy()方法,在servlet不再使用時(shí),容器會調(diào)用destroy()方法進(jìn)行銷毀servlet實(shí)例。、

servlet編程實(shí)例(1)

實(shí)例流程

首先創(chuàng)建Login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>loginservlet</title>
</head>
<body>
<form action="<%=request.getContextPath()%>/LoginServlet" method="post">
    <input type="text" name="uname"/>
    <input type="password" name="upwd"/>
    <input type="submit" value="submit">

</form>

</body>
</html>

其中的<%=request.getContextPath()%>
request.getContextPath() 返回站點(diǎn)的根目錄
request.getRealpath("/")得到的是實(shí)際的物理路徑,也就是你的項(xiàng)目所在服務(wù)器中的路徑
request.getScheme() 等到的是協(xié)議名稱,默認(rèn)是http
request.getServerName() 得到的是在服務(wù)器的配置文件中配置的服務(wù)器名稱 比如:localhost .baidu.com 等等
request.getServerPort() 得到的是服務(wù)器的配置文件中配置的端口號 比如 8080等等

再創(chuàng)建LoginServlet

package com.webtest.servlet;

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

/**
 * Created by elijahliu on 2017/2/19.
 */
@WebServlet(name = "LoginServlet")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.service(req, resp);

        String username = req.getParameter("uname");
        String password = req.getParameter("upwd");

        System.out.println(username);
        System.out.println(password);


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

最后在web.xml中更改servlet的路徑配置

 <!--//loginservlet-->
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.webtest.servlet.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/LoginServlet</url-pattern>
    </servlet-mapping>

Servlet編程實(shí)例(2)

使用doGet doPost方法來實(shí)現(xiàn)登錄邏輯.

get和post

將service的業(yè)務(wù)邏輯放到doPost中,在doGet中調(diào)用doPost。降低代碼的重復(fù)性,更符合邏輯。

package com.webtest.servlet;

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

/**
 * Created by elijahliu on 2017/2/19.
 */
@WebServlet(name = "LoginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.service(req, resp);

        


    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("uname");
        String password = request.getParameter("upwd");

        System.out.println(username);
        System.out.println(password);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

servlet編程實(shí)例(3) 添加登錄后的處理流程

流程

建立success.jsp文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>success</title>
</head>
<body>
success
用戶<%=request.getParameter("uname")%><br />

密碼<%=request.getParameter("upwd")%><br />

<a href="LoginServlet.jsp">back to login</a>

</body>
</html>

建立error.jsp頁面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>error</title>
</head>
<body>
error happened
用戶<%=request.getParameter("uname")%><br/>

密碼<%=request.getParameter("upwd")%><br/>

<a href="LoginServlet.jsp">back to login</a>
</body>
</html>

更改LoginServlet文件,修改業(yè)務(wù)邏輯,重定向

package com.webtest.servlet;

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

/**
 * Created by elijahliu on 2017/2/19.
 */
@WebServlet(name = "LoginServlet")
public class LoginServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("uname");
        String password = request.getParameter("upwd");

        System.out.println(username);
        System.out.println(password);

        if (username.equals("elijah") && password.equals("123456")) {//若用戶密碼相同,則重定向到相應(yīng)的頁面
            response.sendRedirect(request.getContextPath() + "/Servletpage/success.jsp");
        } else {
            response.sendRedirect(request.getContextPath() + "/Servletpage/error.jsp");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

Servlet編程實(shí)例(4)

這里是用了請求轉(zhuǎn)發(fā),只進(jìn)行一個請求響應(yīng)流程。請求對象,傳入servlet后,servlet將reques response對象轉(zhuǎn)發(fā)到相應(yīng)的成功失敗頁面。

package com.webtest.servlet;

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

/**
 * Created by elijahliu on 2017/2/19.
 */
@WebServlet(name = "LoginServlet")
public class LoginServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("uname");
        String password = request.getParameter("upwd");

        System.out.println(username);
        System.out.println(password);

        String forward = null;
        if (username.equals("elijah") && password.equals("123456")) {//若用戶密碼相同,則重定向到相應(yīng)的頁面
            forward = "/Servletpage/success.jsp";
            RequestDispatcher rd = request.getRequestDispatcher(forward);//requestDispatcher是一個請求轉(zhuǎn)發(fā)對象
            //getRequestDispatcher獲取一個Dispatcher對象,forward為轉(zhuǎn)發(fā)的地址
            rd.forward(request, response);//執(zhí)行請求轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)當(dāng)前的額request 和response對象

            //請求重定向
            //response.sendRedirect(request.getContextPath() + "/Servletpage/success.jsp");
        } else {

            forward = "/Servletpage/error.jsp";
            RequestDispatcher rd = request.getRequestDispatcher(forward);//requestDispatcher是一個請求轉(zhuǎn)發(fā)對象
            //getRequestDispatcher獲取一個Dispatcher對象,forward為轉(zhuǎn)發(fā)的地址
            rd.forward(request, response);//執(zhí)行請求轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)當(dāng)前的額request 和response對象
            //請求重定向

            //response.sendRedirect(request.getContextPath() + "/Servletpage/error.jsp");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

requestDispatcher是一個請求轉(zhuǎn)發(fā)對象
getRequestDispatcher獲取一個Dispatcher對象,forward為轉(zhuǎn)發(fā)的地址

PS:需要注意一點(diǎn)的是,RequestDispatcher方法不能轉(zhuǎn)發(fā)到不同的應(yīng)用地址,如 轉(zhuǎn)發(fā)地址為 www.google.com這是不可以的。但是response.sendRedirect重定向方法是可以的。

Servlet編程實(shí)例(5)

添加了 JBDC 數(shù)據(jù)庫校驗(yàn),完成校驗(yàn)用戶的Service層的編寫

在DAO層添加實(shí)現(xiàn)獲取用戶的方法,返回結(jié)果集
UserDao.java

package com.webtest.dao;

import com.webtest.entity.User;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Created by elijahliu on 2017/2/18.
 */
public interface UserDao {
    public void save(Connection conn, User user) throws SQLException;
    public void update(Connection conn,Long id,User user) throws SQLException;

    public void delete(Connection conn, User user) throws SQLException;

    //需要編寫相應(yīng)的實(shí)現(xiàn),這是典型的面向接口的編程,接口只定義外觀和行為

    //獲取用戶信息
    public ResultSet get(Connection conn, User user)throws SQLException;

}

在UserDaoimpl中實(shí)現(xiàn)get方法

  @Override
    public ResultSet get(Connection conn, User user) throws SQLException {
        PreparedStatement ps = conn.prepareStatement("SELECT * FROM tbl_user WHERE name=? AND password=?");
        ps.setString(1, user.getName());
        ps.setString(2,user.getPassword());

        return ps.executeQuery();

    }

創(chuàng)建service層的包,com.webtest.service.

package com.webtest.service;

import com.webtest.dao.UserDao;
import com.webtest.dao.impl.UserDaoimpl;
import com.webtest.entity.User;
import com.webtest.util.ConnectionFactory;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Created by elijahliu on 2017/2/19.
 */
public class CheckuserService {
    private UserDao userDao= new UserDaoimpl();//上轉(zhuǎn)型建立一個持久層類
    public boolean check(User user){
        Connection conn = null;

        conn = ConnectionFactory.getInstance().makeConnection();//獲取一個連接工廠類的單例連接
        try {
            conn.setAutoCommit(false);//設(shè)置不自動提交

            ResultSet rs = userDao.get(conn, user);//獲取查詢結(jié)果集
            while (rs.next()) {//不為空,則存在,那么就返回true
                return true;
            }
        } catch (SQLException e) {
            try {
                conn.rollback();//錯誤發(fā)生則回滾
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return false;
    }
}

Servlet編程實(shí)例(6)

完成控制層的業(yè)務(wù)邏輯編寫。在com.webtest.servlet下創(chuàng)建CheckServlet.java
在這個servlet中調(diào)用service層的CheckServlet中的check()方法,完成用戶的校驗(yàn),與成功或失敗頁面的跳轉(zhuǎn)。在web.xml中,完成servlet的路徑配置。CheckServlet相當(dāng)于控制層。
CheckServlet.java

package com.webtest.servlet;

import com.webtest.entity.User;
import com.webtest.service.CheckuserService;

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

/**
 * Created by elijahliu on 2017/2/19.
 */
@WebServlet(name = "CheckServlet")
public class CheckServlet extends HttpServlet {

    CheckuserService cku = new CheckuserService();//創(chuàng)建service 業(yè)務(wù)邏輯對象
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String uname = request.getParameter("uname");
        String passwd = request.getParameter("upwd");

        RequestDispatcher rd = null;
        String forward = null;

        if (uname == null && passwd == null) {//如果用戶名或密碼為空,則轉(zhuǎn)發(fā)到錯誤頁面
            request.setAttribute("msg", "用戶名或密碼為空");
            rd = request.getRequestDispatcher("/Servletpage/error.jsp");
            rd.forward(request,response);
        } else {
            User user = new User();//創(chuàng)建用戶對象,使用service層的check方法 判斷是否存在該用戶
            user.setName(uname);
            user.setPassword(passwd);
            boolean bool = cku.check(user);//檢查用戶是否在數(shù)據(jù)庫中存在
            if (bool) {
                forward = "/Servletpage/success.jsp";

            }else{
                request.setAttribute("msg","用戶名或密碼錯誤,重新輸入");
                forward = "/Servletpage/error.jsp";
            }
            rd = request.getRequestDispatcher(forward);//根據(jù)查出是否存在該用戶,從而來確定執(zhí)行轉(zhuǎn)發(fā)的路徑
            rd.forward(request,response);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

web.xml


<!--checkservlet-->
    <servlet>
        <servlet-name>CheckServlet</servlet-name>
        <servlet-class>com.webtest.servlet.CheckServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CheckServlet</servlet-name>
        <url-pattern>/CheckServlet</url-pattern>
    </servlet-mapping>

Servlet編程實(shí)例(7)

完成了前端頁面的編寫,運(yùn)行了登錄實(shí)例程序。登陸頁面在finalservlet包中。
對頁面做一個最基礎(chǔ)的頁面美化。

創(chuàng)建finalservlet目錄 存放三個前端頁面

login.jsp

<%--
  Created by IntelliJ IDEA.
  User: elijahliu
  Date: 2017/2/19
  Time: 20:28
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login</title>
    <style type="text/css">
        body {
            color: #000;
            font-size: 14px;
            margin: 20px auto;

        }

    </style>
    <script type = "text/javascript">
        function check(form){
            if(document.forms.loginForm.uname.value == "") {
                alert("請輸入用戶名!");
                document.forms.loginForm.uname.focus();
                return false;
            }
            if(document.forms.loginForm.upwd.value == "") {
                alert("請輸入密碼!");
                document.forms.loginForm.upwd.focus();
                return false;
            }

        }
    </script>

</head>
<body>
<form action="<%=request.getContextPath()%>/CheckServlet" method="post" name="loginForm">
    <table border="1" cellpadding="0" cellpdding="5" bordercolor="silver" align="center">

        <tr>
            <td colspan="2" align="center" bgcolor="#E8E8E8">用戶登錄</td>
        </tr>
        <tr>
            <td>用戶名:</td>
            <td>
                <input type="text" name="uname"/>
            </td>
        </tr>
        <tr>
            <td>密碼:</td>
            <td>
                <input type="password" name="upwd"/>
            </td>
        </tr>
        <tr>
            <td colspan="2" align="center">
                <input type="submit" name="submit" onclick="return check(this);"/><%--添加了一個onclik方法,觸發(fā)時(shí)會調(diào)用check函數(shù)--%>
            </td>
        </tr>
    </table>

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

error.jsp

<%--
  Created by IntelliJ IDEA.
  User: elijahliu
  Date: 2017/2/19
  Time: 16:16
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>error</title>
    <style type="text/css">
        body {
            color: #000;
            font-size: 14px;
            margin: 20px auto;

        }
        #message{
            test-align:center;
        }

    </style>
</head>
<body>
<div id="message">
    error happened
    <%
        Object obj = request.getAttribute("msg");
        if (obj != null) {
            out.println(obj.toString());
        } else {
            out.println("none");
        }
    %>

    用戶<%=request.getParameter("uname")%>
<br/>

密碼<%=request.getParameter("upwd")%><br/>

<a href="<%=request.getContextPath()%>/finalservlet/Login.jsp">back to login</a>
</div>
</body>
</html>

success.jsp

<%--
  Created by IntelliJ IDEA.
  User: elijahliu
  Date: 2017/2/19
  Time: 16:14
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>success</title>
    <style type="text/css">
        body {
            color: #000;
            font-size: 14px;
            margin: 20px auto;

        }

        #message {
            test-align: center;
        }

    </style>
</head>
<body>
<div id="message">
    success
    用戶<%=request.getParameter("uname")%><br/>

    密碼<%=request.getParameter("upwd")%><br/>

    <a href="<%=request.getContextPath()%>/finalservlet/Login.jsp">back to login</a>

</div>
</body>
</html>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,688評論 19 139
  • 0 系列目錄# WEB請求處理 WEB請求處理一:瀏覽器請求發(fā)起處理 WEB請求處理二:Nginx請求反向代理 本...
    七寸知架構(gòu)閱讀 14,250評論 22 189
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,823評論 18 399
  • 這部分主要是與Java Web和Web Service相關(guān)的面試題。 96、闡述Servlet和CGI的區(qū)別? 答...
    雜貨鋪老板閱讀 1,505評論 0 10
  • 轉(zhuǎn)自陳明乾的博客,可能有一定更新。 轉(zhuǎn)原文聲明:原創(chuàng)作品,允許轉(zhuǎn)載,轉(zhuǎn)載時(shí)請務(wù)必以超鏈接形式標(biāo)明文章 原始出處 、...
    C86guli閱讀 4,885評論 6 72

友情鏈接更多精彩內(nèi)容