Servlet

目录

一.Servlet运行原理

二.ServletAPI

1.HttpServlet

常见面试题

乱码问题:

2.HttpServletRequest

2.1 获取GET请求中的参数

2.2获取POST请求中的参数

2.3获取POST请求中的参数(json) 

 3.HttpServletResonse

3.1设置状态码

3.2自动刷新 

3.3 重定向 

4.Cookie和Session

4.1 什么是Cookie

4.2 什么是Session 

4.3 Cookie和Session的区别

4.4 相关方法

注意事项


一.Servlet运行原理

在Servlet的代码中我们并没有写main方法,那么对应的do Get代码是如何被调用的呢?响应又是如何返回给浏览器的?

这个代码是基于在Tomcat的基础上运行的

上面的流程图,表示的是Web Browser是客户端,通过HTTP协议发给HTTP服务器,即Tomcat.Tomcat拿到了HTTP请求后,就会对请求的进行解析成一个HTTPServletRequest对象,我们调用Servlet类,来执行程序员写好的逻辑(Servlet Program).

1.接收请求:

  • 用户在浏览器输入一个URL,此时浏览器就会构造一个HTTP请求.
  • 这个HTTP请求会经过网络协议栈逐层进行封装成二进制的bit流,最终通过物理层的硬件设备转换成光信号/电信号传输出去.
  • 这些继承信息的光信号/电信号通过互联网上的一系列网络设备,最终到达目标主机(这个过程也需要通过网络层和数据链路层参与).
  • 服务器主机收到这些光信号/电信号,又会通过网络协议栈逐层进行分用,层层解析,最终还原成HTTP请求,并交给Tomcat进程进行处理(根端口号确定进程)
  • Tomcat通过Socket读取到这个请求(一个字符串),并按照HTTP请求的格式来解析这个请求.根据请求中的Context Path确定一个webapp,再通过Servlet Path确定一个具体的类.再根据当前请求的方法(GET/POST/...),决定调用这个类的doGET/doPOST方法的第一个参数HttpServletRequest就包含了这个HTTP请求的详细信息.

2.根据请求计算响应

在我们的doGet/doPost方法中, 就执行到了我们自己的代码,我们自己的代码会根据请求中的一些信息,来给HttpServletRespons对象设置一些属性,例如状态码.header,body等 

二.ServletAPI

1.HttpServlet

我们写的Servlet代码的时候,首先第一步就是先创建类,继承HttpServlet,并重写其中的某些方法

常见面试题

说一下Servletd的生命周期

  1. Servlet在实例化之后调用一次init
  2. Servlet 每次收到请求,调用一次service
  3. Servlet 在销毁之前,调用一次 destroy

乱码问题:

当我们在body中写入中文后

在浏览器的控制台中查看body发现出现乱码了

原因是:IDEA中与浏览器的编码方式是不一样的,在IDEA中的编码方式UTF-8,而在浏览器中的编码方式是gbk

解决方案:

让浏览器按照UTF-8进行解析,则只要在响应中的header里面加上Conten-Type,在Context-Type里面注明响应的响应是UTF-8.

在webapp中创建一个html文件,在html中设置Get请求的按钮和POST请求的按钮,引入JQuery的第三方库来创建ajax表单,并且设置表单中的数据,发送的路径,打印日志的方法

<body>
    <button onclick="sendGet()">发送 Get 请求</button>
    <button onclick="sendPost()">发送 POST 请求</button>

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script>
        function sendGet() {
            $.ajax({
                type:"get",
                url:"method",
                sucess:function(data,status) {
                    console.log(data);//打印的是body
                }
            })
        }
        function sendPost() {
            $.ajax({
                type:"post",
                url:"method",
                data:"request body",//post方法中有正文
                sucess:function(data,status) {
                    console.log(data);
                }
            })
        }
    </script>
</body>

在doGet/doPost方法中设置Type 

 单单设置还不够,还要设置该项目的编码方式.

2.HttpServletRequest

这个类就表示一个http请求,理解这个类的前提就是理解http协议的格式.

http的请求的报文格式:

1.首行:方法类型,URL,版本号.URL中进一步分出来path,query string
2.header,一堆键值对,键值对的类型也很多
3.空行
4.body

在HttpServletRequst类中,有很多方法,能够将HTTP报文格式的内容分类出来,由Tomcat把字符串结构的请求解析成一个结构化的数据,即从字符串到结构化的数据,这样的过程称为反序列化.

通过这些方法可以,获取到一个请求中的各个方法的信息,请求对象是服务器收到的内容,不应该修改,因此上面的方法都只是读方法,而不是写方法.

注意: 

1.URL和URI的含义是类似的,都是网络上的一个资源,L指的是location(资源的位置),I是identity(资源的标识符)
2.String getQuerString()方法返回的是完整的query strung :如query string:a=10&b=20,返回的就是整个.而下面的三个方法,都是对应query string来操作的,第一个是返回的所有query string所有的key.以枚举返回.第二个是返回key对应的value.第三个是返回某个key的所有value值,返回的字符串数组类型,大多数用的参数是重复时候(可能参数为a=10&a=20)

3.下面这两个方法都是对header进行操作的

假设报头为:

那么第一个方法返回的是header头中的key.第二个方法返回的header头中对于的key的value值

2.1 获取GET请求中的参数

GET请求的参数一般都是通过query string传递给服务器/

