服务器(二)——
一、传递JSON参数
1、request.getReader()——获取请求体中的内容
不能获取地址栏的参数,但是可以获取请求体中的参数。,所以不能用在 doGet()方法中。
如果通过 postman 直接传过来,那么参数格式会是这样:
2、了解 json
我们当然可以自己手动解析,但是那样太麻烦,要做字符串截取;如果是用 JSON ,那解析就十分的方便了:
像上图那种就是 json 格式了,键值对,中间用冒号 : 隔开。
像上图那种一看就可以创建一个对象,来接收 json 格式传过来的参数:
首先,要导入 json 包:
3、解析 json——ObjectMapper()
接收到请求体中的内容后,读取成字符串,然后通过 ObjectMapper(). readValue(x,x),把 json 格式的内容解析成对应的对象,然后就可以通过对象,方便的调用到里面的内容。
当然,readValue()的第一个参数也可以接收一个流进来:
注意:这里用的是流,不像 doGet()方法那样,可以多次使用,流接收了以后就没了(流只能读一次,读完就没了)。
二、小知识点总结
1、乱码问题
2、请求参数对应的解析方式
三、HttpServletResponse对象
1、能返回的东西
HttpServletResponse 能返回 json 格式的数据,字符串,还能写 html 页面。
html 页面:
json 格式: 注意:最后的 close 关流,这里的场景可以关,如果到框架部分,就不建议关了,因为可能框架后面还有什么操作到流的部分。
2、sendRedirect——页面跳转(客户端跳转)
客户端跳转(服务端只会浏览器跳转,服务端告诉浏览器去访问另外一个页面。总计浏览器发了两次请求)
a、直接调用 sendRedirect 方法
然后看页面:
点击之后:
可以看到,页面发生了跳转,路径发生了变化。此时点开 F12 查看:
状态码 302。正常成功的状态码是200。302的意思是:重定向。浏览器如果收到服务器的302响应就知道,服务器要它重新发一个新的请求,重新载入一个新的页面。那么重新载入什么页面呢:
看响应头里面,多了一个字段:Location。
b、手动设置重定向属性
c、跳转到 servlet
同理:
同样可以成功,区别在于这里不用写 . html。
3、getRequestDispatcher——服务端跳转
服务端跳转(只能站内跳转,且跳转后地址不会发生变化,用户输入的信息不会清空。总计浏览器只发了一次请求) 注意:比如是一个电商网站,如果采用了服务端跳转,这时用户下单了,页面变化,如果此时再刷新页面,会弹出类似这种页面:
如果用户点击继续,则会再次发送一个post请求。所以这种场景不适合使用服务端跳转,而应该用客户端跳转。
4、总结跳转
四、Servlet 生命周期
1、实例化
2、init()——初始化
3、service()——服务
4、destory()——销毁
5、Servlet 执行流程
五、Servlet 线程安全问题
Servlet 线程安全问题,对于现在来说,已经不用太过去考虑。
1、线程安全问题
2、如何保证线程安全
1、synchronized(同步锁):
将存在线程安全问题的代码放到同步代码块中
2、实现 SingleThreadModel 接口(此方式已淘汰):
servlet实现SingleThreadModel接口后,每个线程都会创建servlet实例,这样每个客户端请求就不存在共享资源的问题,
但是servlet响应客户端请求的效率太低,所以已经淘汰。
3、局部变量:
尽可能使用局部变量。
线程安全问题这一块,其实用的最多的都是局部变量这个方法,使用到全局变量基本很少,更不用说用到 synchronized 这个了。
六、Servlet 的并发能力
1、引入
当有请求到 Servlet 中时,会有个子线程分配过来处理请求:
看上图,这里是之前跳转的代码,打印线程名字,接着跳转之后,再打印一次线程名字:
看结果:
可以看到,线程名字是一样的,那么怎么体现 Servlet 的并发能力呢?
目前用的都是 Servlet 的阻塞请求。
阻塞请求:当请求到达Servlet 之后(不管哪个Servlet),从 Service 到 Dao,都是在同一个线程里面去处理: 如果 Servlet 的并发能力是100,当满负荷了以后,第101个请求到来,只能等待,这样的效率太低。现在的方案是:当有请求到达Servlet 时,Servlet 开启子线程,让请求去跑这个子线程,那么此时 Servlet 就空了出来可以去接收新的请求,这样效率大大提升
2、开启异步支持
如果要在 Servlet 里面开启子线程,的同时还想给用户返回数据,就要开启异步支持:
接着开启异步 Servlet 的处理:
|