Servlet

一、含义

1.1 基础

1.1.1 含义

项目含义
本质一个Servlet就是一个Java类,但需要在web.xml文件中注册。
运行位置在服务器上运行的小程序。即不在客户端运行。
基础性JSP的前身。即先有servlet再有JSP。
访问模式通过“请求-响应”编程模型,来访问这个驻留在服务器内存里的servlet程序。
MVC位置相当于控制器角色(C)。

(1)Java Servlet 是运行在 Web 服务器或应用服务器上的程序。
(2)解码请求,格式化响应。
(3)Servlet是Java语言中编写Web服务器扩展功能的重要技术。
(4)是JSP技术的底层运行基础。JSP页面在编译期或运行期,都会先转化成Servlet文件。
(5)Servlet是一个基于java技术的Web组件,运行在服务器端,由servlet容器管理,用于生成动态内容。

1.1.2 作用

  1. 接收页面数据。
  2. 简单处理数据。
  3. 调用service层方法,并传入前端接收的参数。
  4. 接收service返回结果。
  5. 简单处理后,向前端传递数据。
  6. 页面跳转。

1.1.3 Servlet等级

在这里插入图片描述

1.1.4 Servlet生命周期

生命周期说明
初始化阶段调用init()方法。
响应客户请求阶段调用service()方法。
终止阶段调用destroy()方法

初始化----->加载---->实例化---->服务---->销毁
注意
servlet的生命周期由Servlet容器管理。因此,不需要new一个servlet的实例。也不用我们手动去销毁(初始化)它。

——初始化时间
即实例化时间。启动tomcat,打开浏览器访问这个Servlet时。可见一个servlet只会构造一次。
——销毁时间
servlet容器关闭时。

doget和dopost两个处理业务逻辑的执行次数:每一次用户访问时候都会执行。

1.1.5 Tomcat装载Servlet的三种情况

情况一:Servlet容器启动时,会自动装载某些Servlet。
——即添加< loadon-startup>标签。
实现自动装载,只需要在web.xml文件的< servlet></ servlet>之间添加如下代码:< loadon-startup>1< loadon-startup>。数字越小表示优先级越高。
情况二:Servlet容器启动后,客户首次向Servlet发送请求时。
——即点击页面请求时
情况三:Servlet类文件被更新后,会重新装载Servlet。
——即修改servlet代码,重新保存时。
注意

  1. servlet实例被加载后,servlet对象会长期保存在服务器的内部。直至上述三种情况出现,才会被重新加载。
  2. Servlet被装载后,servlet容器创建一个servlet实例,并且调用servlet的init()方法进行初始化。在servlet的整个生命周期内,init()方法只被调用一次。

1.1.6 Servlet继承结构

接口或类说明
Servlet接口(interface)init() + service() + destroy()
GenericServlet基类(abstract)与协议无关的Servlet
HttpServlet基类(abstract)实现了http协议的Servlet
自定义servlet类(实现类)重写(覆盖)doGet()和doPost()方法。

1.2 比较

1.2.1 与CGI比较

CGI:Common Gateway Interface,公共网关接口。
比CGI实现的程序优势:
(1) 性能更好。
(2)在 Web 服务器的地址空间内执行。不必再创建一个单独的进程来处理每个客户端请求。
(3)独立于平台。因为它们是用 Java 编写的。
(4)可信的。服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。
(5)Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库或其他软件进行交互。
在这里插入图片描述

1.2.2 与JSP比较

相同点
jsp和servlet本质都是一样的,都是可以通过java程序动态的生产静态网页,因为jsp经编译后就变成了的java文件,其实就是一个功能增强的Servlet。
不同点
——输出html形式。jsp是感觉是在html中嵌入java代码。当然事实上jsp转译后也是输出html的。servlet是在java代码中输出html。
(1)Servlet擅长于流程控制和事务处理。控制层
(2)JSP由HTML代码和JSP标签构成,可以方便地编写动态网页。视图层
因此在实际应用中采用Servlet来控制业务流程,而采用JSP来生成动态网页。
——对象创建
(1)JSP有很多内置对象可以直接使用
(2)Servlet需要自己定义。

二、步骤

2.1 创建servlet——继承HttpServlet类

