JavaWeb 核心之 Servlet

一、Servlet 简介

1、什么是 Servlet 
Servlet  是运行在服务端的 Java 小程序 ,是 sun 公司提供的一套规范,用来处理客户端的请求、响应给浏览器的动态资源,但 Servlet 的实质就是 Java 
代码,通过 Java 的 API 动态的向客户端输出内容。

Servlet 规范包含三个技术点
1)servlet 技术
2)filter 技术(过滤器)
3)listener 技术(监听器)

2、Servlet 快速入门
实现步骤:
1)创建类实现 Servlet 接口
2)覆盖未实现的方法
3)在 web.xml 进行 Servlet 的配置

但是在实际开发中我们一般不会去实现 Servlet 接口,因为那样覆盖的方法太多,我们一般继承 HttpServlet 类
实现步骤:
1)创建类继承 HttpServlet 类
2)覆盖 doGet() 和 doPost()
3)在 web.xml 中进行 Servlet 的配置

3、实现案例

package com.ma.servlet;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class QuickStartServlet implements Servlet{
       @Override
       public void service(ServletRequest arg0, ServletResponse arg1)
                   throws ServletException, IOException {
            HttpServletResponse response = (HttpServletResponse) arg1;
            response.getWriter().write( "hello Servlet !" );
            
      }
       @Override
       public void destroy() {
             // TODO Auto-generated method stub
            
      }
       @Override
       public ServletConfig getServletConfig() {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public String getServletInfo() {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public void init(ServletConfig arg0) throws ServletException {
             // TODO Auto-generated method stub
            
      }
}

配置文件
<? xml version = "1.0" encoding = "UTF-8" ?>
  < display-name > WEB13 </ display-name >
  < servlet >
       < servlet-name > QuickStartServlet </ servlet-name >
       < servlet-class > com.ma.servlet.QuickStartServlet </ servlet-class >
  </ servlet >
  < servlet-mapping >
       < servlet-name > QuickStartServlet </ servlet-name >
       < url-pattern > /QuickStartServlet </ url-pattern >
  </ servlet-mapping >
  < 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 >
</ web-app >
 
运行结果

二、Servlet 的 API ( 生命周期 )

(1)Servlet 接口中的方法

1) init(Config config) 何时执行:Servlet 对象创建的时候执行(默认第一次访问 servlet 时候创建该对象,代表的是 servlet  对象的配置信息)
package com.ma.servlet;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class QuickStartServlet implements Servlet{
       @Override
       public void init(ServletConfig arg0) throws ServletException {
             //1、获得 servlet 的名字
            String str = arg0.getServletName();
            System. out .println(str);
             //2、获得 servlet 初始化时候设置的参数
            String url = arg0.getInitParameter( "url" );
            System. out .println(url);
             //3、获得 ServletContext 对象
            ServletContext servletContext = arg0.getServletContext();
            System. out .println(servletContext);
      }
       @Override
       public void service(ServletRequest arg0, ServletResponse arg1)
                   throws ServletException, IOException {
            HttpServletResponse response = (HttpServletResponse) arg1;
            response.getWriter().write( "hello Servlet !" );
            
      }
       @Override
       public void destroy() {
             // TODO Auto-generated method stub
            
      }
       @Override
       public ServletConfig getServletConfig() {
             // TODO Auto-generated method stub
             return null ;
      }
       @Override
       public String getServletInfo() {
             // TODO Auto-generated method stub
             return null ;
      }
}

2) service(ServletRequest arg0, ServletResponse arg1) 何时执行:每次请求都会执行(ServletRequest代表请求,认为 ServletRequest 内部封装了http 请求的信息;ServletResponse 代表响应,认为 ServletResponse 内部封装了 http 响应的信息)

3) destory() 何时执行:Servlet 销毁的时候执行(服务器关闭)
三、Servlet 的配置
<!-- Servlet 类的配置 -->
  < servlet >
       < servlet-name > QuickStartServlet </ servlet-name >
       < servlet-class > com.ma.servlet.QuickStartServlet </ servlet-class >
       < init-param >
       < param-name > url </ param-name >
       < param-value > jdbc:mysql:///user </ param-value >
       </ init-param >
  </ servlet >
  <!-- Servlet 虚拟路径的配置 -->
  < servlet-mapping >
       < servlet-name > QuickStartServlet </ servlet-name >
       < url-pattern > /QuickStartServlet </ url-pattern >
  </ servlet-mapping >

