Javaweb动态开发最重要的Servlet实例分析

2023-10-24,

这篇文章主要讲解了“Javaweb动态开发最重要的Servlet实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Javaweb动态开发最重要的Servlet实例分析”吧!

一.导入方式

由于jdk中没有servlet对应的jar包,所以需要咱们手动引入,有两种方式:

1.可以采取向lib目录导入servlet-api的jar包的方式

2.在maven项目中设置如下坐标,并添加相关依赖到依赖库中即可(推荐使用这种,在maven里选择webapp的骨架建立项目会自动给你配置好web.xml文件)

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>

版本号可以自己定,依赖范围要配置成provided,否则会和其他jar包冲突

二.Servlet生命周期

原生的Servlet项目都是实现Servlet接口,功能都是通过实现这个接口或者继承HttpServlet来完成的,其实在IDEA里重写方法的过程中所对应的顺序就是他的生命周期,以下面为例:

按照每一个方法翻译而来的字面意思,流程是:

初始化&mdash;&mdash;得到服务配置&mdash;&mdash;服务&mdash;&mdash;获取服务信息&mdash;&mdash;销毁,简言之,就是一个从初始化到服务再到消亡的过程。

初始化阶段:

public void init(ServletConfig servletConfig)

当服务器启动,读取web.xml文件的过程中,Tomcat加载 Servlet,加载完成后,Servlet 容器会创建一个 Servlet 实例 并调用 init()方法,init()方法只会调用一次,这个没什么好解析的,就是面向对象中类特性的体现

服务阶段:

public void service(ServletRequest servletRequest, ServletResponse servletResponse)

这个方法的形参里有两个ServletRequest和ServletResponse类型的接口,翻译过来就是服务请求、服务响应,Tomcat启动时自动装载某些 servlet,并在 Servlet 容器启动后,浏览器首次向 Servlet 发送请求,发送的请求和响应作为参数就传到了service方法对应的形参里进行处理。看了一下jdk的源码,发现两个接口下面都有很多的抽象方法,至于请求和响应在底层是怎样执行的源码里啥都没写,目前还不知道(推测是个底层驱动)

消亡阶段:

public void destroy()

从图中规定的顺序不难看出,执行到最后的方法也就预示着Servlet的生命即将结束

在JDK的源码中,Servlet接口下的destory()没有方法体,应该也是和启动线程的start0()方法类似被开发者封装简化了

完整流程演示:

@WebServlet("/demo1")
public class SevDemo1 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {System.out.println("我在初始化~~~");}
    @Override
    public ServletConfig getServletConfig() {return null;}
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    System.out.println("hello world!!!!");}
    @Override
    public String getServletInfo() {return null;}
    @Override
    public void destroy() {System.out.println("我走了,拜拜~~~");}
}

控制台打印的信息很好地反映了执行情况:

至于public ServletConfig getServletConfig()public String getServletInfo()在实现接口后重写的方法中默认返回的是null,应该是两个起补充作用的方法

三.继承HttpServlet

在实际开发中采用继承HttpServlet类的方式开发Servlet程序更加方便,因为实现接口重写那麽多方法是真的麻烦,而通过继承的方式就可以根据需要选择性的重写doGe()或doPost()方法就简单很多,比如

public class HttpDemo extends HttpServlet { 
 @Override 
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
      System.out.println("执行 doGet()...");
   }
 @Override 
 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
      System.out.println("执行 doPost()...");
    } 
}

至于方法体里写什么内容就要看对应的业务场景了

气氛烘托到这里了就不得不说一下GET和POST的区别了

GET&POST

以前老师是教我这样理解的&mdash;&mdash;我把一封信放在信封里邮寄出去,我可以选择密封或者不密封,而这就会导致信的内容会不会被别人看到,若是前者则对应POST,后者就对应GET

当然,这只是抽象层面,而从具体方面来看:

1.从功能上来讲,get是从服务器上获取数据,post是向服务器传送数据

2.从报文上来讲,在不带参数时区别就单纯是第一行方法名不同,而在带参数时GET方法的参数放在请求头URL中,POST方法的参数放在请求体BODY中 注:GET方法的参数写在?后,用&分割

3.从安全性来讲,其实他们都不安全,因为http是明文传输(在网页按F12进入开发者模式发现两种方式都能看到数据信息)。但是这张图应该很生动形象也能反映一些问题,相比较之下POST还是比GET安全,因为数据在地址栏不可见,哈哈哈

四.Servlet相关性质(八股文)

1.Servlet 是一个供其他 Java 程序(Servlet 引擎)调用的 Java 类,不能独立运行

2.对于每次访问请求,Servlet 引擎都会创建一个新的 HttpServletRequest 请求对象和一个 新的 HttpServletResponse 响应对象,然后将这两个对象作为参数传递给它调用的 Servlet 的 service()方法,service 方法再根据请求方式分别调用 doXXX 方法

