Servlet完整笔记

Servlet规范

1、servlet规范来自于JAVAEE规范中的一种

2、作用

指定动态资源文件开发步骤

指定Http服务器调用动态资源文件规则

指定Http服务器管理动态资源文件实例对象规则

Servlet接口实现类

1、Servlet接口来自于Servlet规范下一个接口,这个接口存在Http服务器,提供jar包

2、Tomcat服务器下lib文件有一个servlet-api.jar存放Servlet接口(javax.servlet.Servlet接口)

3、Servlet规范中任务,Http服务器能调用的动态资源文件必须是一个Servlet接口实现类

class Student(){

//不是动态资源文件,Tomcat无权调用

}

class Teacher implements Servlet(){

// 合法动态资源文件,Tomcat有权利调用

Servlet obj = new Teacher();

obj.doGet();

}

Servlet接口实现类开发步骤:

第一步:创建一个Java类继承HttpServlet父类,使之成为一个Servlet接口实现类

第二步:重写HttpServlet父类两个方法。doGet或者doPost

第三步:将Servlet接口实现类信息 在注册到Tomcat服务器

网站->web->web-inf->web.xml

//将Servlet接口实现类类路径地址交给Tomcat

<servlet>

//声明一个变量存储servlet接口实现类类路径

<servlet-name>oneServlet</servlet-name>

//声明servlet接口实现类类路径

<servlet-class>com.li.controller.OneServlet</servlet-class>

</servlet>

Tomcat String oneServlet = "com.li.controller.OneServlet";

为了降低用户访问Servlet接口实现类难度,需要设置简短请求别名

<servlet-mapping>

<servlet-name>oneServlet</servlet-name>

<url-pattern>/one</url-pattern>

</servlet-mapping>

如果现在浏览器向Tomcat索要OneServlet地址:http://localhost:8080/myWeb/one

Servlet对象声明周期:

1、网站中所有的Servlet接口实现类的实例对象,只能由Http服务器负责创建,开发人员不能手动创建Servlet接口实现类的实例对象。

2、在默认的情况下,Http服务器接收到对于当前Servlet接口实现类第一次请求时自动创建这个Servlet接口实现类的实例对象。

在手动配置情况下,要求Http服务器在启动时自动创建某个Servlet接口实现类的实例对象

<servlet>

<servlet-name>OneServlet</servlet-name>

<servlet-class>com.li.controller.OneServlet<servlet-class>

<load-on-startup>30<load-on-startup>

</servlet>

3、在Http服务器运行期间,一个Servlet接口实现类只能被创建出一个实例对象

4、在Http服务器关闭时刻,自动将网站中所有的Servlet对象进行销毁

响应接口和请求接口

HttpServletResponse接口:

1、介绍:

1、HttpServletRresponse接口来自于Servlet规范中,在Tomcat中存在servlet-api.jar

2、HttpServletResponse接口实现类由Http服务器负责提供

3、HttpServletResponse接口负责将doGet/doPost方法执行结果写入到响应体交给浏览器

4、开发人员习惯将HttpServletResponse接口修饰的对象称为响应对象

2、主要功能:

1、将执行结果以二进制形式写入到响应体

2、设置响应头中 content-type 属性值,从而控制浏览器使用

对应编译器将形影提二进制数据编译为 文字,图片,视频,命令

3、设置响应头中 location 属性,将一个请求地址赋值给location

从而控制浏览器向指定服务器发送请求

java 复制代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception{
    //既有文字信息又有html标签
    String result = "Java<br>MySQL<br>HTML<br/>";
    String result2 = "糖酥里脊";
    //设置响应头content-type
    response.setContentType("text/html;charset=utf-8");
    //向Tomcat索要输出流
    PrintWriter writer = response.getWriter();
    //通过输出流写入到响应体
    writer.print(result);
    writer.print(result2);
}


protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception{
    int result = 65;
    PrintWriter writer = response.getWriter();
    //用这个方法,参数传一个数字,会输出对应的ASCII码
    writer.write(result);
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception{
    String result = "http://www.baidu.com?username=jack";
    //通过响应对象,将地址赋值给响应头中location属性
    /*
    浏览器在接收到响应包之后,如果发送响应头中存在location属性
    自动通过地址栏location指定网站发送请求
    sendRedirect方法远程控制浏览器请求行为 请求地址,请求方式,请求参数
    */
    response.sendRedirect(result);
}

HttpServletRequest接口:

1、介绍:

1、HttpServletRequest接口来自于Servlet规范中,在Tomcat中存在servlet-api.jar

2、HttpServletRequest接口实现类由Http服务器负责提供

3、HttpServletRequest接口负责在doGet/doPost方法运行时读取Http请求协议包中信息

4、开发人员习惯于将HttpServletRequest接口修饰的对象成为请求对象

2、作用:

1、可以读取Http请求协议包中请求行信息

2、可以读取保存在Http请求协议包中请求头或者请求体请求参数信息

3、可以代替浏览器向Http服务器申请资源文件调用

java 复制代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception{
    //通过请求对象,读取请求行中url信息
    String url = request.getRequestURL().toString();
    //通过请求信息,读取请求行中method信息
    String method = request.getMethod();

    String URI = request.getRequestURI();
    
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception{
    //通过请求对象获得请求头中所有请求参数名
    Enumeration<String> parameterNames = request.getParameterNames();

    while(parameterNames.hasMoreElements()){
        String s = parameterNames.nextElement();
        String value = request.getParameter(s);
    }
}

问题:

以get方式发送中文参数内容"糖炒栗子",得到正常结果

以post方式发送中文参数内容"五香瓜子",得到乱码

原因:

浏览器以get方式发送请求,请求参数保存在请求头,在Http请求协议包到达Http服务器之后,第一件事就是进行解码,请求头二进制内容有Tomcat负责解码,Tomcat9.0默认使用utf-8字符集,可以解释一切国家文字

浏览器以post方式发送请求,请求参数保存在请求体,在Http请求协议包到达Http服务器之后,第一件事就是进行解码,请求体二进制内容由当前请求对象(request)负责解码。request默认使用ISO-8859-1字符集。此时如果请求体参数内容是中文,将无法解码只能得到乱码。

解决方案:

在post请求方式下,在读取请求体内容之前,应该通知请求对象使用utf-8字符集对请求体内容进行一次重新解码request.setCharacterEncoding("utf-8");

java 复制代码
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws Exception{
    //通知请求对象,使用utf-8字符集对请求体二进制内容进行一次重写解码
    request.setCharacterEncoding("utf-8");
    //通过请求对象,读取请求体参数信息
    String username = request.getParameter("username");
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception{
    //通过请求对象,读取请求头参数信息
    String username = request.getParameter("username");
    System.out.println("请求头中得到的参数信息为" + username);
}

请求对象和响应对象生命周期:

1、在Http服务器接收到浏览器发送得到Http请求协议包之后

自动为当前的Http请求协议包生成一个请求对象和一个响应对象

2、在Http服务器调用doGet/doPost方法时,负责将请求对象和响应对象

作为实参传递到方法,确保doGet/doPost正确执行

3、在Http服务器准备推送Http响应协议包之前,负责将本次请求关联的请求对象和响应对象销毁请求对象和响应对象声明周期贯穿一次请求的处理过程中,请求对象和响应对象相当于用户在服务端的代言人。

欢迎资源文件

如果是动态资源文件,写入别名就可以,别名前面的/要去掉

1、前提:

用户可以记住网站名,但是不会记住网站资源文件名

2、默认欢迎资源文件:

用户发送一个针对某个网站的默认请求时,

此时由Http服务器自动从当前网站返回的资源文件

正常请求:http://localhost:8080/myWeb/index.html

默认请求:http://localhost:8080/myWeb/

3、Tomcat对于默认欢迎资源文件定位规则:

规则位置:

Tomcat安装位置/conf/web.xml

规则命令:

<welcome-file-list>

<welcome-file>index.html</welcome-file>

<welcome-file>index.jsp</welcome-file>

</welcome-file-list>

4、设置当前网站的默认欢迎资源文件规则:

规则位置:

网站/web/WEB-INF/web.xml

规则命令:

<welcome-file-list>

//可以设置为动态资源文件,给个别名就行了

<welcome-file>user/add</welcome-file>

</welcome-file-list>

网站设置自定义默认文件定位规则,此时Tomcat自带定位规则将失效

重定向和请求转发

1、前提条件:

某些来自于浏览器发送请求,往往需要服务端中多个Servlet协同处理。

但是浏览器一次只能访问一个Servlet,导致用户需要手动通过浏览器发起多次请求才能得到服务。

这样增加用户获得服务难度,导致用户放弃访问当前网站。

2、提高用户使用感受规则:

无论本次请求涉及到多少个Servlet,用户只需要手动通知浏览器发起一次请求即可。

3、多个Servlet之间调用规则:

重定向解决方案

请求转发解决方案

重定向解决方案:

1、工作原理

用户第一次通过手动方式通知浏览器访问OneServlet

OneServlet工作完毕后,将TwoServlet地址写入到响应头location属性中,导致Tomcat将302状态码写入到状态行。

在浏览器接收到响应包之后,会读取302状态。此时浏览器自动根据响应头中location属性地址发起第二次请求,访问TwoServlet去完成请求中剩余任务。

2、实现命令:

response.sendRedirect("请求地址");

将地址写入到响应包中响应头中location属性

3、特征:

1、请求地址:

即可以把当前网站内容的资源文件地址发送得到浏览器,也可以把其他网站资源文件地址发送给浏览器

2、请求次数:

浏览器至少发送两次请求,但是只有第一次请求时用户手动发送。

后续请求都是浏览器自动发送的。

3、请求方式:

重定向解决方案中,通过地址栏通知浏览器发起下一次请求,因此

通过重定向解决方案调用的资源文件接收的请求方式一定是get

4、缺点:

重定向解决方法需要在浏览器与服务器之间进行多次往返,大量时间消耗在往返次数上,增加用户等待服务时间。

请求转发解决方案:

1、原理:

用户第一次通过手动方式要求浏览器访问OneServlet

OneServlet工作完毕后,通过当前的请求对象代替浏览器

向Tomcat在接收到这个请求之后。自动调用TwoServlet来完成剩余任务。

2、实现命令:

请求对象代替浏览器向Tomcat发送请求

RequestDispatcher report = request.getRequestDispatcher("/资源文件名");

report.forward(当前请求对象, 当前响应对象);

3、优点:

1、无论本次请求涉及到多少个Servlet,用户只需要手动通过浏览器发送一个请求

2、Servlet之间调用发送在服务端计算机上,节省服务端与浏览器之间往返次数,增加处理服务速度

4、特征:

1、请求次数:

在请求转发过程中,浏览器只发送一次请求

2、请求地址:

只能向Tomcat服务器申请调用当前网站下资源文件地址

request.getRequestDispatcher("/资源文件名")

3、请求方式:

在请求转发过程中,浏览器只发送一个Http请求协议包

参与本次请求的所有Servlet共享同一个请求协议包,因此这些Servlet接收的请求方式与浏览器发送的请求方式保持一致。

多个Servlet之间数据共享

多个Servlet之间数据共享实现方案:

1、数据共享:OneServlet工具完毕后,将产生数据交给TwoServlet来使用

2、Servlet规范中提供四种数据共享方案:

ServletContext接口,Cookie类,HttpSession接口,HttpServletRequest接口

ServletContext接口:

1、介绍:

来自于Servlet规范中一个接口。在Tomcat中存在servlet-api.jar,在Tomcat中负责提供这个接口实现类。

如果两个Servlet来自于同一个网站。彼此之间通过网站的ServletContext实例对象实现数据共享。

开发人员习惯于将ServletContext对象成为全局作用域对象。

2、工作原理

每一个网站都存在一个全局作用域对象。

这个全局作用域对象相当于一个Map

在这个网站中OneServlet可以将一个数据

存入到全局作用域对象,当前网站中其他

Servlet此时都可以从全局作用域对象得到

3、全局作用域对象声明周期:

1、在Http服务器启动过程中,自动为当前网站在内存中创建一个全局作用域对象

2、在Http服务器运行期间时,一个网站只有一个全局作用域对象

3、在Http服务器运行期间,全局作用域对象一直处于存活状态

4、在Http服务器准备关闭时,负责将当前网站中全局作用域对象进行销毁处理

4、命令:同一个网站 OneServlet将数据共享给TwoServlet

OneServlet{

public void doGet(HttpServletRequest request, HttpServletResponse response){

//通过请求对象向Tomcat索要当前网站中全局作用域对象

ServletContext application = request.getServletContext();

//将数据添加到全局作用域对象作为共享数据

application.setAttribute("key1", 数据);

}

}

TwoServlet{

public void doGet(HttpServletRequest request, HttpServletResponse response){

//通过请求对象向Tomcat索要当前网站中全局作用域对象

ServletContext application = request.getServletContext();

//从全局作用域对象得到指定关键字对应数据

Object 数据 = application.getAttribute("key1");

}

}

Cookie:

1、介绍:

1、Cookie来自于Servlet规范中一个工具类,存在于Tomcat提供servlet-api.jar中

2、如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务,此时借助于Cookie对象进行数据共享

3、Cookie存放当前用户的私人数据,在共享数据过程中提高服务质量

4、在现实生活场景中,Cookie相当于用户在服务端得到会员卡

2、原理:

用户通过浏览器第一次向myWeb网站发送请求申请OneServlet

OneServlet在运行期间创建一个Cookie存储与当前用户相关数据

OneServlet工作完毕后,将Cookie写入到响应头交还给当前浏览器。

浏览器收到响应包之后,将Cookie存储在浏览器的缓存中。

一段时间之后,用户通过同一个浏览器再次向myWeb网站发送请求申请TwoServlet时,浏览器需要无条件的将myWeb网站之间推送过来的Cookie,写入到请求头。

发送过去,此时TwoServlet在运行时,就可以通过读取请求头中Cookie中信息,得到OneServlet提供的共享数据。

3、实现命令:同一个网站 OneServlet 与 TwoServlet借助于Cookie实现数据共享

OneServlet{

public void doGet(HttpServletRequest request, HttpServletResponse response){

//创建一个cookie对象,保存共享数据

Cookie cookie = new Cookie("key1", "abc");

//cookie 相当于一个map

//一个cookie中只能存放一个键值对

response.addCookie(cookie);

}

}

TwoServlet{

public void doGet(HttpServletRequest request, HttpServletResponse response){

//调用请求对象从请求头得到浏览器返回的Cookie

Cookie[] arr = request.getCookies();

for(Cookie c : arr){

String key = c.getName();

String value = c.getValue();

}

}

}

4、Cookie销毁时机

在默认情况下,Cookie对象存放在浏览器的缓存中。因此只要浏览器关闭,Cookie对象就被销毁掉。

在手动设置情况下,解压要求浏览器将收纳的Cookie存放在客户端计算机的硬盘上,需要指定Cookie存活时间。

cookie.setMaxAge(60);

HttpSession接口:

1、介绍:

1、HttpSession接口来自于Servlet规范下一个接口,存在于Tomcat中servlet-api.jar其实现类由Http服务器提供。Tomcat提供实现类存在于servlet-api.jar。

2、如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户听服务,此时借助于HttpServlet对象进行数据共享。

3、开发人员习惯于将HttpServlet接口修饰对象成为会话作用域对象

2、HttpSession与Cookie区别:

1、存储位置:一个在天上,一个在地下

Cookie:存放在客户端计算机

HttpServlet:存放在服务端计算机内存

2、数据类型:

Cookie对象存储共享数据类型只能是String

HttpSession对象可以存储任意类型的共享数据 Object

3、数据数量:

一个Cookie对象只能存储一个共享数据

HttpSession使用map集合存储共享数据,所以可以存储任意数量共享数据

4、参照物:

Cookie相当于客户在服务器端的会员卡

HttpSession相当于客户在服务端的私人保险柜

3、命令实现:同一个网站下OneServlet将数据传递给TwoServlet

OneServlet{

public void doGet(HttpServletRequest request, HttpServletResponse response){

//调用请求对象向Tomcat索要当前用户在服务端的私人储物柜

HttpSession session = request.getSession();

//将数据添加到用户私人储物柜

session.setAttribute("key1", 共享数据);

}

}

浏览器访问/myWeb中TwoServlet

TwoServlet{

public void doGet(HttpServletRequest request, HttpServletResponse response){

//调用请求对象向Tomcat索要当前用户在服务端的私人储物柜

HttpSession session = request.getSession();

Object value = session.getAttribute("key1");

}

}

4、Http服务器如何将用户与HttpSession关联起来

Cookie

5、getSession() 与 getSession(false)

确认用户身份后用以下方式

1、getSession():如果当前用户在服务端已经拥有了自己的私人储物柜,要求Tomcat将这个私人储物柜进行返回,如果当前用户在服务器尚未拥有自己的私人储物柜,要求Tomcat为当前用户创建一个全新的私人储物柜。

未确认用户身份用以下方式

2、getSession(false):如果当前用户在服务端已经拥有了自己的私人储物柜,要求Tomcat将这个私人储物柜进行返回,如果当前用户在服务端尚未拥有自己的私人储物柜,此时Tomcat将返回null。

6、HttpSession销毁时机:

1、用户与HttpSession关联时使用的Cookie只能存放在浏览器缓存中

2、在浏览器关闭时,意味着用户与它的HttpSession关系被切断

3、由于Tomcat无法检测浏览器何时关闭,因此在浏览器关闭时并不会导致Tomcat将浏览器关联的HttpSession进行销毁

4、为了解决这个问题,Tomcat为每一个HttpSession对象设置空闲时间,这个空闲时间默认30分钟。

7、HttpSession空闲时间手动设置

在当前网站/web/WEB_INF/web.xml

<session-config>

<session-timeout> 5 <session-timeout>

<session-config>

HttpServletRequest接口实现数据共享

1、介绍:

1、在同一个网站中,如果两个Servlet之间通过请求转发方式进行调用,彼此之间共享同一个请求协议包。而一个请求协议包只对应一个请求对象,因此servlet之间共享一个请求对象,此时可以利用这个请求对象在两个Servlet之间实现数据共享。

2、在请求对象实现Servlet之间数据共享功能时,开发人员将请求对象成为请求作用域对象

2、命令:OneServlet通过请求转发申请调用TwoServlet时,需要给TwwoServlet提供共享数据

OneServlet{

public void doGet(HttpServletRequest request, HttpServletResponse response){

//将数据添加到请求作用域对象中attribute属性

request.setAttribute("key1",数据);

//向Tomcat申请调用TwoServlet

request.getRequestDispatchet("two").forward(request, response);

}

}

TwoServlet{

public void doGet(HttpServletRequest request, HttpServletResponse response){

//从当前请求对象得到OneServlet写入到共享数据

Object data = request.getAttribute("key1");

}

}

监听器接口

1、介绍:

1、一组来自于Servlet规范下接口,共有八个接口。在Tomcat存放servlet-api.jar

2、监听器接口需要由开发人员亲自实现,Http服务器提供jar包并没有对应的实现类

3、监听器接口用于监控作用域对象生命周期变化时刻以及作用域对象共享数据变化时刻

2、作用域对象:

1、在Servlet规范中,认为在服务端内存中key在某些条件下为两个Servlet之间提供数据共享方案的对象,被称为作用域对象

2、Servlet规范下作用域对象:

ServletContext:全局作用域对象

HttpSession:会话作用域对象

HttpServletRequest:请求作用域对象

3、监听器接口实现类开发规范:三步

1、根据监听的实际情况,选择对应监听器接口进行实现

2、重写监听器接口声明监听事件处理方法

3、在web.xml文件将监听器接口实现类注册到Http服务器

<listener>

<listener-class>com.li.listener.OneListener</listener-class>

</listener>

4、ServletContextListener接口:

1、作用:通过这个接口合法的检测全局作用域被初始化时刻以及被销毁时刻

2、监听事件处理方法:

public void contextInitialized(); 在全局作用域对象被Http服务器初始化被调用

public void contextDestroy(); 在全局作用域对象被Http服务器销毁时触发调用

5、ServletContextAttributeListener接口:

1、作用:通过这个接口合法的检测全局作用域对象共享数据变化时刻

2、监听事件处理方法:

public void contextAdded(); 在全局作用域对象添加共享数据

public void contextReplaced(); 在全局作用域对象更新共享数据

public void removeed(); 在全局作用域对象删除共享数据

6、全局作用域对象共享数据变化时刻

ServletContext application = request.getServletContext();

application.setAttribute("key1", 100);

application.setAttribute("key1", 200);

application.removeAttribute("key1");

过滤器接口

1、介绍:

1、来自于Servlet规范下接口,在Tomcat中存在于servlet-api.jar包

2、Filter接口实现类由开发人员负责提供,Http服务器不负责提供

3、Filter接口在Http服务器调用资源文件之前,对Http服务器进行拦截

2、具体作用:

1、拦截Http服务器,帮助Http服务器检测当前请求合法性

2、拦截Http服务器,对当前请求进行增强操作

3、Filter接口实现类开发步骤:三步

1、创建一个Java实现类Filter接口

2、重写Filter接口中doFilter方法

3、web.xml将过滤器实现类注册到Http服务器

<filter>

<filter-name>oneFilter</filter-name>

<filter-class>com.li.filter.OneFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>oneFilter</filter-name>

<url-pattern>/car.jpg</url-pattern>

</filter-mapping>

4、Filter拦截地址格式:

1、命令格式:

<filter-mapping>

<filter-name>oneFilter</filter-name>

<url-pattern>拦截地址</url-pattern>

</filter-mapping>

2、命令作用:

拦截地址通知Tomcat在调用何种资源文件之前需要调用OneFilter过滤器进行拦截

3、要求Tomcat在调用某一个具体文件之前,来调用OneFilter拦截

<url-pattern>/img/car.jpg</url-pattern>

4、要求Tomcat在调用某一个文件夹下所有的资源文件之前,来调用OneFilter拦截

<url-pattern>/img/*</url-pattern>

5、要求Tomcat在调用任意文件夹下某种类型文件之前,来调用OneFilter拦截

<url-pattern>*.jpg</url-pattern>

6、要求Tomcat在调用网站中任意文件时,来调用OneFilter拦截

<url-pattern>/*</url-pattern>