JavaWeb三大组件之Servlet


一、基本概念

WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源。Internet上供外界访问的Web资源分为:

  1、静态web资源(如html 页面):指web页面中供人们浏览的数据始终是不变

  2、动态web资源:指web页面中供人们浏览的数据是由程序产生的,不同时间点访问web页面看到的内容各不相同。常用动态web资源开发技术:JSP/Servlet、ASP、PHP等,在Java中,动态web资源开发技术统称为Javaweb。

静态WEB中存在以下几个缺点:

  1、Web页面中的内容无法动态更新,所有的用户每时每刻看见的内容和最终效果都是一样的。为了可以让静态的WEB的显示更加好看,可以加入了JavaScript以完成一些页面上的显示特效,但是这些特效都是在客户端上借助于浏览器展现给用户的,所以在服务器上本身并没有任何的变化。

  2、静态WEB无法连接数据库,无法实现和用户的交互。使用数据库保存数据是现在大多数系统的选择,因为数据库中可以方便地管理数据,增删改查操作可以使用标准的SQL语句完成。

动态WEB:

所谓的动态不是指页面会动,主要的特性的是:“WEB的页面展示效果因时因人而变”,而且动态WEB具有交互性,WEB的页面的内容可以动态更新。整个动态WEB操作的过程图如下:

