0


Servlet基础详解


前言

Servlet是开发动态Web资源的一项技术,在整个开发架构中主要承担控制器(Controller)的作用,刚开始本章主要学习了解Servlet的基础概念及使用规范。


一、Servlet简介

Servlet是Server Applet的简称,翻译过来就是服务程序。是由sun公司提供的一门用于开发动态Web资源的技术。简单的讲,Servlet就是运行在服务器上的一个小程序,用来处理服务器接收到的请求。

比如一般的网页程序,是由我们通过浏览器来访问实现的,在这个过程中,我们的浏览器发送访问请求,服务器接收到请求,并对浏览器的请求做出相应的处理,这就是我们熟悉的B/S模型(浏览器—服务器模型)。而Servlet就是对请求做出处理的组件,运行于支持java的应用服务器中。

Servlet从狭义上说白了就是个接口,从广义上说就是实现了这个接口的所有的子类。

附加:我们打开项目目录下的JSP文件查看其源码,可以发现JSP底层也是实现了Servlet接口的,所以JSP它本质上就是一个Servlet。

二、Servlet的作用

在Servlet刚刚出现的年代,Servlet的作用十分复杂,即承担了处理数据的作用,又承担了展示页面的作用,导致代码的耦合性过高,不易于维护。随着时间的推移,出现了MVC思想,也就是模型 - 界面 - 控制器思想,极大的简便了开发,也明确了Servlet的作用。

附加:最经典的MVC模型是:JSP+JavaBean+Servlet开发模式。

根据上图我们可以知道,Servlet在其中承担的作用是Controller(控制器),起到对数据进行操作的作用。

三、Servlet处理的信息是什么

如图:我们查找Servlet底层的实现类以及实现类的子类。

除了自定义的实现类以外,还有GenericServlet实现类,该实现类中的service()方法没有实现接口中对应的方法,而是继续抽象下去。

继续查找service()方法是在哪个类中实现的。随之就找到了HttpServlet这个子类。如图:

HttpServlet是直接继承的GenericServlet,从上图所见,客户端发送到服务器的请求类型是多样化的,而Servlet作为控制器处理的就是这些请求报文(request)。

如下图:对客户端传过来的请求类型进行判断,更具传过来的类型执行对应的处理请求数据的方法。

注意:我们的Web应用完全是基于http协议的。而http有请求报文(request)和响应报文(response),请求报文就是浏览器向服务器发送的数据形成的数据对象,同理,响应报文就是服务器向浏览器发送的数据形成的数据对象,而http有两个重要的方法,也就是上图中HttpServlet中的doPost()和doGet()方法。这两个方法对应的post和get,就是前端表单中使用的。比如你登录某网站首页时,提交用户名和密码,就是被http协议封装成请求报文的形式发送到服务器的,这样,servlet就能够读取请求报文的类容,并对报文进行处理。

四、Servlet的开发流程

(一)、实现Servlet接口或者继承HttpServlet类

注:继承HttpServlet类更简洁更常用。

(二)、重写HttpServlet类的doGet()和doPost()方法

(三)、配置web.xml文件或者使用注解对servlet进行配置

1、首先在maven配置文件pom.xml中导入Servlet - API的依赖

2、使用web.xml配置servlet访问路径

3、使用注解配置servlet访问路径

注意:配置访问路径,注解和web.xml两者二选一即可,避免混淆!

五、Servlet的生命周期

我们通过去实现Servlet接口的方式观察Servlet的生命周期。如图:

所谓生命周期,就是Servlet什么时候创建,调用了何种方法,最后在什么时候被销毁。我们之前学过的对象都是自己手动创建的,最后由JVM来销毁,而Servlet的整个生命周期,都是由tomcat服务器来控制的。

由上图所示,程序运行后得出结论,Servlet的生命周期是:

实例化 --》初始化 --》多次调用service服务 --》 tomcat容器关闭时销毁

  • 默认情况下Servlet是在第一次访问的时候实例化和初始化的
  • 第一次访问就会调用service()服务方法
  • 直到关闭服务器时,Servlet才会被销毁

除了默认情况,我们也可以通过load-on-startup来控制Servlet在服务器启动的时候就加载(实例化+初始化)

(一)、通过web.xml文件来配置load-on-startup(启动时加载)优先级

(二)、通过注解来配置load-on-startup(启动时加载)优先级

注意:配置load-on-startup启动时加载时,web.xml和注解两种方式,二选一即可。

六、Servlet获取参数的方法

这里主要解析Servlet获取get和post参数的方式,主要有三种:

  1. 使用getParameter()获取参数方法,单个获取。
  2. 使用getParameterMap()获取Map键值对参数的方法。
  3. get特有的查询字符串的方法以及post以流的形式查询字符串的方法。

