JavaWeb 学习笔记(三)GenericServlet和HttpServlet介绍

来源:互联网 发布:手机时间提醒软件 编辑:程序博客网 时间:2024/05/22 05:09

GenericServlet

(1)GenericServlet概述
GenericServlet是Servlet接口的实现类,我们可以通过继承GenericServlet来编写自己的Servlet
ServletConfig是什么?

<servlet> 
<servlet-name>HelloWorld</servlet-name>
<servlet-class>HelloWorld</servlet-class>
</servlet>
这是一个配置信息,它与ServletConfig对象对应。这个信息最终会被加载进内存,也就是说web.xml文件会由其解析器解析后加载进内存。这个文件中的name和class信息会加到ServletConfig对象中,这个对象是对本Servlet的配置:即一个Servlet对象,对应一段web.xml中Servlet的配置信息
这里写图片描述
(2)查看API文档中ServletConfig接口中定义的方法:接口中提供的方法如果不是由自己来实现,那么就由Tomcat来实现。

  • String getServletName() 方法获取的是<servlet-name>中的内容,这个方法使用的很少;
  • 没有获取<servlet-class>信息的方法,因为获取这个信息是不安全的;
  • ServletContext getServletContext() 方法获取的是Servlet上下文对象,这个对象后面会提到;这个方法使用的多
  • String getInitParameter(String name) 方法获取初始化参数
  • Enumeration getInitParameterNames() 方法获取的是一个集合,里面装的是初始化参数的名称

下面这段代码也是属于<servlet>中的

<init-param>    <param-name>p1</param-name>    <param-value>v1</param-value></init-param><init-param>    <param-name>p2</param-name>    <param-value>v2</param-value></init-param>

通过String getInitParameter(String name) 方法,传入p1就可以得到v1的值
方法演示:
自定义方法

public class HelloWorld implements Servlet {    @Override    public void init(ServletConfig servletConfig) throws ServletException {        /*        获取初始化参数         */        System.out.println(servletConfig.getInitParameter("p1"));        System.out.println(servletConfig.getInitParameter("p2"));        /*        获取所有初始化参数的名称         */        Enumeration e = servletConfig.getInitParameterNames();        while(e.hasMoreElements()){            System.out.println(e.nextElement());        }    }

可以看到,在调用init()方法后,显示出了相应的初始化参数和其对应的值
这里写图片描述

(2)Servlet相关类之ServletRequest和ServletResponse对象的介绍
void service(ServletRequest req, ServletResponse res) 形参中包含了两个对象:请求和响应。