动态WEB中,程序依然使用客户端和服务端,通过网络(Network)连接到服务器上,使用HTTP协议发起请求(Request),现在的所有请求都先经过一个WEB Server Plugin(服务器插件)来处理,此插件用于区分是请求的是静态资源(*.htm或者是*.htm)还是动态资源。

  • 如果WEB Server Plugin发现客户端请求的是静态资源(*.htm或者是*.html),则将请求直接转交给WEB服务器,之后WEB服务器从文件系统中取出内容,发送回客户端浏览器进行解析执行。
  • 如果WEB Server Plugin发现客户端请求的是动态资源(*.jsp、*.asp/*.aspx、*.php),则先将请求转交给WEB Container(WEB容器),在WEB Container中连接数据库,从数据库中取出数据等一系列操作后动态拼凑页面的展示内容,拼凑页面的展示内容后,把所有的展示内容交给WEB服务器,之后通过WEB服务器将内容发送回客户端浏览器进行解析执行。

二、WEB服务器

对于“Web服务器”的多种定义和解读:

  1. Web服务器,一般是指“网站服务器”,是指驻留于互联网上某种类型计算机的程序。Web服务器可以向Web浏览器等客户端提供文档,也可以放置网站文件,让全世界浏览,更可以放置数据文件,让全世界下载。
  2. Web服务器是一种被动程序,只有当互联网上运行的、其他计算机中的浏览器发出请求时,Web服务器才会响应。
  3. Web服务器,是指驻留于互联网上某种类型计算机的程序。当Web浏览器(客户端)连到Web服务器上,并请求文件时,Web服务器将处理该请求,并将文件发送反馈到Web浏览器上,附带的信息会告诉Web浏览器如何查看该文件。由于Web服务器,使用HTTP(超文本传输协议)与客户机浏览器进行信息交流,所以人们常把它们称为“HTTP服务器”。

目前最常用的Web服务器是: Apache (阿帕奇)的Tomcat服务器和 Microsoft(微软)的互联网信息服务器(英文全写:Internet Information Services,缩写:IIS,即“互联网信息服务”)。

三、Tomcat服务器

学习web开发,为什么必须要先装一个WEB服务器?

  在本地计算机上随便创建一个web页面,用户是无法访问到的,但是如果启动tomcat服务器,把web页面放在tomcat服务器中,用户就可以访问了。这说明什么问题?
  1、不管什么web资源,想被远程计算机访问,都必须有一个与之对应的网络通信程序,当用户来访问时,这个网络通信程序读取web资源数据,并把数据发送给来访者。
  2、WEB服务器就是这样一个程序,它用于完成底层网络通迅。使用这些服务器,We应用的开发者只需要关注web资源怎么编写,而不需要关心资源如何发送到客户端手中,从而极大的减轻了开发者的开发工作量。


 【1】Servlet简介

 > 意为:运行在服务器端的小程序。

        > Servlet实际上就是一个接口。             - 狭义上的Servlet,指的就是Servlet接口             - 广义上的我们认为凡是实现Servlet接口的类,我们都称他是一个Servlet          > Servlet的作用:             1.接收用户发送的请求             2.调用其他的java程序来处理请求             3.根据处理结果,返回给用户一个页面   > Servlet的HelloWorld             1.创建一个类并实现Servlet接口             2.在web.xml文件中对Servlet进行配置                                     别名                     全类名                                                     别名                     需要servlet处理的请求地址                

【2】Servlet的生命周期

  > Servlet的生命周期,指Servlet的对象从被创建到被销毁的过程。         > Servlet的生命周期方法:             1.构造器:                 - Servlet第一次处理请求时,会调用构造器,来创建Servlet实例。                 - 只会调用一次,Servlet是单例模式,他是以多线程的方式调用service()方法.                 - Servlet不是线程安全,所以尽量不要再service()方法中操作全局变量。               2.init()方法:                 - 构造器调用之后马上被调用,用来初始化Servlet,只会调用一次。               3.service()方法:                 - Servlet每次处理请求时都会调用service()方法,用来处理请求,会调用多次。               4.destroy()方法:                 - Servlet对象销毁前(WEB项目卸载时)调用,用来做一些收尾工作,释放资源。

[3] 相关接口

①ServletConfig             代表:当前Servlet的配置信息,每一个Servlet都有其唯一对应的ServletConfig。                                     AServlet                     com.atguigu.servlet.AServlet                                             user                         root                                                                 password                         123123                                                   获取:由Tomcat服务器创建,最终作为参数传递到init()方法中,我们可以在init()方法直接使用。                     当我们通过继承HttpServlet创建Servlet时,由于父类已经实现ServletConfig接口,                         所以我们可以在Servlet中直接调用ServletConfig的方法。               功能:                 【1】 获取Servlet的别名                 【2】 获取当前Servlet的初始化参数。                                                     user                             root                                                                             password                             123123                                         【3】 获取当前WEB应用的ServletContext对象。           ②ServletContext

    代表:当前的WEB应用,一个WEB应用对应一个唯一的ServletContext对象,

                  ServletContext对象在项目启动时创建,在项目卸载时销毁。               获取:通过ServletConfig的getServletContext()方法获取。               功能:                 【1】 可以获取整个WEB应用的初始化参数                                             phone                         1388888888                                     【2】 可以获取资源的真实路径(物理路径),主要在文件的上传和下载时使用。                 【3】 可以作为一个域对象在不同的web资源之间共享数据。  

[4] GenericServlet

        - 通用Servlet的父类         - 相比Servlet接口GenericServlet更加简单一些,但是我们最终实际上使用的是 HttpServlet

[5] HttpServlet

- HttpServlet继承了GenericServlet,而GenericServlet实现Servlet接口

        - 所以我们可以同构继承HttpServlet来创建一个Servlet。         - HttpServlet重写service()方法:             1.在该方法中先将ServletRequest和ServletResponse                 强转为了HttpServletRequest和HttpServletResponse。             2.然调用重载的service()方法,并将刚刚强转得到对象传递到重载的方法中。         - 重载service(HttpServletRequest request , HttpServletResponse response)             1.在方法中获取请求的方式(get或post)             2.在根据不同的请求方式去调用不同的方法:                 如果是GET请求,则调用doGet(HttpServletRequest request , HttpServletResponse response)                 如果是post请求,则调用doPost(HttpServletRequest request , HttpServletResponse response)         - 结论:             当通过继承HttpServlet来创建一个Servlet时,我们只需要根据要处理的请求的类型,来重写不同的方法。                 处理get请求,则重写doGet()                 处理post请求,则重写doPost()

[6] HttpServletRequest

  代表:浏览器发送给服务器的请求报文。

        获取:该对象由Tomcat服务器创建,最终作为参数传递到doGet或doPost方法中,我们可以在这两个方法中直接使用。         功能:             【1】获取用户发送的请求参数                 request.getParameter("username");             【2】获取项目的名字(用来设置绝对路径)                 request.getContextPath();             【3】作为一个域对象,在不同的WEB资源之间共享数据。             【4】请求的转发                 request.getRequestDispatcher("target.html").forward(request, response);

[7] HttpServletResponse

        代表:服务器发送给浏览器的响应报文。         获取:该对象由Tomcat服务器创建,最终作为参数传递到doGet或doPost方法中,我们可以在这两个方法中直接使用。         功能:             【1】响应给浏览器一个网页或者是网页片段(设置的是响应报文的响应体)                 response.getWriter("");             【2】请求的重定向                 response.sendRedirect("target.html");       转发和重定向:(掌握)                                   转发                    重定向         请求的次数:            1                         2         发生的位置            服务器内部               浏览器         浏览器地址栏        不改变                    改变         浏览器的感知        不知道                    知道     

[8] 字符编码

> 当用户通过表单向Servlet发送中文请求参数时,Servlet获取到内容会产生乱码, 当Servlet向浏览器响应中文内容时,也会产生乱码。         > 浏览器和服务器之间通信时,中文内容时不能直接发送的,需要对中文进行编码。         > 编码:             - 将字符转换为二进制码的过程叫编码。         > 解码:             - 将二进制码转换为普通字符的过程叫解码。         > 编码和解码所采用的规则我们称为字符集。           > 产生乱码问题的根本原因:             编码和解码所采用的字符集不同。           > 解决方法:             统一编码和解码的字符集为UTF-8。   > 常见字符集:             1.ASCII             2.ISO8859-1             3.GBK             4.GB2312             5.UTF-8   > 请求编码             - 请求是浏览器发送给服务器的。             - 浏览器 --> 服务器             - 浏览器 编码                 > 浏览器的会自动使用网页的字符集对参数进行编码                   UTF-8的张三:%E5%BC%A0%E4%B8%89                   GBK的张三:%D5%C5%C8%FD                   > 所以我们只需要统一网页的字符集为UTF-8即可。               - 服务器 解码                 post请求                     > request解码时默认字符集时iso8859-1,但是iso压根就不支持中文                     > post请求在servlet中解码,所以我们只需要指定request的字符集即可。                     > 我们可以通过如下方法,来设置request的字符集:                         request.setCharacterEncoding("utf-8");                     > 注意:                         该方法要在request.getParameter()第一次调用之前调用                   get请求                     > get请求是通过url地址传递请求参数,url中的请求参数将会被Tomcat服务器自动解码。                     > Tomcat的默认编码是iso8859-1,但是iso压根就不支持中文,所以必然乱码。                     > 只需要修改Tomcat的解码的默认字符集,修改配置文件server.xml                     > 在server.xml的Connector标签中(改端口号的那个标签)添加如下属性:                         URIEncoding="utf-8"                     > 修改完配置文件以后,get请求的编码就不用再处理的,但是post请求还是老样子。           > 响应编码             - 响应是服务器发送给浏览器             - 服务器 --> 浏览器             - 服务器 编码                 > 指定服务器的编码字符集为UTF-8。                 > 指定response的字符集                     response.setCharacterEncoding("utf-8");                 > 虽然我们已经指定了response的字符集为utf-8,但是浏览器并不是用utf-8解码。                     浏览器默认使用gb2312解码的,所以依然乱码,只不过没有那么乱。               - 浏览器 解码                 > 浏览器的解码字符集可以通过浏览器来设置(不靠谱)                 > 我们可以通过服务器来告诉浏览器,我们的内容的编码格式为utf-8                 > 我们可以通过一个响应头来告诉浏览器,内容的编码格式:                     Content-Type:text/html;charset=utf-8                 > 通过response的方法,来设置响应头:                     response.setHeader("Content-Type", "text/html;charset=utf-8");               解决方案:                 1.设置响应头                     response.setHeader("Content-Type", "text/html;charset=utf-8");                 2.设置response的编码格式                     response.setCharacterEncoding("utf-8");                   > 当我们设置Content-Type这个响应头时,服务器会自动使用响应头中的字符集为内容编码。                   > 最终方案:                     response.setContentType("text/html;charset=utf-8");  

[9] 路径问题

> URI和URL

- URI,统一资源标志符(Uniform Resource Identifier, URI),表示的是web上每一种可用的资源,如 HTML文档、图像、视频片段、程序等都由一个URI进行标识的。URI只是一种概念,怎样实现无所谓,只要它唯一标识一个资源就可以了。

- URL是URI的一个子集。它是Uniform Resource Locator的缩写,译为“统一资源定位符”。

> 总结:只要能唯一标识资源的就是URI,在URI的基础上给出其资源的访问方式的就是URL

> URL地址的格式             http://主机名:端口号/项目名/资源路径/资源名           ①相对路径和绝对路径             > 相对路径                 - 所谓的相对路径指相对于当前资源所在路径:                     http://主机名:端口号/项目名/资源路径/             - 由于转发的出现,相对路径会经常发生变化,容易出现错误的链接                 所以在开发中我们一般不使用相对路径,而是使用绝对路径。               > 绝对路径             - 绝对路径使用 / 开头                - 由浏览器解析的绝对路径中的 / 代表的是服务器的根目录:                 http://主机名:端口号/                 注意:指定路径时需要加上项目名               - 由服务器解析的绝对路径中的 / 代表的项目的根目录:                 http://主机名:端口号/项目名/                 注意:指定路径时不要加项目名               - 转发的路径由服务器解析,设置绝对路径时不需要加项目名             - 重定向的路径由浏览器解析,设置绝对路径时需要加上项目名             ②常见的路径:             url-pattern:             转发的路径:                 - url-pattern和转发中的路径都是由服务器解析的,                     根目录是项目的根目录:                         http://主机名:端口号/项目名/                 - 所以这两个路径不需要加项目名               重定向的路径:             页面中的路径:                 - 重定向和页面中的路径(HTML标签中的路径),由浏览器解析的,                     根目录是服务器的根目录:                         http://主机名:端口号/                 - 所以这个两个路径必须加上项目名  

[10]运行的流程