(1)将一个类的接口转换成客户希望的另一个接口,是的原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式是Adapter,也称为Wrapper,是指如果一个接口需要B接口,但是待传入的对象却是A接口。
(2)编写一个Adapter的步骤如下:
实现目标接口,这里是Runnable。
内部持有一个待转换接口的引用,这里通过字段持有Callable接口。
在目标接口的实现方法内部,调用带转换接口的方法。
(1)今天我们访问网站,使用APP时,都是基于Web这种Browser/Server模式,它的特点是,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只要请求服务器,获取Web页面,并把Web页面展示给客户即可。Web页面具有极强的交互性,由于Web页面使用HTML编写的,而HTML具备超强的表现力,并且,服务器端升级后,客户端无需任何部署就可以使用到新的版本,因此,BS架构升级非常容易。
(2)在Web应用中,浏览器请求一个URL,服务器就把生成的HTML网页发送给浏览器,而浏览器和服务器之间的传输协议是HTTP,所以:
HTML是一种用来定义网页的文本,会HTML就可以编写网页。
HTTP是在网络上传输HTML的协议,用于浏览器和服务器的通信。
(3)对于浏览器来说,请求页面的流程如下:
1.与服务器建立TCP连接。
2.发送HTTP请求
3.收到HTTP响应,然后把网页在浏览器中显示出来。
(4)浏览器发送的HTTP请求如下:
GET / HTTP/1.1
Host: www.sina.com.cn
User-Agent: Mozilla/5.0 xxx
Accept: /
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8
其中,第一行表示使用GET请求获取路径为/的资源,并且使用HTTP/1.1协议,从第二行开始,每行都是以Header:value形式表示的HTTP头,比较常用的HTTP Header包括:
Host:表示请求的主机名,因为一个服务器上可能运行这多个网站,Host表示浏览器正在请求的域名;
User-Agent:标识客户端本身,例如Chrome浏览器的标识类似Mozilla/5.0 … Chrome/79,IE浏览器的标识类似Mozilla/5.0 (Windows NT …) like Gecko;
Accept:标识浏览器能接收的资源类型,如text/*,image/*。
Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页。
Accept-Encoding:表示浏览器可以支持的压缩类型。
(5)服务器的响应类型如下:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 21932
Content-Encoding: gzip
Cache-Control: max-age=300
…网页数据…
服务器响应的第一行总是版本号+空格+数字+空格+文本,数字表示响应代码,其中2xx表示成功,3xx表示重定向,4xx表示客户端引发的错误,5xx表示服务器端引发的错误。数字是给程序识别,文本则是给开发者调试使用的。常见的响应代码有:
200 OK:表示成功;
301 Moved Permanently:表示该URL已经永久重定向。
302 Found:表示该URL需要临时重定向。
304 Not Found:表示该URL没有修改,客户端可以使用本地缓存的版本
400 Bad Request:表示客户端发送了一个错误的请求,例如参数无效
401 Unauthorized:表示客户端因为身份未验证而不允许访问该url;
403 Forbidden:表示服务器因为权限问题拒绝了客户端的请求;
404 Not Found:表示客户端请求了一个不存在的资源
500 Internal Server Error:表示服务器处理时内部出错,例如因为无法连接数据库
503 Servie Unavailable:表示服务器此刻暂时无法处理请求
(6)从第二行开始,服务器每一行均返回一个HTTP头,服务器经常返回的HTTP Header包括:
Content-Type:表示该响应内容的类型,例如test/html,image/jpeg
Content-Length:表示该响应内容的长度(字节数)
Content-Encoding:表示该响应压缩算法,例如gzip
Cache-Control:指示客户端如何缓存,例如max-age=300表示最多缓存300秒
(7)HTTP请求和响应都由HTTP Header和HTTP Body构成,其中HTTP Header每行都以\n\r 结束。如果遇到两个连续的\n\r,那么后面就是HTTP Body。浏览器读取HTTP Body,并根据Header信息中指示的Content-Type、Content-Encoding等解压后显示网页、图像或其他内容。通常浏览器获取的第一个资源是HTML网页,在网页中如果嵌入了JavaScript、CSS、图片、视频等其他资源,浏览器会根据资源的URL再次请求对应的资源。
(8)HTTP目前有多个版本,1.0是早期版本,浏览器每次建立TCP连接后,只发送一个HTTP请求并接收一个HTTP响应,然后就关闭TCP连接,由于创建TCP连接本身就需要消耗一定的时间,因此,HTTP1.1允许浏览器和服务器在同一个TCP连接上反复发送、接收多个HTTP请求和响应,这样就大大提高了传输效率。
我们注意到HTTP协议是一个请求-响应协议,它总是发送一个请求,然后接收一个请求,能不能一次发送多个请求,然后再接收多个响应呢?HTTP2.0可以支持浏览器同时发出多个请求,但每个请求需要唯一标识,服务器可以不按请求的顺序返回多个响应,由浏览器自己把收到的响应和请求对应起来。可见,HTTP2.0进一步提高了传输效率,因为浏览器发出一个请求后,不必等待响应,就可以继续发出下一个请求。
HTTP3.0为了进一步提高速度,将抛弃TCP协议,改为使用无需创建连接的UDP协议,目前HTTP3.0仍然处于实验阶段。
(1)在JavaEE平台上,处理TCP连接,解析HTTP协议这些底层工作统统扔给现成的Web服务器上,为了实现这一目的,JavaEE提供了Servlet API,我么您使用Servlet API来编写自己Servlet来处理HTTP请求,Web服务器实现Servlet API接口,实现底层功能。
(2)一个Servlet总是继承自HttpServlet,然后覆写doGet()或者doPost()方法。注意到doGet()方法传入了HttpServletRequest和HttpServletReponse两个对象,分别代表HTTP请求和响应。我们使用Servlet API时,并不直接与底层TCP交互,也不需要解析HTTP协议,因为HttpServletRequest和HttpServletResponse就已经封装好了请求和响应。以发送响应为例,我们只需要设置正确地响应类型,然后获取PrintWriter,写入响应。
(3)实际上,类似Tomcat这样的服务器也是java编写的额,启动Tomcat服务器实际上是启动Java虚拟机,执行Tomcat的main方法,然后Tomcat负责加载我们的.war文件,并且创建一个HelloServlet实例,最后以多线程的模式来处理HTTP请求。如果Tomcat收到的请求路径是/,就转发HelloServlet并传入HttpServletRequest和HttpServletReponse两个对象。因为我们编写的Servlet并不是直接运行,而是由Web服务器加载后创建实例运行,所以,类似Tomcat这样的Web服务器也称为Servlet容器。在Servlet容器中运行的Servlet具有如下特点:
无法在代码中直接通过new创建Servlet实例,必须由Servlet容器自动创建Servlet实例;
Servlet容器只会给每个Servlet类创建实例;
Servlet容器会使用多线程执行doGet()或者doPost()方法。
(4)复习一下Java多线程的内容,我们可以得出结论:
在Servlet中定义的实例变量会被多个线程同时访问,要注意线程安全。
HttpServletRequest和HttpServletResponse实例是由Servlet容器传入的局部变量,他们只能被当前线程访问,不存在多个线程访问的问题;
在doGet()或者doPost()方法中,如果使用了ThreadLocal,但没有清理,那么它的状态很可能会影响到下次的某个请求,因为Servlet容器很可能使用线程池实现线程复用。
(1)Servlet就是一个能处理HTTP请求,发送HTTP响应的小程序,而发送响应无非就是获取PrintWriter,然后输出HTML,只不过,用PrintWriter输出HTML比较痛苦,因为不但要正确编写HTML,还需要插入各种变量。如果想要在Servlet中输出一个类似新浪首页的HTML,写对HTML基本上不太可能。
(2)JSP是Java Server Pages的缩写,它的文件必须放到/src/main/webapp下,文件名必须以.jsp结尾,整个文件与HTML并无太大区别,但需要插入变量,或者动态输出的地方,使用特殊指令<%…%>。
(3)JSP和Servlet没有任何区别,因为JSO 在执行前首先被编译成一个Servlet。
(1)Servlet适合编写Java代码,实现各种复杂的业务逻辑,但不适合输出复杂的HTML,JSP适合编写HTML,并在其中插入动态内容,但不适合编写复杂的Java代码。
(2)MVC设计模式:Model-View-Controller,即UserServlet作为控制器(Controller),User作为模型(Model),user.jso作为视图(View),整个MVC架构如下:
使用MVC模式的好处是,Controller专注于业务处理,它的处理结果就是Model。Model可以是一个JavaBean,也可以是一个包含多个对象的Map,Controller只负责把Model传递给View,View只负责把Model给渲染出来,这样三者职责明确,且开发简单,因为开发Controller时无需关注页面,开发View时无需关心如何创建Model。
(1)通过结合Servlet和JSP的MVC模式,我们可以发挥二者各自的优点:Servlet实现业务逻辑,JSO实现展示逻辑。但是,直接把MVC搭在Servlet和JSP之上还是不太好,原因如下:
Servlet提供的接口仍然偏底层,需要实现Servlet调用相关接口;
JSP对页面开发不友好,更好地替代品是末班引擎;
业务逻辑最好由纯粹的Java类实现,而不是强迫继承自Servlet。
(2)一个MVC框架是基于Servlet基础抽象出更高级的接口,使得上层基于MVC框架的开发可以不涉及Servlet相关的HttpServletRequest等接口,处理多个请求更加灵活,并且可以使用任意模板引擎,不必使用JSP。