  • Servlet把请求数据拿过来,然后处理请求,最后对客户端响应。所有的请求数据都被Tomcat封装到ServletRequest对象当中,调用对象的方法就能把请求信息拿出来,http协议中请求的所有信息都在其中。
  • 而ServletResponse对象,例如服务端返回一个302,那么这个302的值还有Location就可以调用对象相应的set方法来发送,甚至可以使用其对象来发送html的代码,这时浏览器就会收到这个对象发送回来的信息

(3)GenericServlet
GenericServlet是Servlet接口的实现类,可以通过继承GenericServlet来编写自己的Servlet
以下是自己写的一个Servlet实现:Servlet每次被访问的时候,Tomcat传递给它一个ServletConfig对象。在所有的方法第一个被调用的是init()。

import javax.servlet.*;import java.io.IOException;/* * 模拟GenericServlet抽象类 */public class BServlet implements Servlet {    private ServletConfig servletConfig;    //前期自己写的时候总会写这个成员    @Override    /*    由Tomcat来调用,并且只调用一次    它是这些方法中第一个被调用的,它会在构造器之后马上被调用     */    public void init(ServletConfig servletConfig) throws ServletException {        //把Tomcat传递的ServletConfig值赋给本类的一个成员,其实就是把它保存起来,方便在其他方法中使用        this.servletConfig = servletConfig;    }    @Override    public ServletConfig getServletConfig() {        return this.servletConfig;    }    @Override    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {        System.out.println("每次处理请求都会被调用!");    }    @Override    /*    这个方法用的很少,所以不写了     */    public String getServletInfo() {        return "我是一个快乐的Servlet";    }    @Override    public void destroy() {        System.out.println("啊,我要死了!");    }}

下面来看GenericServlet抽象类的常用方法:

  • ServletConfig getServletConfig()方法返回this.servletConfig对象;
  • ServletContext getServletContext() 方法用的是this.getServletContext();
  • 其他的一些方法就可以使用ServletConfig对象的方法来实现;

一个小技巧:上面代码是自己实现的Servlet,如果再写一个类CServlet继承上面的这个类,对于初始化方法想重新写,那么就可以这样写

//父类中的初始化方法public void init(ServletConfig servletConfig) throws ServletException {        this.servletConfig = servletConfig;        init();        //组合的方式    } public init(){}
//子类中的初始化方法public init(){    System.out.println("这是我自己的初始化方法!");}

以下是GenericServlet的源码:关于源码的一些解释和技巧看上面自己实现的BServlet

import java.io.IOException;import java.util.Enumeration;public abstract class GenericServlet implements Servlet, ServletConfig,        java.io.Serializable {    private static final long serialVersionUID = 1L;    private transient ServletConfig config;    public GenericServlet() {    }    @Override    public void destroy() {        //可写可不写    }    @Override    //参考上面解释    public String getInitParameter(String name) {        return getServletConfig().getInitParameter(name);    }    @Override    //参考上面解释    public Enumeration<String> getInitParameterNames() {        return getServletConfig().getInitParameterNames();    }    @Override    public ServletConfig getServletConfig() {        return config;    }    @Override    public ServletContext getServletContext() {        return getServletConfig().getServletContext();    }    @Override    //这个方法不常用    public String getServletInfo() {        return "";    }    @Override    public void init(ServletConfig config) throws ServletException {        this.config = config;        //参考小技巧        this.init();    }    public void init() throws ServletException {    //不是生命周期方法(生命周期方法只有三个)不由Tomcat直接调用,这个方法的创建是为了其子类再定义初始化方法使用的,具体参考小技巧       }    public void log(String msg) {        getServletContext().log(getServletName() + ": " + msg);    }    public void log(String message, Throwable t) {        getServletContext().log(getServletName() + ": " + message, t);    }    @Override    //这个是抽象方法,强迫各位程序猿必须去写    public abstract void service(ServletRequest req, ServletResponse res)            throws ServletException, IOException;    @Override    public String getServletName() {        return config.getServletName();    }}

自己调皮的继承了GenericServlet抽象类,并简单演示了如何继承:

import javax.servlet.*;import java.io.IOException;public class DServlet extends GenericServlet {    //小技巧的使用    public void init(){        System.out.println("哈哈哈,我来了!");    }    @Override    //这个方法必须写    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {        System.out.println("Hello World!");    }    @Override    //可写可不写    public void destroy() {        System.out.println("哎,我走了!");    }}

把web.xml文件中的name,class,url-pattern修改一下,使得能够访问DServlet。可以看到自定义的东西:
访问六次以后
访问了六次
关闭服务:
这里写图片描述

HttpServlet

(1)HttpServlet所在的包与Servlet和GenericServlet的包有所不同,类名前缀说明HttpServlet总是与http协议相关。http请求最常见的两种方式:get和post,这个类就提供了相应的方法来获取。
现在重点看一下几个方法

  • void doGet(HttpServletRequest req, HttpServletResponse resp)方法
  • void service(HttpServletRequest req, HttpServletResponse resp)void service(ServletRequest req, ServletResponse res)是service方法的重载,前者是跟协议相关的。Tomcat会很智能的根据协议来创建对象。协议是基于http但是方法却与协议无关,所以在HttpServlet后者中对传入其中的对象做一个强转,然后再去调用http的方法,这样就可以让生命周期方法来调用前者

这里写图片描述

(2)这里的doGet()和doPost()是需要覆盖的,如果没有覆盖并且他们被调用了,那么就会出现405表示不支持这种请求方式(资源找到了,但是不支持客户端这样的请求方式)
过程时序图示:
过程时序图
首先覆盖一下doGet方法而不覆盖doPost方法

public class EServlet extends HttpServlet {    //这个类是抽象类,但是所有方法都实现了    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        System.out.println("deGet()...");    }}

在地址里输入地址,localhost:8080/JavaWeb/EServlet这就是get的请求方式,就可以看到:
这里写图片描述

当只覆盖doPost方法时:由于使用默认使用的是get请求方式,所以会出现下面的情况

这里写图片描述

此时写一个html文件,请求方式为post。上传表单到EServlet

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Login</title></head><body><form action="/JavaWeb/EServlet" method="post">    <input type="submit" value="sub"/></form></body></html>

这时候就可以看到正常的页面了:
这里写图片描述

HttpServlet的关键就是调用流程,也就是上面的时序图

本人是菜鸟一枚,当做学习笔记写博客。谢谢各路大咖驻足审阅

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 ps直线工具变成箭头了怎么办 笔记本图形处理速度慢怎么办 微信语音发不出去怎么办 ps里的图层锁定怎么办 ps图层丢失了怎么办 PS标题画面太小怎么办 轮胎蹭掉一块皮怎么办 吃香蕉吃的胃难受怎么办 qq糖卡在喉咙里怎么办 头发上粘到了qq糖怎么办 老房子土墙掉土怎么办 速写画的太慢怎么办 艺术生文化课没过线怎么办 5岁儿童坐飞机忘带证件怎么办 儿童坐飞机没带证件怎么办 儿童坐飞机没带户口本怎么办 儿童坐飞机没有带户口本怎么办 刚打蜡的车下雨怎么办 飞机票不能退票不能改签怎么办 深圳航空买机票姓名错了怎么办 大众cc打不着火怎么办 手上扎了仙人掌刺怎么办 pscs5界面字体太小怎么办 儿童做飞机没带户口本怎么办 黑户口想做飞机怎么办 宝宝坐飞机忘记带证件怎么办 值机柜台关闭了怎么办 值机迟到几分钟怎么办 婴儿坐飞机没带证件怎么办 飞机票买了一天降价1000怎么办 社保卡磁性没了怎么办 社保卡民族错了怎么办 坐飞机婴儿出生证明没带怎么办 手提行李超过5kg怎么办 随身行李超过5kg怎么办 南航机票填错身份证怎么办 两岁宝宝坐着驼背怎么办 两岁的宝宝坐晕车怎么办 在机场丢东西了怎么办 孩子放学不按时回家怎么办?转 右腿比左腿粗2cm怎么办