servlet类

自定义servlet和service的执行流程

自定义的servlet
  1. 先根据自己的Tomcat版本导入对应的Servlet -api.jar包
  2. 创建一个类,名字叫****servlet ,继承Httpservlet类
  3. 重新service方法
  4. 在web.xml配置servlet的访问路劲

web.xml
servle类

运行流程

在客户端浏览器输入访问路劲----》访问后台服务器的页面或者servlet
在这里插入图片描述
http://localhost:8080/javaweb_day01_war_exploded/dmo
http:// 超文本传输协议 网络传输协议
localhost 主机ip地址
8080 Tomcat服务端口号
javaweb_day01_war_wxploded 虚拟路劲、、项目的访问路劲
dmo 资源路劲 去定位具体的一个servlet类

当访问dmo时 会去项目中找web.xml,依次 先找 url-pattern 的路劲 找不到就报错 404 根据url 找servlet-name 在根据 中的 找 中的,然后在去找 从而定位到我们具体访问的servlet类
在这里插入图片描述
service是如何被执行的?
在这里插入图片描述

java设计模式:单例模式,在程序运行期间,一个类只会实例化一个对象,只能new一次

只创建一次有什么好处:

​ 避免重复创建对象,提高效率,节省资源(jvm虚拟机实例化对象是非常耗内存资源的)。

对象什么时候被销毁?服务器关闭时自动被销毁。

多例的时候:

GC:垃圾回收机制!自动回收!

一个简单的servlet输出数据库

新建一个web项目,使用servlet和dao模式,部署项目tomcat,查询表的数据并显示在页面中。
接口

package com.aaa.dao;

import java.util.List;
import java.util.Map;
//设置接口也就是查询的方法
public interface IgradeDao {
    List<Map> setselect();
}

工具类

 import com.aaa.Utils.JDBCUtils;
import com.aaa.dao.IgradeDao;

import java.util.List;
import java.util.Map;

/**
 * @author zhangyifan
 * @version 8.0
 * @description:
 * @date 2021/9/7 18:21
 */
public class Igrade implements IgradeDao {
//编写查询的方法
    @Override
    public List<Map> setselect() 
        String sql="select * from grade";//sql语句
        List<Map> list= JDBCUtils.query(sql,null);//利用工具类
        if (list!=null){
            return list;
        }
        return null;
    }
}
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;

/**
 * @author zhangyifan
 * @version 8.0
 * @description:
 * @date 2021/9/7 18:26
 */
public class gradeservlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         resp.setContentType("text/html;charset=utf-8");//设置字符集格式
        PrintWriter writer= resp.getWriter();//创建输出对象
        
        writer.write("<table border='1'>");
        
        IgradeDao igradeDao=new Igrade();//创建输出对象调用输出
        
        List<Map> maps= igradeDao.setselect();
        
        writer.write("<thead><tr><td>GradeID</td><td>GradeName</td> </tr> </thead>");
        
        for (Map map:maps){//循环遍历输出
            writer.write("<tr><td>"+map.get("GradeID")+"</td><td>"+map.get("GradeName")+"</td></tr>");
        }
        writer.write("</table>");
    }
}

servlet接口实现类

1、servlet接口来自于servlet规范下一个接口 这个接口存在Http服务器
2、servlet规范中任务 ,http服务器能调用的动态资源文件必须是一个servlet接口实现类
3、servlet-api.jar存放的有Javax.servlet.servlet接口
Servlet接口五个方法在这里插入图片描述
三个重要的方法
inin()初始化方法
service 服务方法
destory()销毁方法

servlet继承

servlet 和applet相对应,是运行在服务端的小程序,用来处理客户端请求并给予响应的java类,继承了HTTPServlet类
GenericServlet这个类实现了三个接口(ServletConfig ,Servlet,Serializable);
在这里插入图片描述
HttpServlet里面do开头的都是请求方法 但是大部分只用doGet()和doPost()
1.service() 函数的调用

问题:这是一个重写的函数,我们并没有调用,但是service被调用了,谁调用的?

解决:tomcat帮我们调用的。先去缓存池中找servlet对象,如果找到了,直接使用这个对象调用service()方法,如果没有找到,通过java反射 Class.forName().Instance();创建一个servlet对象放入缓存池中,在调service()。
CLass.forName(“com.qy137.servlet.PeopleServlet”);
2.servlet 接口
问题1:万一这个类没有实现servlet接口还能调用码?
直接报错
tomcat要求程序员配置的servlet类 ,必须实现一个接口 叫做Servlet,如果不实现 则报错。

问题2 为什么我们自己写的servlet不去直接实现Servlet接口,此时tomcat为了定制规则,让程序员自己的类必须实现Servlet接口,但是有一个新问题出现了。这个Servlet接口定制了5个函数,其中只有service函数比较有用,剩下的四个基本上用不到。怎么解决?
如果直接继承servlet 就必须重写五个函数
在这里插入图片描述

**官方创建来GenericServlet实现servlet接口,我们自己写的servlet类只需要继承GenericServlet类就可以了**

问题3:自己写的类为什么不继承GenericServlet而是要继承 HttpServlet 类呢?
原因①:
因为有一部分需要基于Http的 Generic里面没有这些
​ 因为我们的请求和响应都是基于HTTP的,而GenericServlet中的参数是ServletRequest和ServletResponse,此时有一些专属于HttpServlet的方法没办法调用 ,所以我们需要将ServletRequest转化成HttpServletRequest,将ServletResponse转换成HttpServletResponse,
原因②:

