zoukankan      html  css  js  c++  java
  • Servlet 基础

    JSP 的前身就是 Servlet

    什么是 Servlet?

    Servlet 是在服务器上运行的小程序。一个 Servlet 就是一个 Java 类,并且可以通过“请求 - 响应”编程模型来访问这个驻留在服务器内存里的 Servlet 程序。

    Tomcat 容器等级

    Tomcat 容器分为四个等级,Servlet 容器管理 Context 容器,一个 Context 对应一个 Web 工程

    具体如上图所示: Tomcat 容器 : Container 容器 --> Engine 容器(引擎容器) --> HOST (主机)容器 --> Servlet --> Context

    手工编写第一个 Servlet

    1、新建一个 MyFirstServletDemo 动态项目,并新建一个 index.jsp 文件

    <%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Insert title here</title>
    </head>
    <body>
    
    <a href="servlet/HelloServlet">Get请求HelloServlet</a>
    
    <form action="servlet/HelloServlet" method="post">
        <input type="submit" value="Post请求HelloServlet"/>
    </form>
    </body>
    </html>

    2、在src中新建一个servlet包,再定义一个HelloServlet类,并重写 doGet 和 doPost 方法

    package servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class HelloServlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // TODO Auto-generated method stub
            System.out.println("处理Get请求……");
            PrintWriter out = resp.getWriter();
            resp.setContentType("text/html; charset=utf-8");
            out.println("<h1>Hello Servlet</h1>");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // TODO Auto-generated method stub
            System.out.println("处理Post请求……");
            PrintWriter out = resp.getWriter();
            resp.setContentType("text/html; charset=utf-8");
            out.println("<h1>Hello Servlet</h1>");
        }
    
    }

    3、在 WEB-INF - web.xml 中注册servlet,添加 servlet 和 servlet-mapping 两个标签

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
      <display-name>MyFirstServletDemo</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
      
      <servlet>
          <servlet-name>HelloServlet</servlet-name>
          <servlet-class>servlet.HelloServlet</servlet-class>
      </servlet>
      
      <servlet-mapping>
          <servlet-name>HelloServlet</servlet-name>
          <url-pattern>/servlet/HelloServlet</url-pattern>
      </servlet-mapping>
    </web-app>

    运行查看

     

     从这个例子中,可以大概看出 Servlet 的执行流程

     Servlet 的生命周期

    Servlet 生命周期阶段包括:初始化、加载、实例化、服务和销毁

    1、初始化阶段,调用 init() 方法;

    2、响应客户请求阶段,调用 service() 方法。由 service() 方法根据提交方式选择执行 doGet() 或者 doPost() 方法

    3、终止阶段,调用 destroy() 方法

     

     下面用代码演示下 Servlet的生命周期

    1、新建一个 testServlet.jsp 页面

    <%@ page language="java" contentType="text/html; charset=utf-8"
        pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Insert title here</title>
    </head>
    <body>
    <h1>测试 Servlet 生命周期</h1>
    
    <a href="servlet/TestServlet1">发起Get请求</a>
    </body>
    </html>

    2、新建一个TestServlet1 类,并重写父类的构造方法,初始化方法,doGet方法和销毁方法

    package servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class TestServlet1 extends HttpServlet {
    
        public TestServlet1() {
            System.out.println("TestServlet1的构造方法被执行……");
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // TODO Auto-generated method stub
            System.out.println("处理Get请求……");
            resp.setContentType("text/html; charset=utf-8");
            PrintWriter out = resp.getWriter();
            out.println("<h1>Test Servlet1<h1>");
        }
    
        @Override
        public void destroy() {
            // TODO Auto-generated method stub
            System.out.println("TestServlet1的销毁方法被执行……");
        }
    
        @Override
        public void init() throws ServletException {
            // TODO Auto-generated method stub
            System.out.println("TestServlet1的初始化方法被执行……");
        }
    
        
        
    
    }

    3、修改配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
      <display-name>MyFirstServletDemo</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
      
      <servlet>
          <servlet-name>TestServlet1</servlet-name>
          <servlet-class>servlet.TestServlet1</servlet-class>
      </servlet>
      
      <servlet-mapping>
          <servlet-name>TestServlet1</servlet-name>
          <url-pattern>/servlet/TestServlet1</url-pattern>
      </servlet-mapping>
      
    </web-app>

    从下图中可以看到依次执行的是 构造方法、初始化方法和service方法,当servlet实例已经存在的时候直接调用service方法,而不需要再去执行构造方法和初始化方法。只有当服务器关闭的时候,才会执行销毁方法

     Servlet 容易装载 Servlet的三种情况:

    1、Servlet 容器启动时自动装载某些Servlet,实现它只需要在 web.xml 文件中的 <Servlet></Servlet> 之间添加代码:<load-on-start-up>1</load-on-start-up>  数字越小,表示优先级越高

    2、在Servlet 容器启动后,客户首次向 Servlet 发送请求

    3、Serlvet 类文件被更新后,重新装载 Servlet

    其实,上例演示的也就是第2种情况,启动Servlet容器,首次向 Servlet发送请求

    现在我们来演示第1种情况,在 servlet包下创建一个 TestServlet2 类

    package servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class TestServlet2 extends HttpServlet {
    
        public TestServlet2() {
            System.out.println("TestServlet2的构造方法被执行……");
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // TODO Auto-generated method stub
            System.out.println("处理Get请求……");
            resp.setContentType("text/html; charset=utf-8");
            PrintWriter out = resp.getWriter();
            out.println("<h1>Test Servlet2<h1>");
        }
    
        @Override
        public void destroy() {
            // TODO Auto-generated method stub
            System.out.println("TestServlet2的销毁方法被执行……");
        }
    
        @Override
        public void init() throws ServletException {
            // TODO Auto-generated method stub
            System.out.println("TestServlet2的初始化方法被执行……");
        }
        
    }

    2、修改web.xml 配置文件,在 servlet 标签中加一对 load-on-startup,把TestServlet1的优先级设为2,低于 TestServlet1的优先级1

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
      <display-name>MyFirstServletDemo</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
      
      <servlet>
          <servlet-name>TestServlet1</servlet-name>
          <servlet-class>servlet.TestServlet1</servlet-class>
          <load-on-startup>2</load-on-startup>
      </servlet>
      
      <servlet-mapping>
          <servlet-name>TestServlet1</servlet-name>
          <url-pattern>/servlet/TestServlet1</url-pattern>
      </servlet-mapping>
      
      <servlet>
          <servlet-name>TestServlet2</servlet-name>
          <servlet-class>servlet.TestServlet2</servlet-class>
          <load-on-startup>1</load-on-startup>
      </servlet>
      
      <servlet-mapping>
          <servlet-name>TestServlet2</servlet-name>
          <url-pattern>/servlet/TestServlet2</url-pattern>
      </servlet-mapping>
    </web-app>

    重新启动Tomcat服务器,我们发现服务器先执行的是TestServlet2的构造方法和初始化方法

     现在来实现一个小例子,用户注册完成以后,把用户的注册信息在另一个页面打印出来

     1、reg.jsp

    <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'reg.jsp' starting page</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
        <style type="text/css">
         .label{
               20%    
         }
         .controler{
               80%    
         }
       </style>  
       <script type="text/javascript" src="js/Calendar3.js"></script>
      </head>
      
      <body>
        <h1>用户注册</h1>
        <hr>
        <form name="regForm" action="servlet/RegServlet" method="post" >
                  <table border="0" width="800" cellspacing="0" cellpadding="0">
                    <tr>
                        <td class="lalel">用户名:</td>
                        <td class="controler"><input type="text" name="username" /></td>
                    </tr>
                    <tr>
                        <td class="label">密码:</td>
                        <td class="controler"><input type="password" name="mypassword" ></td>
                        
                    </tr>
                    <tr>
                        <td class="label">确认密码:</td>
                        <td class="controler"><input type="password" name="confirmpass" ></td>
                        
                    </tr>
                    <tr>
                        <td class="label">电子邮箱:</td>
                        <td class="controler"><input type="text" name="email" ></td>
                        
                    </tr>
                    <tr>
                        <td class="label">性别:</td>
                        <td class="controler"><input type="radio" name="gender" checked="checked" value="Male">男<input type="radio" name="gender" value="Female">女</td>
                        
                    </tr>
                   
                    <tr>
                        <td class="label">出生日期:</td>
                        <td class="controler">
                          <input name="birthday" type="text" id="control_date" size="10"
                          maxlength="10" onclick="new Calendar().show(this);" readonly="readonly" />
                        </td>
                    </tr>
                    <tr>
                        <td class="label">爱好:</td>
                        <td class="controler">
                        <input type="checkbox" name="favorite" value="nba"> NBA &nbsp;
                          <input type="checkbox" name="favorite" value="music"> 音乐 &nbsp;
                          <input type="checkbox" name="favorite" value="movie"> 电影 &nbsp;
                          <input type="checkbox" name="favorite" value="internet"> 上网 &nbsp;
                        </td>
                    </tr>
                    <tr>
                        <td class="label">自我介绍:</td>
                        <td class="controler">
                            <textarea name="introduce" rows="10" cols="40"></textarea>
                        </td>
                    </tr>
                    <tr>
                        <td class="label">接受协议:</td>
                        <td class="controler">
                            <input type="checkbox" name="isAccept" value="true">是否接受霸王条款
                        </td>
                    </tr>
                    <tr>
                        <td colspan="2" align="center">
                            <input type="submit" value="注册"/>&nbsp;&nbsp;
                            <input type="reset" value="取消"/>&nbsp;&nbsp;
                        </td>
                    </tr>
                  </table>
                </form>
      </body>
    </html>

    2、web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
      <display-name>getServletUserInfo2</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
      
      <servlet>
          <servlet-name>RegServlet</servlet-name>
          <servlet-class>servlet.RegServlet</servlet-class>
      </servlet>
      
      <servlet-mapping>
          <servlet-name>RegServlet</servlet-name>
          <url-pattern>/servlet/RegServlet</url-pattern>
      </servlet-mapping>
    </web-app>

    3、JavaBean Users.java

    package user;
    
    import java.util.Date;
    
    /**
     * 用户类
     * @author wupeng
     *
     */
    public class Users {
    
        private String username; // 用户名
        private String mypassword; // 密码
        private String gender; // 性别
        private String email; // 邮箱
        private Date birthday; // 出生日期
        private String[] favorites; // 爱好
        private String introduce; // 自我介绍
        private boolean flag; // 是否接受协议
        
        
        public Users() {
            
        }
    
    
        public String getUsername() {
            return username;
        }
    
    
        public void setUsername(String username) {
            this.username = username;
        }
    
    
        public String getMypassword() {
            return mypassword;
        }
    
    
        public void setMypassword(String mypassword) {
            this.mypassword = mypassword;
        }
    
    
        public String getGender() {
            return gender;
        }
    
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
    
        public String getEmail() {
            return email;
        }
    
    
        public void setEmail(String email) {
            this.email = email;
        }
    
    
        public Date getBirthday() {
            return birthday;
        }
    
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
    
        public String[] getFavorites() {
            return favorites;
        }
    
    
        public void setFavorites(String[] favorites) {
            this.favorites = favorites;
        }
    
    
        public String getIntroduce() {
            return introduce;
        }
    
    
        public void setIntroduce(String introduce) {
            this.introduce = introduce;
        }
    
    
        public boolean isFlag() {
            return flag;
        }
    
    
        public void setFlag(boolean flag) {
            this.flag = flag;
        }
        
        
    
    }

    4、RegServlet.java

    package servlet;
    
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import user.Users;
    
    public class RegServlet extends HttpServlet {
    
        public RegServlet() {
            // TODO Auto-generated constructor stub
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // TODO Auto-generated method stub
            super.doGet(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // TODO Auto-generated method stub
            req.setCharacterEncoding("utf-8");
            
            Users u = new Users();
            
            String username, mypassword, gender, email, introduce, isAccept;
            Date birthday;
            String[] favorites;
            
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            
            try {
                username = req.getParameter("username");
                mypassword = req.getParameter("mypassword");
                gender = req.getParameter("gender");
                email = req.getParameter("email");
                introduce = req.getParameter("introduce");
                birthday = sdf.parse(req.getParameter("birthday"));
                if(req.getParameterValues("isAccpet")!=null)
                {
                  isAccept = req.getParameter("isAccept");
                }
                else
                {
                  isAccept = "false";
                }
                favorites = req.getParameterValues("favorite");
                
                // 把用户信息存到对象u中
                u.setUsername(username);
                u.setMypassword(mypassword);
                u.setGender(gender);
                u.setEmail(email);
                u.setIntroduce(introduce);
                u.setBirthday(birthday);
                if ("true".equals(isAccept)) {
                    u.setFlag(true);
                } else {
                    u.setFlag(false);
                }
                u.setFavorites(favorites);
                
                // 把注册成功的用户信息保存到 session 中
                req.getSession().setAttribute("regUser", u);
                
                // 服务器转发到注册成功页面
                req.getRequestDispatcher("../userinfo.jsp").forward(req, resp);
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        
    
    }

    5、userinfo.jsp

    <%@ page language="java" import="java.util.*,java.text.*" contentType="text/html; charset=utf-8"%>
    
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'userinfo.jsp' starting page</title>
        
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">    
        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
        <meta http-equiv="description" content="This is my page">
        <!--
        <link rel="stylesheet" type="text/css" href="styles.css">
        -->
        <style type="text/css">
         .title{
              30%;    
             background-color: #CCC;
             font-weight: bold;
         }
         .content{
             70%;
             background-color: #CBCFE5;
         }
         
       </style>  
      </head>
      
      <body>
        <h1>用户信息</h1>
        <hr>
        <center>
        
        <jsp:useBean id="regUser" class="user.Users" scope="session" />
        
         <table width="600" cellpadding="0" cellspacing="0" border="1">
            <tr>
              <td class="title">用户名:</td>
              <td class="content">&nbsp;<jsp:getProperty property="username" name="regUser"/></td>
            </tr>
            <tr>
              <td class="title">密码:</td>
              <td class="content">&nbsp;<jsp:getProperty property="mypassword" name="regUser"/></td>
            </tr>
            <tr>
              <td class="title">性别:</td>
              <td class="content">&nbsp;<jsp:getProperty property="gender" name="regUser"/></td>
            </tr>
            <tr>
              <td class="title">E-mail:</td>
              <td class="content">&nbsp;<jsp:getProperty property="email" name="regUser"/></td>
            </tr>
            <tr>
              <td class="title">出生日期:</td><td class="content">&nbsp;
                 <% 
                   SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
                   String date = sdf.format(regUser.getBirthday());
                 %> 
                 <%=date%>
              </td>
            </tr>
            <tr>
              <td class="title">爱好:</td>
              <td class="content">&nbsp;
                  <%
                      String[] favorites = regUser.getFavorites();
                      for (String f:favorites) {
                %>
                <%=f %>"&nbsp;&nbsp;"
                <% 
                      }
                  %>
              </td>
            </tr>
            <tr>
              <td class="title">自我介绍:</td>
              <td class="content">&nbsp;<jsp:getProperty property="introduce" name="regUser"/></td>
            </tr>
            <tr>
              <td class="title">是否介绍协议:</td>
              <td class="content">&nbsp;<jsp:getProperty property="flag" name="regUser"/></td>
            </tr>
         </table>
        </center>
      </body>
    </html>

    页面输出:

     

    Servlet 路径跳转

    1、index.jsp 中的路径跳转

    <a href="request.jsp?username=科比">测试URL传参数</a>
    
    <!-- 使用相对路径访问 Servlet -->
    <!-- /servlet/HelloServelt 第一个/ 表示服务器的根目录 -->
    <a href="servlet/HelloServlet">访问HelloServlet</a>
    
    <!-- 使用绝对路径访问Servlet,可以使用 path 变量:path变量表示项目的根目录 -->
    <a href="<%=path %>/servlet/HelloServlet">访问HelloServlet</a>
    
    <!-- 表单中 action的 URL地址写法,与超链接方式完全相同 -->

    2、web.xml 中 url-pattern

    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <!-- url-pattern 处必须以 / 开头,这里的 / 表示项目的根目录  -->
        <url-pattern>/servlet/HelloServlet</url-pattern>
    </servlet-mapping>

    3、servlet 跳转

    // 请求重定向方式跳转到 test.jsp,当前路径是 ServletPathDirection/servlet
    // response.sendRedirect("test.jsp");
    // 使用 request.getContextPath 获得上下文对象
    // response.sendRedirect(request.getContextPath + "/test.jsp");
    
    // 服务器内部跳转,这里的斜线表示项目的根目录
    request.getRequestDispatcher("/test.jsp").forward(request, response);
  • 相关阅读:
    springnodejs
    js CacheQueue
    权重练习
    架构师速成8.3-可用性之分库分表
    架构师速成8.3-可用性之分布式
    架构师速成8.3-可用性
    架构师速成8.3-架构师必须要了解的规则(转)
    架构师速成6.15-开发框架-单点登录
    架构师速成6.14-开发框架-异常处理
    架构师速成6.13-开发框架-前后结合
  • 原文地址:https://www.cnblogs.com/rogerwu/p/8535338.html
Copyright © 2011-2022 走看看