(1)继承HttpServlet类。
(2)重写doGet、doPost、init等方法。
LifeServlet.java:

public class LifeServlet extends HttpServlet {
    // 设置属性。接收初始化参数。与web.xml中的参数名一一对应。
    private String username;
    private String password;
	public LifeServlet() {
	}
	// 方法。初始化。
	@Override
	public void init() throws ServletException {
		this.setUsername(this.getInitParameter("username"));
		this.setPassword(this.getInitParameter("password"));
	}
	// 接受get提交的方法
	@Override	
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html:charset=utf-8");
		PrintWriter out = response.getWriter();
		out.println("接受get提交的方法");
		out.flush();
		out.close();
	}
	// 接受post提交的方法
	@Override	
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request,response); //让doPost()做doGet()方法,目的是减少代码量。
	}
	// servlet的destroy销毁化方法
	@Override
	public void destroy() {
		super.destroy();
	}
}

2.2 注册Servlet

web.xml

<servlet>
	<!-- 第一步:定义Servlet标识。名称 -->
	<servlet-name>LifeServlet</servlet-name>
	<!-- 第二步:映射后端中的Servlet类路径 -->
	<servlet-class>pockageName.LifeServlet</servlet-class>
	<!-- 第三步:初始化参数(个数不限),可省略。 -->
	<init-param>
		<param-name>username</param-name>
		<param-value>admin</param-value>
	</init-param>
	<init-param>
		<param-name>password</param-name>
		<param-value>123456</param-value>
	</init-param>
</servlet>
<servlet-mapping>
	<!-- 第四步:映射本文件中的Servlet标识符。 -->
	<servlet-name>LifeServlet</servlet-name>
	<!-- 第五步:映射前端请求的URL。 -->
	<url-pattern>/actionValue|aHref</url-pattern>
</servlet-mapping>

三、示例-用户登录

需求:在登录界面。输入姓名和密码时,通过数据库存储的信息,判断登录成功与否。

3.1 数据库

3.1.1 数据库设计

数据库名(shopping)
表名(users):字段1(id)+ 字段2(username) + 字段3(password)

CREATE DATABASE IF NOT EXISTS shopping;
CREATE TABLE IF NOT EXISTS users(
  id INT PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '用户id',
  username VARCHAR(20) NOT NULL COMMENT '登录名',
  password VARCHAR(30) NOT NULL COMMENT '密码',
  gender VARCHAR(10) COMMENT '性别',
  hobby VARCHAR(100) COMMENT '爱好'
)ENGINE = InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=UTF8;

3.1.2 数据库连接

DBUtil.java:

public class DBUtil{
  private static final String driver = "com.mysql.jdbc.Driver"; 
  private static final String url = "jdbc:mysql://127.0.0.1:3306/shopping?characterEncoding=utf8";
  private static final String user = "root";
  private static final String password = "123456";
  private Connection conn = null;
  private PreparedStatement ps = null;
  private ResultSet rs = null;
  static{
     try{
       Class.forName(driver);
     }catch(ClassNotFoundException e){
       e.printStackTrace();
     }
  }
  // 方法1。连接数据库。
  public static Connection getConnection(){
    if(conn == null){
      try{
         conn = DriverManager.getConnection(url,user,password);         
      }catch(SQLException e){
        e.printStackTrace();
      }
    }
    return conn;
  }
  // 方法2。关闭SQL语句和结果集。
  public void closeRsAndPs(){
    try{
      if(rs != null){
        rs.close();
      }
      if( ps != null){
        ps.close();
      }
    }catch(SQLException e){
          e.printStackTrace();
    }
  }
  // 方法3。关闭连接。
  public void closeConnection(){
    try{
      if(conn != null){
        conn.close();
      }
    }catch(SQLException e){
       e.printStackTrace();
    }
  }
}

3.2 model层。

3.2.1 创建实体类

属性与数据库一一对应
Users.java:

private int id;
private String username;
private String password;
private String gender;
private String[] hobby;
// getter和setter使用自动生成。

3.2.2 DAO层