https://v.bitedu.vip/personInf/student?userId=1111&classId=100
 

此时浏览器通过query string给服务器传递了两个参数,userId和classId值分别是1111和100,在服务器端可以通过getParamenter来获取参数的值

因此我们可以约定,在客户端中的quer string中假设只有两个参数,userId和classId,当我们从客户端访问服务器的时候,让服务器能够返回客户端中输入的userId和classId中的参数.

创建GetParameterServlet类

因为约定的参数只有userId和classId,因此调用getParameter的时候去查找名字相同的即可.

假设在客户端访问服务器的时候,没有带上参数(即127.0.0.1:8080/20220415/getParameter),那么页面显示为:

因此,如果当前的query string中key不存在,那么得到的value就是null. 

2.2获取POST请求中的参数

POST请求的参数一般通过body传递给服务器.body中的数据格式有很多种.如果采用form表单的形式,仍然可以通过getParameter获取参数的值.

我们知道Post请求的body中的格式有三种:

1.application/x-www-form-urlencoded.如:a=10&b=20,根query string类似
2.mutipart/from-data主要用来传输文件的生成一个分隔符.
3.application/json

使用第一种方式,getParameter方法来获取也是可以的

 我们需要写一个html页面来验证服务器的程序,此时使用form表单的形式即可.

此时在页面输入22:点击提交后

可以看到一个POST请求

2.3获取POST请求中的参数(json) 

我们按照JSON的格式传递,那么获取的参数也发生调整.需要解析成json格式的body,即获取到userId和classId里面具体的值,但是json的格式解析起来是比较复杂的,因为json里面可以再嵌套json.我们可以可以使用第三方库--Jackson Databind,这个库也适用于Spring全家桶.

注意:使用jackson解析成json的时候,需要先明确,要把这个字符串转成什么样的对象.

 

 3.HttpServletResonse

Servlet中的do...方法的目的就是根据请求计算得到响应,然后把响应的数据设置到HttpServletResponse对象中.然后Tomcat就会把这个HttpServletResponse对象按照HTTP协议的格式转成字符串,并通过Socket写回给浏览器.

 注意:响应对象是服务器返回给浏览器的内容,这里的重要的信息都是程序员设置的,因此上面的方法都是写方法.注意:对于状态码/响应头的设置要放到getWriter/getOutputStream之前,否则可能失效

3.1设置状态码

3.2自动刷新 

header中有一个属性--Refresh它的值就是隔多长时间刷新,单位是s

抓刷新后的包可以看到:

3.3 重定向 

重定向就是"呼叫转移",状态码是302,可以设置location字段重定向

此时我们客户端访问服务器,可以看到页面跳转到搜狗地址上了. 

4.Cookie和Session

4.1 什么是Cookie

因为HTTP是无状态的协议,无法根据之前的状态进行本次的请求处理,为了保留无状态协议这个特征,于是引入了Cookie信息来控制客户端的状态.Cookie会根据从服务器发送的响应报文内一个叫Set-Cookie的首部字段信息,通知客户端保存Cookie.当下次再给服务器发送请求的时候,客户端自动在请求报文中加入Cookie值后发送出去.
服务器端发现客户端发来的Cookie后,会检查是那一个客户端发送的连接请求,对比服务器上的记录,最后得到之前的状态信息

此时服务器这边就需要记录Cookie信息,这个就是Session机制所做的工作

4.2 什么是Session 

Session译为会话,Session是存储在服务端的,当客户端第一次访问服务器端的时候,服务端会把客户端的信息存储在服务器上,当客户端再次访问的时候,就可以通过Session中查找该客户端的状态就可以了,存储的方式类似于哈希表.

4.3 Cookie和Session的区别

  1. Cookie是保存在客户端,Session是保存在服务端
  2. Cookie不安全
  3. 单个Cookie保存的数据不超过4k
  4. Cookie和Session经常会在一起配合使用,但是不是必须配合 

4.4 相关方法

HttpServletRequest类中的相关方法

方法描述
HttpSession getSession()在服务器中获取会话. 参数如果为 true, 则当不存在会话时新建会话; 参数如果为 false, 则当不存在会话时返回 null
Cookie[] getCookies()返回一个数组, 包含客户端发送该请求的所有的 Cookie 对象. 会自动把Cookie 中的格式解析成键值对.

HttpServletResponse类相关方法

方法描述
void addCookie(Cookie cookie)把指定的 cookie 添加到响应中.

HttpSession类中的相关方法

方法描述
Object getAttribute(String name)该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 nu
void setAttribute(String name, Object value)该方法使用指定的名称绑定一个对象到该 session 会话
boolean isNew()判定当前是否是新创建出的会话

Cookie类中的相关方法

方法描述
String getName()该方法返回 cookie 的名称。名称在创建后不能改变。(这个值是 SetCooke 字段设置给浏览器的)
String getValue()该方法获取与 cookie 关联的值
void setValue(String newValue)该方法设置与 cookie 关联的值。

注意事项

  • 通过HttpServletRequest.getCookie()获取到请求中的一系列Cookie键值对,需要带有参数
  • 当为true的时候,如果session不存在,就会创建,如果存在,就获取session然后返回,当为false的时候,如果session不存在就会返回null,如果存在,就获取session然后返回
  • HTTP的cookie字段中存储的实际上是多组键值对,每个键值对在Servlet中都对应了一个Cookie对象,Cookie里主要有key和value两个属性.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值