web开发日记-servlet

servlet

Servlet(Server Applet),全称Java Servlet,暂无中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。
Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
最早支持Servlet标准的是JavaSoft的Java Web Server,此后,一些其它的基于Java的Web服务器开始支持标准的Servlet。

servlet入门小实例

src下创建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();//关闭输出流对象
    }

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

    }
}

这里继承了 httpservlet ,使用PrintWriter输出流输出到页面。

相应的修改web.xml配置入口url

<servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.webtest.servlet.HelloServlet</servlet-class><!--servelt-class用于连接完全限定名,也就是name对应的类的路径-->
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/Hello</url-pattern><!--servlet mapping 通过name与servlet相连接,然后通过下面的url-pattern,当浏览器路径是这个的时候,访问这个路径,就会调用对应的servlet来处理-->
    </servlet-mapping>

servelt-class用于连接完全限定名,也就是name对应的类的路径
servlet mapping 通过name与servlet相连接,然后通过下面的url-pattern,当浏览器路径是这个的时候,访问这个路径,就会调用对应的servlet来处理

servlet处理流程分析

servlet处理流程

处理流程:客户端发送request请求,到Tomcat webserver服务器,然后http服务器再再servlet容器中创建运行servlet,也就是说,在没有访问的请求发起时,servlet是不创建对象的。servlet的通过requset response对象来处理数据,结束后,可以再调用其他servlet,或最后直接将数据传输到浏览器返回响应。

servlet执行流程

servlet执行流程

在创建servlet实例时,会调用init()方法来进行初始化,初始化后,servlet才会处于服务状态。整个servlet生命周期中,只能进行一次初始化。
service()方法可以多次调用,这个请求次数有关,用来处理客户端的请求。
destroy()方法,在servlet不再使用时,容器会调用destroy()方法进行销毁servlet实例。、

servlet编程实例(1)

实例流程

首先创建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() 返回站点的根目录
request.getRealpath("/")得到的是实际的物理路径,也就是你的项目所在服务器中的路径
request.getScheme() 等到的是协议名称,默认是http
request.getServerName() 得到的是在服务器的配置文件中配置的服务器名称 比如:localhost .baidu.com 等等
request.getServerPort() 得到的是服务器的配置文件中配置的端口号 比如 8080等等

再创建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编程实例(2)

使用doGet doPost方法来实现登录逻辑.

get和post

将service的业务逻辑放到doPost中,在doGet中调用doPost。降低代码的重复性,更符合逻辑。

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编程实例(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文件,修改业务逻辑,重定向

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")) {//若用户密码相同,则重定向到相应的页面
            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编程实例(4)

这里是用了请求转发,只进行一个请求响应流程。请求对象,传入servlet后,servlet将reques response对象转发到相应的成功失败页面。

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")) {//若用户密码相同,则重定向到相应的页面
            forward = "/Servletpage/success.jsp";
            RequestDispatcher rd = request.getRequestDispatcher(forward);//requestDispatcher是一个请求转发对象
            //getRequestDispatcher获取一个Dispatcher对象,forward为转发的地址
            rd.forward(request, response);//执行请求转发,转发当前的额request 和response对象

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

            forward = "/Servletpage/error.jsp";
            RequestDispatcher rd = request.getRequestDispatcher(forward);//requestDispatcher是一个请求转发对象
            //getRequestDispatcher获取一个Dispatcher对象,forward为转发的地址
            rd.forward(request, response);//执行请求转发,转发当前的额request 和response对象
            //请求重定向

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

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

requestDispatcher是一个请求转发对象
getRequestDispatcher获取一个Dispatcher对象,forward为转发的地址

PS:需要注意一点的是,RequestDispatcher方法不能转发到不同的应用地址,如 转发地址为 www.google.com这是不可以的。但是response.sendRedirect重定向方法是可以的。

Servlet编程实例(5)

添加了 JBDC 数据库校验,完成校验用户的Service层的编写

在DAO层添加实现获取用户的方法,返回结果集
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;

    //需要编写相应的实现,这是典型的面向接口的编程,接口只定义外观和行为

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

}

在UserDaoimpl中实现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();

    }

创建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();//上转型建立一个持久层类
    public boolean check(User user){
        Connection conn = null;

        conn = ConnectionFactory.getInstance().makeConnection();//获取一个连接工厂类的单例连接
        try {
            conn.setAutoCommit(false);//设置不自动提交

            ResultSet rs = userDao.get(conn, user);//获取查询结果集
            while (rs.next()) {//不为空,则存在,那么就返回true
                return true;
            }
        } catch (SQLException e) {
            try {
                conn.rollback();//错误发生则回滚
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return false;
    }
}

Servlet编程实例(6)

完成控制层的业务逻辑编写。在com.webtest.servlet下创建CheckServlet.java
在这个servlet中调用service层的CheckServlet中的check()方法,完成用户的校验,与成功或失败页面的跳转。在web.xml中,完成servlet的路径配置。CheckServlet相当于控制层。
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();//创建service 业务逻辑对象
    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) {//如果用户名或密码为空,则转发到错误页面
            request.setAttribute("msg", "用户名或密码为空");
            rd = request.getRequestDispatcher("/Servletpage/error.jsp");
            rd.forward(request,response);
        } else {
            User user = new User();//创建用户对象,使用service层的check方法 判断是否存在该用户
            user.setName(uname);
            user.setPassword(passwd);
            boolean bool = cku.check(user);//检查用户是否在数据库中存在
            if (bool) {
                forward = "/Servletpage/success.jsp";

            }else{
                request.setAttribute("msg","用户名或密码错误,重新输入");
                forward = "/Servletpage/error.jsp";
            }
            rd = request.getRequestDispatcher(forward);//根据查出是否存在该用户,从而来确定执行转发的路径
            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编程实例(7)

完成了前端页面的编写,运行了登录实例程序。登陆页面在finalservlet包中。
对页面做一个最基础的页面美化。

创建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方法,触发时会调用check函数--%>
            </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>

最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,644评论 18 139
  • 0 系列目录# WEB请求处理 WEB请求处理一:浏览器请求发起处理 WEB请求处理二:Nginx请求反向代理 本...
    七寸知架构阅读 13,933评论 22 190
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,605评论 18 399
  • 这部分主要是与Java Web和Web Service相关的面试题。 96、阐述Servlet和CGI的区别? 答...
    杂货铺老板阅读 1,401评论 0 10
  • 转自陈明乾的博客,可能有一定更新。 转原文声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、...
    C86guli阅读 4,677评论 6 72