实现数据库访问层。
目的:
(1)增加用户:单增加(姓名+密码)。
(2)查询用户:单查询(姓名) + 多查询(无)
(3)删除用户:单删除(姓名 + 密码)
(4)修改用户:单修改(新旧姓名+新旧密码)。

UserDao.java:

public class UserDao{
  private Connection conn = null;
  private PreparedStatement ps = null;
  private ResultSet rs = null;
  // 方法1。设置用户属性。
  public void setUserAttribute(Users user, ResultSet rs){
    user.setId(rs.getInt("id"));
    user.setUsername(rs.getString("username"));
    user.setPassword(rs.getString("password"));
    user.setGender(rs.getString("gender"));
    String[] hobbyArray = rs.getString("hobby").split(",");
    user.setHobby(hobbyArray);
  }
  // 方法2。查询。形参:用户姓名。返回值:用户对象集。
  public List<Users> queryByName(String username){
    List<Users> users = null;
    if(username != null){
      try{
        conn.setAutoCommit(false);
        conn = DBUtil.getConnection();
        String sql = "SELECT * FROM users WHERE username = ?;";
        ps = conn.prepareStatement(sql);
        ps.setString(1,username);
        rs = ps.executeQuery();
        Users user = null;
        while(rs.next){
          user = new Users();
          setUserAttribute(user, rs);
          users.add(user);
        }
        conn.commit();
      }catch(SQLException e){
        e.printStackTrace();
      }finally{
        DBUtil.closeRsAndPs();
      } 
    }
    return users;
  }
    // 方法3。查询。形参:无。返回值:用户对象集。
  public List<Users> queryAll(){
    List<Users> users = null;
    try{
        conn.setAutoCommit(false);
        conn = DBUtil.getConnection();
        String sql = "SELECT * FROM users";
        ps = conn.prepareStatement(sql);
        ps.setString(1,username);
        rs = ps.executeQuery();
        Users user = null;
        while(rs.next){
          user = new Users();
          setUserAttribute(user, rs);
          users.add(user);
        }
        conn.commit();
    }catch(SQLException e){
      e.printStackTrace();
    }finally{
      DBUtil.closeRsAndPs();
    } 
    return users;
  }
  // 方法4。单查询。形参:用户姓名 + 密码。返回值:用户对象。
  public Users queryByNameAndPass(String username, String password){
    Users user = null;
    if(username != null && password != null){
      try{
        conn.setAutoCommit(false);
        conn = DBUtil.getConnection();
        String sql = "SELECT * FROM users WHERE username = ?  AND password = ?;";
        ps = conn.prepareStatement(sql);
        ps.setString(1,username);
        ps.setString(2,password);
        rs = ps.executeQuery();
        user = new Users();
        setUserAttribute(user, rs);
        conn.commit();
      }catch(SQLException e){
        e.printStackTrace();
      }finally{
        DBUtil.closeRsAndPs();
      } 
    }
    return user;
  }
  // 方法5。删除。形参:用户姓名 + 密码。返回值:无。
  public void deleteUser(String username, String password){
    if(username != null && password != null){
      if(queryByNameAndPass(username,password) != null){
        try{
          conn = DBUtil.getConnection();
          String sql = "DELETE FROM users WHERE username = ? AND password = ?;"
          ps = conn.prepareStatement(sql);
          ps.setString(1,username);
          ps.setString(2,password);
          ps.executeUpdate();
        }catch(SQLException e){
           e.printStackTrace();
        }finally{
          DBUtil.closeRsAndPs();
        }
      }
    }
  }
  // 方法6。增加。形参:用户姓名 + 密码。返回值:无。
  public void addUser(String username, String password,String gender, String hobby){
    if(username != null && password != null){
      if(queryByName(username) == null){
        try{
          conn = DBUtil.getConnection();
          String sql = "INSERT INTO users(username,password,gender,hobby) VALUES(?,?,?,?);"
          ps = conn.prepareStatement(sql);
          ps.setString(1,username);
          ps.setString(2,password);
          ps.setString(3,gender);
          ps.setString(2,hobby);
          ps.executeUpdate();
        }catch(SQLException e){
           e.printStackTrace();
        }finally{
          DBUtil.closeRsAndPs();
        }
      }
    } else {
       System.out.println("用户名为" + username + "已经存在,请重新命名!");
    }
  }
    // 方法7。修改。形参:用户姓名(新旧) + 密码(新旧)。返回值:无。
  public void modifyUser(String username, String password, String newUsername , String newPassword,String gender, String hobby){
    if(username != null && password != null && newUsername != null && newPassword != null){
      if(queryByName(username,password) != null){
        try{
          conn = DBUtil.getConnection();
          String sql = "UPDATE users SET username = ?,password = ?,password = gender,password = hobby WHERE username = ? AND password = ? ;";
          ps = conn.prepareStatement(sql);
          ps.setString(1,newUsername);
          ps.setString(2,newPassword);          
          ps.setString(3,gender);
          ps.setString(4,hobby);
          ps.setString(5,username);
          ps.setString(6,password);
          ps.executeUpdate();
        }catch(SQLException e){
           e.printStackTrace();
        }finally{
          DBUtil.closeRsAndPs();
        }
      }
    }
  }
}

