servlet 使用手册

servlet

servlet的基本概念

需要服务器能够认识找到servlet的结构->web.xml文件

servlet就是一组接口,这组接口是与服务器进行数据交换的规则

大致流程:

  1. 创建java EE项目

  2. 定义类实现servlet接口,五个抽象方法init,destroy,getservletconfig,getservletinfo,service(service最重要)

  3. 配置servlet(服务器url地址mapping)
    将具体的类配置为servlet,在web.xml文件中使用<servlet>标签来进行配置配置服务器url地址与servlet的映射,使用<servlet-mapping>标签进行配置<url-pattern>

    另一种是通过注解进行配置,实际上是web.xml配置的子功能

逻辑实际执行流程:

​ 客户端发送http请求->服务器接收到请求->服务器处理

servlet的生命周期

服务器在第一次调用一个servlet类的时候,会创建servlet对象,这个对象只会存在一个被保存在服务器的上下文环境中,供服务器的持续调用,知道服务器下线,servlet对象才会调用销毁destroy方法,结束生命周期

init方法:

  • 在servlet被创建的时候会调用一次

service方法

  • 服务器调用servlet的方法

destroy方法

  • 服务器正常关闭时调用

servletConfig方法,servletInfo方法

servletConfig方法用于获取servletconfig对象的,该对象中记录了web.xml中servlet的各种信息,包括:

  • 获取在web.xml中的名字 getservletName
  • 获取在web.xml中通过<init-param>标签配置的初始化参数 getinitparameter
  • 获取所有 初始化参数的名字枚举 getinitparameternames
  • 获取当前web应用的servletcontext对象, getsevletcontext(*****servletContext用于不同的servlet之间共享数据)

servletInfo方法用于获取servlet的信息:

  • servlet版本
  • servlet作者

servlet的具体调用

  1. 默认情况下就是第一次调用servlet的时候调用init
    但是可以改变sevlet的创建时机,<servlet>标签下通过<load-on-startup>服务器启动时创建,负数就是默认值
  2. servlet被销毁,服务器被正常关闭才会执行destroy方法,这个方法也是服务器调用的.

servlet的问题

因为是单例存在于服务器中,所以存在线程安全问题

如果同时多个用户访问同一个servlet

为了保证servlet的执行效率和并行效率,不能对servlet进行加锁

所以在servlet中尽量不使用成员变量的修改,使用局部变量不会有线程安全问题

servlet注解配置

在servlet3.0开始,支持注解配置servlet,解决了使用web.xml配置繁琐的问题,并且更好理解servlet的配置

改变:

  1. 创建java EE时需要选则servlet3.0以上版本(java EE 6开始)
  2. 可以不用创建web.xml文件
  3. 在类上使用@webServlet注解

@webServlet注解结构

根据之前配置web.xml文件的经验,注解应该包含以下的配置选项

配置servlet

  • name String
  • loadOnStartup int default -1

name可以不用配置了,因为name用于配置映射的作用不再需要了,直接在类上配置路径即可完成映射

loadOnStartup就是servlet的创建时机配置,默认是-1,配置为非负数就是服务器启动的时候创建servlet

配置mapping

  • urlPatterns String[]
  • value String[]

urlPattern 这个就是对应的服务器资源路径,需要注意的是,资源路径一定是/开头

value 如果不配置其他属性,那么可以直接写String[]参数作为value的值,其实就是urlpatterns

资源路径小知识

定义资源路径有三种方法

  1. /xxx
  2. /xxx/xxx
  3. *.do

what mean?

第一种是基础,指明了资源路径必须由/开头

第二种表示路径可以有多层

第三种指明了*可以代表任意资源名称,这个*也需要带上/

服务器小知识

要配置服务器应用,需要将servlet所在工程拷贝到服务器的配置目录下

工程中的web-inf目录的资源不能被客户端直接访问,可以将隐私资源放在这个目录下

资源小知识

web资源分为静态资源和动态资源

  • 静态资源

也就是所有用户看到的都是相同的内容,不需要做出改变的资源

  • 动态资源 (servlet/jsp,php,asp)

需要servlet根据不同的条件对资源进行加工,转变成静态资源之后再返回给客户端

所以jsp文件不能直接用浏览器渲染,而改为html文件就可以直接打开

通信三要素

  • ip
  • 端口
  • 传输协议

传输协议:

安全协议tcp: 三次握手四次挥手

​ tcp/http协议

不安全udp

HttpServlet

Http协议

先介绍Http协议

http是四个字母的缩写,hyper text tranform protocol 超本文传输协议

定义了客户端和服务端发送数据的格式,使得两边能够相互解释二进制序列

特点

基于TCP/IP协议,是一种安全协议,不会丢失

HTTP服务的默认端口是80

基于请求响应模型:一次请求得到一次响应,减少服务端压力

无状态协议:每次请求之间没有关系

历史版本

1.0版本 每次连接响应之后都会断开

1.1版本 复用链接,如果短时间内没有请求在断开连接

HTTP数据格式

Http请求消息格式

一共四个部分

  • 请求行
  • 请求头
  • 请求空行
  • 请求体

image-20231219163903652

  • 请求行 使用一行 描述清楚请求的网络信息

请求方式 请求url 请求协议/版本号

  • 请求头

直接接着请求行下一行开始,语法格式:

请求头属性名称:值,值…

  • 空行用于分割请求头和请求体,也就是使用换行符分割每一条数据
  • 请求体(正文)

get方式没有请求体

请求体里面表单信息,例如username=value

7种请求方式

常用的有get和post请求

