自定义servlet和service的执行流程
自定义的servlet
- 先根据自己的Tomcat版本导入对应的Servlet -api.jar包
- 创建一个类,名字叫****servlet ,继承Httpservlet类
- 重新service方法
- 在web.xml配置servlet的访问路劲
运行流程
在客户端浏览器输入访问路劲----》访问后台服务器的页面或者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()销毁方法
过程
- 实例化(创建对象 调用构造方法 ) 只实例化一次
- 初始化(数据的初始化,和获取信息的过程)初始化一次
- 提供服务(service,doGet,doPost)多次
- 销毁(关闭容器时销毁) 销售一次
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