其中 url-pattern 的配置方式
1)完全匹配(访问的资源与配置的资源完全匹配)
  <!-- 1、完全匹配 -->
       < url-pattern > /QuickStartServlet </ url-pattern >
2)目录匹配(格式:/虚拟目录.../* 任意资源)
<!-- 2、目录匹配 -->
       < url-pattern > / aaa / bbb / ccc /* </ url-pattern >
3)扩展名匹配 (格式 :* . 扩展名)
<!-- 3、扩展名匹配  -->
       < url-pattern > *. abcd </ url-pattern >

注意:第二种和第三种不要混用 /aaa/bbb/*.abcd

2、服务器启动实例化 Servlet 配置
Servlet 的创建:默认第一次访问时创建。当在 Servlet 配置时候加上一个 load-on-startup Servlet 对象在服务器启动的时候就创建。 

3、缺省 Servlet 
可以将 url pattern 配置一个 / ,代表该 Servlet 是缺省的 Servlet。
什么是缺省的 Servlet ?
    当你访问的资源地址都不匹配时找缺省的 Servlet。
4、欢迎页面
< 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 >

案例一、用户登录功能

登录页面 
<! DOCTYPE html>
< html >
< head >
< meta charset = "UTF-8" >
< title > Insert title here </ title >
</ head >
< body >
       < form action = "/WEB13/loginServlet" method = "post" >
            用户名: < input type = "text" name = "username" >< br />
            密码: < input type = "password" name = "password" >< br />
             < input type = "submit" value = "登录" >
      
      
       </ form >
</ body >
</ html >

web.xml
< servlet >
    < description ></ description >
    < display-name > LoginServlet </ display-name >
    < servlet-name > LoginServlet </ servlet-name >
    < servlet-class > com.ma.login.LoginServlet </ servlet-class >
  </ servlet >
  < servlet-mapping >
    < servlet-name > LoginServlet </ servlet-name >
    < url-pattern > /loginServlet </ url-pattern >
  </ servlet-mapping >
 
Servlet 类
package com.ma.login;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ma.domain.User;
import com.ma.utils.DataSourceUtils;
/**
 * Servlet implementation class LoginServlet
 */
public class LoginServlet extends HttpServlet {
      
       protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             //1、获得用户名及密码
            String username = request.getParameter( "username" );
            String password = request.getParameter( "password" );
            
             //2、从数据库中验证用户名和密码是否正确
            QueryRunner runner = new QueryRunner(DataSourceUtils. getDataSource ());
            String sql = "select * from user where username = ? and password = ?" ;
            User user = null ;
             try {
                  user = runner.query(sql, new BeanHandler<User>(User. class ), username,password);
            } catch (SQLException e) {
                  
                  e.printStackTrace();
            }
             //3、根据返回结果给用户不同的信息
             if (user != null ){
                   //用户登录成功
                  response.getWriter().write(user.toString());
            } else {
                   //用户登录失败
                  response.getWriter().write( "NO Finding ..." );
            }
            
      }
      
       protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             // TODO Auto-generated method stub
      }
}

数据库连接工具类
package com.ma.utils;

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

import javax.sql.DataSource;


public class DataSourceUtils {

    private static DataSource dataSource = new ComboPooledDataSource();

    private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();

    // 直接可以获取一个连接池
    public static DataSource getDataSource() {
        return dataSource;
    }

    // 获取连接对象
    public static Connection getConnection() throws SQLException {

        Connection con = tl.get();
        if (con == null) {
            con = dataSource.getConnection();
            tl.set(con);
        }
        return con;
    }

    // 开启事务
    public static void startTransaction() throws SQLException {
        Connection con = getConnection();
        if (con != null) {
            con.setAutoCommit(false);
        }
    }

    // 事务回滚
    public static void rollback() throws SQLException {
        Connection con = getConnection();
        if (con != null) {
            con.rollback();
        }
    }

    // 提交并且 关闭资源及从ThreadLocall中释放
    public static void commitAndRelease() throws SQLException {
        Connection con = getConnection();
        if (con != null) {
con.commit (); // 事务提交
            con.close();// 关闭资源
            tl.remove();// 从线程绑定中移除
        }
    }

    // 关闭资源方法
    public static void closeConnection() throws SQLException {
        Connection con = getConnection();
        if (con != null) {
            con.close();
        }
    }