get方法与post方法的区别:

  1. 最大区别在于传递参数的位置不同,get方式参数跟在url中,明文显示,post的参数在请求体中
  2. get方式的url有长度限制,而post没有,因为post不需要将url中的参数解析出来的步骤
  3. post相对安全,不过也只是相对,有心人拦截了请求包照样能解析出请求体的数据

请求头属性

请求头属性的目的就是告诉服务器客户端的一些信息

服务器主要使用的信息有:

  1. Host 服务器的地址

  2. user_agent 浏览器版本信息,服务器解决兼容性问题

  3. Accept 浏览器能够接受的response格式

  4. Accept-language:zh-CN

  5. referer (*****)告诉服务器当前请求是从那个url发出的可以用来防止盗取链接

    统计工作

  6. connection 是否连接复用

request,response的来历

服务器解析http请求之后

  1. 服务器先根据路径找到servlet
  2. 服务器创建request对象和response对象,将http请求中的数据封装进去
  3. 服务器将request和response对象交给servlet加工处理
  4. 服务器将servlet处理后的request方法和response交给filter处理
  5. 服务器根据response生成响应消息返回浏览器客户端

request的继承体系结构

不同的协议,请求消息的数据结构不一样,所以request有不同的子接口

例如servletrequest,HttpservletRequest

ServletRequest –接口
|继承
HttpServletRequest –接口
|实现
org.apache.catalina.connector.RequestFacade (tomcat会创建这个类)

使用request

获取请求消息
  1. 获取请求行数据
  2. 获取请求头数据
  3. 获取请求体数据

1 获取请求行数据

例如 get /day14/demo1?name=zhangsan HTTP/1.1

  • 获取请求方式 String getMethod()
  • (*****)获取虚拟目录,通过虚拟目录可以映射到物理路径 String getcontextPath()
  • 获取servlet路径 String getServletPath()
  • 获取get方式的url参数 String getQuery()
  • (*****)获取请求URI String getRequestURI() 获取URL getRequestURL()
  • 获取协议版本 String getProtocol()
  • 获取客户端ip 如果请求头中包含X-forwarded-for或者X-real-ip字段,那么此方法会优先获取到此信息作为返回,如果不包含这些ip字段信息,会返回底层连接的ip String ggetRemoteAdrr()

关于虚拟目录

一般用户无法直接分辨URL中的虚拟目录部分和Servlet资源路径部分。对于一般用户来说,URL中的路径部分通常是不透明的,他们只会看到完整的URL,而无法直接分辨其中的虚拟目录和Servlet资源路径。

虚拟目录和Servlet资源路径的概念主要是针对开发者和服务器端的应用程序来说的,用于确定请求应该由哪个Servlet或资源来处理。一般用户通常只需要关注完整的URL路径,而无需关心其中的具体细节。

因此,对于普通用户来说,URL路径通常是作为整体来使用的,而不需要区分其中的虚拟目录和Servlet资源路径部分。这些细节主要由开发者和服务器端来管理和处理。

2 获取请求头数据

  • 通过请求头属性名获取值 String getHeader(String name)
  • 获取所有请求头属性名 Enumeration<String> getHeaderNames()

3 获取请求体数据

只有post方式才有请求体,其中封装了请求参数

因为请求体的参数类型不确定,请求体的大小也不确定,有二进制数据,也有文本数据参数

所以请求体的参数大都需要自己解析

  • 获取请求体流对象 BufferReader getReader() 获取字符输入流
  • ServletInputStream getInputStream() 获取字节流输入,可以操作任意数据类型

中文乱码问题

因为编码的问题,需要在request设置流的编码

request.setCharacterEncoding(“utf-8”)

输出流也需要设置

4 其他高效功能

(*****)获取请求参数的通用方法 String getParameter(string name )根据参数名称获取参数值

String[] getParameterValues(string name) 用于获取同一个参数多个值的类型

Enumeration<String> getParameterNames()获取所有参数名

Map<String,String> getParameterMap() 获取所有参数键值对

请求转发(而不是重定向)
是一种在服务器内部资源跳转方式,将请求交给其他servlet处理

好处->可以让servlet更加内聚,每个servlet专门做一件事情,减少耦合

方法:

  • 获取请求的转发对象
    因为servlet没有服务器根据请求调用servlet的功能,所以这个功能需要通过服务器的手段,服务器提供的手段就是转发对象 RequestDispatcher getRequestDispatcher(“path”)
  • 调用转发对象的forward方法 forward(request,response)

请求转发的特点:

  • 客户端不知道,浏览器url不变化
  • 只能转到服务器内部资源,不能转到外部资源
  • 转让发是一次请求,不会降低效率

共享数据

不同的域就有不同的作用范围,比如我在main函数中定义的一个对象,在main函数此代码后面的所有代码都可以使用这个对象,而在后面某个函数中定义的对象,在main调用无法使用

这就是不同的作用域的概念

servlet中的作用域如下:

request作用域,因为request每次请求服务器只会创建一个,所以本次请求中所有都在作用域中,通过setAttribute设置共享数据 getAttribute获取通过removeAttribute移除数据

获取servletContext

记得servlet接口中五个方法,除了生命周期的三个方法,还有getServletConfig和getServletInfo方法

其中getServletConfig能够获取到servlet的配置信息,大多是web.xml中的配置信息,而这个对象也能够获取到servletContext

servletContext 叫做servlet上下文环境,也就是servlet对象所在的域

每个servlet都能够获取到同一个SErvletContext

Http响应消息格式

response对象通过getWriter获取到输出字符流

我们通过向输出字符串输出相应内容


servlet 使用手册
https://wainyz.online/wainyz/2023/12/19/servlet 使用手册/
作者
wainyz
发布于
2023年12月19日
许可协议