(一)、单个获取请求参数的方法

(二)、获取键值对形式的请求参数的方法

注意该方法获取到的请求参数是以Map键值对的形式存在的,并且在构造实体时,我们还需要将获取到的Map类型的参数通过BeanUtils工具类转换为需要的实体类类型进行构造。所以需要先导入BeanUtils的依赖。

1、在maven配置文件中导入BeanUtils工具类的依赖

2、获取参数,构造实体

(三)、get特有的查询字符串的方法以及post以流的形式查询字符串的方法。

这两种获取字符串的方式比较特别,get获取的是浏览器中URL地址栏访问路径?后面的参数,而post是从请求体中获取参数,这两者获取到的字符串参数都是URL编过码的,所以在获取参数时候都需要解码

1、get请求特有的查询字符串方法

2、post请求以流的形式获取请求体中的字符串参数

在使用该方法前,我们需要先简单了解下tomcat的工作原理:

如图所示,整个过程都是以流的形式传输的,所以在post请求中要获取请求体中的字符串参数,就需要先获取到这条输入流。

注意:获取流查询字符串参数的方式要放在最前面执行,因为流是只能消耗一次,放在其它操作过流的方法后面该方法就获取不到数据了,因为流被消耗了。

七、Servlet响应页面和数据

(一)、Servlet响应页面

响应页面,也就是收到前端的请求响应需要跳转的页面。Servlet响应页面有转发重定向两种方式(之前JSP的章节也讲过):

1、转发 — 也就是携带客户端发送的请求转发跳转到下一个页面,使用的是request请求对象。

//转发可以将请求中的数据带到新的页面。
//getRequestDispatcher():表示获取请求转发器的方法
//forward():表示将请求及响应对象一并转发到下一个新页面
request.getRequestDispatcher("跳转页面路径").forward(request,response);

2、重定向 — 服务器接收到前端请求,通过响应将要跳转的页面地址响应给客户端,客户端再重新发送请求跳转到目标页面。

//重定向是将要跳转的页面路径交给前端重新发送请求跳转页面。
//相当于客户端发送了两次请求,所以原来请求中的数据就没有了。
response.sendRedirect("响应的页面路径")

(二)、Servlet响应数据

响应数据也是通过流的方式响应给前端,这里主要用到的是一条打印流(也就是之前JSP中的内置对象out).响应数据一般都是响应的json格式的数据,前端获取到json格式的数据就相当于拿到了一个对象,通过对象的方式去获取数据。

1、获取到打印流响应普通数据(注意:有乱码要设置编码格式)

2、响应json字符串格式的数据

  • 首先我们需要先在maven中导入json的依赖,如图:

  • 响应json格式数据

八、Web项目的初始化参数

在web项目中初始化参数有三种:

  1. 每个Servlet可以有自己的初始化参数。
  2. 一个应用程序application也有自己的初始化参数
  3. 一个tomcat也有自己的初始化参数。

(一)、Servlet中的初始化参数如何配置及如何获取

1、配置Servlet初始化参数

2、获取Servlet初始化参数

  • 通过Servlet对象本身this获取Servlet初始化参数

  • 通过Servlet的初始化方法中的config配置对象获取Servlet初始化参数

(二)、application在应用中初始化参数如配放置如何获取

1、配置应用中的初始化参数

2、获取application应用中的初始化参数

(三)、tomcat中初始化参数如何配置如何获取

配置tomcat的初始化参数,需要到tomcat的conf文件目录中找到context.xml文件源码进行配置。

这里会使用到jndi规范(java naming directory interface译:java命名目录接口)进行配置。jndi也就是通过命名和资源关联起来的一种编程规范。

1、配置tomcat的初始化参数

2、获取tomcat的初始化参数

九、Servlet的线程安全问题

同一个Servlet在服务器中只会存在一个实例,不论是多少个访问,都调用的是同一个实例,也就是Servlet是单实例多线程的。这就存在着一定的线程安全问题,如果在Servlet中定义一个全局变量,那么程序运行这个变量的值很有可能会不是我们所预期的,所以在Servlet中要尽量避免使用全局变量。

运行如下程序实例Servlet的线程安全问题:

运行结果反应出Servlet中出现成员变量导致线程不安全:

所以Servlet中尽量避免出现成员变量。


总结

Servlet的基础概念及使用规范,还有上篇讲的JSP技术都是为开发Web项目做准备。后续还会更新过滤器以及MVC和三层架构等……

标签: 后端 servlet web

本文转载自: https://blog.csdn.net/m0_57789266/article/details/122928182
版权归原作者 偷油婆_ERP 所有, 如有侵权,请联系我们删除。

“Servlet基础详解”的评论:

还没有评论