3.针对浏览器的多次 Servlet 请求,通常情况下,服务器只会创建一个 Servlet 实例对象, 也就是说 Servlet 实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至 web 容器退出/或者 redeploy 该 web 应用,servlet 实例对象才会销毁

4.如果在<servlet>元素中配置了一个<load-on-startup>元素,那么 WEB 应用程序在启动时, 就会装载并创建 Servlet 的实例对象、以及调用 Servlet 实例对象的 init()方法

5.在 Servlet 的整个生命周期内,init 方法只被调用一次。而对每次请求都导致 Servlet 引 擎调用一次 servlet 的 service 方法

&mdash;&mdash;ps:刷dy整理出来的

五.Request&Response

对于这些内部方法来说我觉得会用API就行

1.HttpServletRequest

HttpServletRequest 表示请求过来的信息:

公共接口类HttpServletRequest继承自ServletRequest。客户端浏览器发出的请求被封装成为一个HttpServletRequest对象。对象包含了客户端请求信息包括请求的地址,请求的参数,提交的数据,上传的文件客户端的ip甚至客户端操作系统都包含在其内。

还是面向对象那一套,封装成类后调用里面的方法,部分常用方法如下:

public String getAuthType() 返回这个请求的身份验证模式
public Cookie[ ] getCookies() 返回一个数组,该数组包含这个请求中当前的所有cookie
public long getDateHeader(String name) 返回指定的请求头域的值,这个值被转换成一个精确到毫秒的长整数
public String getHeader(String name) 返回一个请求头域的值。(译者注:与上一个方法不同的是,该方法返回一个字符串)

2.HttpServletResponse

HttpServletResponse 表示所有响应的信息,需要设置返回给客户端的信息,通过 HttpServletResponse 对象来进行设置即可,会用几个核心API就够了

addHeader(String name,String value) 将指定的名字和值加入到响应的头信息中
encodeURL(String url) 编码指定的URL
setStatus(int sc) 给当前响应设置状态码
setHeader(String name,String value) 将给出的名字和值设置响应的头部

六.请求转发模型

先前在网页中输出hello java!只是一次请求对应一个Servlet,浏览器&mdash;&mdash;Tomcat&mdash;&mdash;Servlet没有实现请求的转发,而在真实环境中网站不可能只进行一次交互,往往需要在一次请求中使用到多个servlet完成

1.一个 web 资源收到客户端请求后,通知服务器去调用另外 一个 web 资源进行处理

2. HttpServletRequest 对象(也叫 Request 对象)提供了一个 getRequestDispatcher 方法,该 方法返回一个 RequestDispatcher 对象,调用这个对象的 forward 方法可以实现请求转发

3. request 对象同时也是一个域对象,开发人员通过 request 对象在实现转发时,把数据 通过 request 对象带给其它 web 资源处理

在实际场景中,用户输入信息提交后得到反馈这一过程就是典型的请求转发,就像这样:

第一个Servlet里的情况

@WebServlet("/demo2")
public class Sevdemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这里是demo2~~");
        //存储数据
        req.setAttribute("懒羊羊","你好!");
        //请求转发
        req.getRequestDispatcher("/demo3").forward(req,resp);
    }
}

第二个Servlet里的情况

@WebServlet("/demo3")
public class Sevdemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这里是demo3~~");
        Object msg= req.getAttribute("懒羊羊");
        System.out.println(msg);
    }
}

当我启动Tomcat来访问demo2时:

实现了请求的转发!

既然是一个Servlet转发给另一个Servlet,且是部署在同一个Tomcat中,那就说明不能访问当前web工程外的资源、同一次 HTTP 请求中,进行多次转发,仍然是一次 HTTP 请求

七.请求重定向

和请求转发比较类似,请求重定向指:一个 web 资源收到客户端请求后,通知客户端去访问另外一个 web 资源,这称之为请求重定向,还是通过API调方法来实现,基本流程如下:

首先通过setStatus()设置响应状态码,然后setHeader(“location”,“http://www.taobao.com”)设置新地址

就实现了请求重定向

@WebServlet("/demo2")
public class Sevdemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这里是demo2~~");
        //设置响应状态码
        resp.setStatus(302);
        //设置新地址
        resp.setHeader("location","http://www.taobao.com")
    }
}

感谢各位的阅读,以上就是“Javaweb动态开发最重要的Servlet实例分析”的内容了,经过本文的学习后,相信大家对Javaweb动态开发最重要的Servlet实例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是本站,小编将为大家推送更多相关知识点的文章,欢迎关注!

《Javaweb动态开发最重要的Servlet实例分析.doc》

下载本文的Word格式文档,以方便收藏与打印。