3.3 Control层

实现servlet。
LoginServlet.java:

public class LoginServlet{
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response){
    doPost(request,response)
  }
  @Override
  protected void doPost(HttpServletRequest request,HttpServletResponse response){
    request.setCharacterEncoding("utf-8");
    response.setCharacterEncoding("utf-8");
    response.setContentType("text/html; charset=utf-8");
    // 获取用户名和密码。
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    // 调用DAO层。
    DBUtil dbutil = new DBUtil();
    User user = dbutil.queryByNameAndPass(username,password);
    // 根据查询结果。返回给视图层。
    if( user != null){
      // 把信息保存在request作用域。
      request。setAttribute("username",username);
      // 请求转发。目的保存此次用户名和密码。
      request.getRequestDispatcher("success.jsp").forward(request,response);
      request.sendRedirect("success.jsp");
    }else{
      // 请求重定向。目的不保存此次的用户名和密码。
      response.sendRedirect("error.jsp");
    }
  }
}

AddUserServlet.java:

public class AddUserServlet{
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response){
		UserDao userDao=new UserDao();
        //1、获得view信息,并封装成javaBean对象
        String username=request.getParameter("username");
        String password=request.getParameter("password");
        int gender=Integer.parseInt(request.getParameter("gender"));
        String [] hobbys=request.getParameterValues("hobby");
        StringBuffer hobbytemp=new StringBuffer();
        for(int i=0;i<hobbys.length;i++){
            hobbytemp.append(hobbys[i]+",");
        }
        User user=new User();
        user.setUsername(username);
        user.setPassword(password);
        user.setGender(gender);
        user.setHobby(hobbytemp.toString());
        // 2、添加到数据库
        int result= userDao.addUser(user);
        // 3、返回页面
        if(result>0){
        	response.sendRedirect("servlet/UserListServlet");
        }else{
       		response.sendRedirect("loginerror.jsp");
        }
  }
  @Override
  protected void doPost(HttpServletRequest request,HttpServletResponse){
	doGet(request,response);
  }
}

注册servlet(配置servlet)
web.xml:

<servlet>
	<servlet-name>LoginServlet</servlet-name>
	<servlet-class>com.servlet.LoginServlet</servlet-class>
</servlet>
<!-- servlet的url映射 -->
<servlet-mapping>
	<servlet-name>LoginServlet</servlet-name>
	<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet>
	<servlet-name>UserAddServlet</servlet-name>
	<servlet-class>com.servlet.UserAddServlet</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>UserAddServlet</servlet-name>
	<url-pattern>/userAddServlet</url-pattern>
</servlet-mapping>

3.4 View层

界面设计。action路径要与url-pattern一致。
登录页面。
login.jsp:

<form action="login" method="post">
  用户名:<input type="text" name="username" /><br/>
  密码:<input type="passwor" name="password" /><br/>
  性别:<input type="radio" value="boy" name="gender" /><input type="radio" value="girl" name="gender" /><br/>
  爱好:<input type="checkbox" value="羽毛球" name="hobby">羽毛球
 <input type="checkbox" value="篮球" name="hobby">篮球 
 <input type="checkbox" value="足球" name="hobby">足球 <br /> 
  <input type="submit" value="登录"/>
</form>
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值