​ 我们的请求方式一般常用两种,get/post,但是现在用的是service,在service中会根据你请求的方式进行请求的分发,选择合适的方法。
在这里插入图片描述
在这里插入图片描述

servlet的生命周期

1.工作原理

当web服务器接收到一个http请求时,他会判断请求的内容是否是静态网页数据或者是动态数据,静态数据web服务器会自行处理,然后产生响应,动态数据会将请求转发给Servlet容器。Servlet容器会找到对应处理该请求的Servlet实例来处理,结果会送回web服务器,在由服务器传回用户端。
针对同一个Servlet,第一次收到请求时servlet容器**会建立一个Servlet实例**,启动一个线程,第二次请求时,就无序建立相同的Servlet实例,而是启动第二个线程来服务客户端请求。所有多线程可以提高web应用程序的执行效率,也可以降低Web服务器的系统负担。
Servlet**是单例的**,整个服务器运行期间,每个Servlet类只产生一个实例,所有相关请求都由这个Servlet实例来处理。
2、工作流程

在这里插入图片描述

3、 生命周期**

一个Servlet实例对象从被创建到被销毁的过程。
是指Servlet从加载、初始化、处理请求(service方法)、返回响应、直到销毁的过程。
inint()初始化方法
service 服务方法
destory()销毁方法
过程

  1. 实例化(创建对象 调用构造方法 ) 只实例化一次
  2. 初始化(数据的初始化,和获取信息的过程)初始化一次
  3. 提供服务(service,doGet,doPost)多次
  4. 销毁(关闭容器时销毁) 销售一次
4.实例化

创建Servlet对象的时机:

1、默认情况下,在Servlet容器启动后:客户首次加粗样式向Servlet发出请求,Servlet容器会判断内存中是否存在指定的Servlet对象,如果没有则创建它,然后根据客户的请求创建HttpRequest、HttpResponse对象,从而调用Servlet对象的service方法;
在这里插入图片描述
2、Servlet容器启动时
当Tomcat启动时:当web.xml文件中如果元素中指定了< load-on-startup>子元素时,Servlet容器在启动web服务器时,将按照顺序创建并初始化Servlet对象;
load-on-startup的从小到大的顺序创建
在这里插入图片描述

在这里插入图片描述

3、Servlet 类文件被更新后,查询创建Servlet
Servlet容器会在启动时自动创建Servlet,是由web.xml文件中为Servlet设置的《load-on-startup》属性决定的

Servlet容器停止或者重新启动:Servlet容器调用Servlet对象的destroy方法来释放资源。

Service方法处理 请求/响应

对于每一个HTTP请求,servlet容器会创建一个封装了HTTP请求的ServletRequest实例传递给servlet的service方法,ServletResponse则表示一个Servlet响应,其隐藏了将响应发给浏览器的复杂性。

常用方法
Request对象: 接口封装了客户的请求信息,如客户请求方式,参数,客户使用的协议,以及发出请求的远程主机信息
HttpServletResquest的常用方法

req.getParameter(String);//根据名字获取参数的值;表单中的参数,地址栏中的参数
req.getParameterValues(String);//根据名字获取一组参数的值(复选框)
req.getParameterMap()://获得一个Map<String, String[]>对象,所有的参数值都放在字符串数组中
req.getAttribute(String);//根据名字获取属性的值
req.setAttribute(String,Object);//根据属性设置值
req.getRequestDispatcher(String);//请求转发器
req.setCharacterEncoding(“utf-8”); //设置请求的编码方式

Response对象:接口封装了服务器响应信息,主要用来输出信息到客户端浏览器
HttpServletResponse常用方法

Response.setContentType(“text/html;charset=utf-8”);设置响应的内容类型
PrintWriter response.getWriter();//获得响应的输出流
response.sendRedirect(redirect);//重定向到指定的网址

请求转发和重新定向

请求转发跟重定向的区别?
请求转发,服务器转发:

地址栏不会发生改变,在服务器端完成,效率高。

携带数据可以在Servlet之间进行传递

请求转发,服务器转发

 //将usename设置到req里面
        req.setAttribute("name",usename);
        //数据转发
        req.getRequestDispatcher("tow").forward(req,resp);  

获取数据然后通过setAttribute吧值给req。 通过请求转发吧req发送到tow里面 ===》 在tow里面通过getAttribute取出来就行
在这里插入图片描述

 //重新定向
        resp.sendRedirect("login.html");

在这里插入图片描述
请求数据转发的时候更快,而且能携带数据
重新定向不能携带数据,流程慢一点

在这里插入图片描述
请求转发的时候是直接在服务器里面进行的 只发送了一次请求
在这里插入图片描述
重新定向是在客户端里面进行的,不可以携带数据 需要发送两次请求 所有地址栏发生了改变
在这里插入图片描述

注解
//@WebServlet("/login")//直接路劲 访问路劲
//@WebServlet(name = "servlet的名字",urlPatterns = {"/hello","hehe"})//不常用
@WebServlet(name = "login",urlPatterns = "/login")//映射单个路劲
简单的登录验证

1、前台输入用户名和密码,(login.jsp)
2、将用户名密码传到servlet服务里面(LoginServlet.class)
3、服务接收用户名和密码,调用jdbc去查询数据库记录,判断是否存在(Itab_dlDao)
4、如果有记录 跳转到登录成功页面ssds.jsp,失败跳转到失败页面fail.html

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Network porter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值