    public static void closeStatement(Statement st) throws SQLException {
        if (st != null) {
            st.close();
        }
    }

    public static void closeResultSet(ResultSet rs) throws SQLException {
        if (rs != null) {
            rs.close();
        }
    }

}



entity 类
package com.ma.domain;
public class User {
       private int id ;
       private String username ;
       private String password ;
       private String email ;
       public int getId() {
             return id ;
      }
       public void setId( int id) {
             this . id = id;
      }
       public String getUsername() {
             return username ;
      }
       public void setUsername(String username) {
             this . username = username;
      }
       public String getPassword() {
             return password ;
      }
       public void setPassword(String password) {
             this . password = password;
      }
       public String getEmail() {
             return email ;
      }
       public void setEmail(String email) {
             this . email = email;
      }
       @Override
       public String toString() {
             return "User [id=" + id + ", username=" + username + ", password="
                        + password + ", email=" + email + "]" ;
      }
      
      
}

数据库配置
<? xml version = "1.0" encoding = "UTF-8" ?>
< c3p0-config >
  < default-config >
    < property name = "driverClass" > com.mysql.jdbc.Driver </ property >
       < property name = "jdbcUrl" > jdbc:mysql:///user </ property >
       < property name = "user" > root </ property >
       < property name = "password" > 123456 </ property >
       < property name = "initialPoolSize" > 5 </ property >
       < property name = "maxPoolSize" > 20 </ property >
  </ default-config >
 
  < named-config name = "oracle" >
    < property name = "driverClass" > com.mysql.jdbc.Driver </ property >
       < property name = "jdbcUrl" > jdbc:mysql:///web_07 </ property >
       < property name = "user" > root </ property >
       < property name = "password" > 123 </ property >
  </ named-config >
 
</ c3p0-config >

数据库资源

四、什么是 ServletContext 对象?
ServletContext 对象代表一个 web 应用的环境(上下文)对象。该对象内部封装的是 web 应用信息,一个 web 应用对应一个对象。        
创建:该 web 应用被加载,项目发布。
销毁:服务器关闭或者 web 应用移除。
获得对象:
1、 ServletContext servletContext = config.getServletContext();
2、 ServletContext servletContext = this.getServletContext();
用处:
1、获取初始化参数 

web.xml 中配置
< context-param >
       < param-name > driver </ param-name >
       < param-value > com.mysql.jdbc.Driver </ param-value >
  </ context-param >

ContextServlet 类
package com.ma.context;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Servlet implementation class ContextServlet
 */
public class ContextServlet extends HttpServlet {
      
       protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             //1、获得 ServletContext 对象
            ServletContext context = getServletContext();
             //2、获得初始化参数
            String initparameter = context.getInitParameter( "driver" );
            System. out .println(initparameter);
            
      }
       protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             // TODO Auto-generated method stub
      }
}

结果:

2、获得 web  应用中任何资源的绝对路径( 重要 重要 重要 ! ! !
package com.ma.context;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet implementation class ContextServlet
*/
public class ContextServlet extends HttpServlet {
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获得 ServletContext 对象
        ServletContext context = getServletContext();
        //2、获得初始化参数
        String initparameter = context.getInitParameter("driver");
        System.out.println(initparameter);
        //3、获得  a、b、c、d . txt 的绝对路径
        //3.1 获得 a.txt
        String realpath_A = context.getRealPath("/a.txt");
        System.out.println(realpath_A);
        //3.2 获得 b.txt
        String realpath_B = context.getRealPath("/WEB-INF/b.txt");
        System.out.println(realpath_B);
        //3.3 获得 c.txt
        String realpath_C = context.getRealPath("/WEB-INF/classes/c.txt");
        System.out.println(realpath_C);        
        //3.4 获取不到 4.txt
        //在读取 src (classes) 下面的资源是可以通过类加载器来完成的
        //getResource("") 相对地址 相对于 classes
        String path = ContextServlet.class.getClassLoader().getResource("/c.txt").getPath();
        System.out.println(path);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
    }

}


结果:
3、ServletContext   一个域对象(存储数据的区域就是域对象)
    作用域的范围:整个web 项目的动态资源

存数据

取数据

统计用户访问次数:
取数据:

猜你喜欢

转载自blog.csdn.net/young_1004/article/details/80866896
今日推荐