《Tomcat与Java Web开发技术详解》阅读梳理 第四章Servlet技术(上)

点击查看合集
Servlet通过Servlet容器运行,从而对用户提供各种服务。

Servlet可以做的事

1.动态生成HTML文档
2.把请求转发给同一个Web应用中的其他Servlet组件
3.把请求转发给其他Web应用中的Servlet组件
4.读取客户端的Cookie,以及向客户端写入Cookie
5.访问其他服务器资源(如数据库或基于Java的应用程序)

Servlet特点

1.Servlet是用Java语言编写出来的类,只要开发人员有深厚的Java编程功底,就可以编写出能够完成各种复杂任务的Servlet类
2.Servlet对象由Servlet容器创建。Servlet能利用容器提供给它的各种资源。通过利用这些资源,才能发挥出强大的能力。

容器提供给Servlet的资源

1.请求对象(ServletRequest和HttpServletRequest):Servlet从请求对象中可以获取客户端的请求信息。
2.响应对象(ServletResponse和HttpServletResponse):Servlet通过该对象来生成响应结果。
3.Servlet配置对象(ServletConfig):当容器初始化一个Servlet对象时,会向他提供一个ServletConfig对象,Servlet通过该对象来获取初始化参数信息以及ServletContext对象。
4.Servlet上下文对象(ServletContext):Servlet通过该对象来访问容器为当前Web应用提供的各种资源。

Servlet API的类框架

在这里插入图片描述

Servlet接口

Servlet接口是Servlet API的核心,所有的Servlet类都要实现这个接口。该接口中定义了五个方法。其中三个为声明周期方法,由Servlet容器调用。另外两个为get方法。分别获得ServletConfig和ServletInfo对象。
1.init(ServletConfig config)方法:当容器创建Servlet对象后就会调用该方法来初始化Servlet。
2.service(ServletRequest request,ServletResponse response)方法:负责响应客户的请求,客户请求访问某个Servlet后,容器就会调用该Servlet的service方法。
3.destroy()方法:负责释放Servlet占用的资源。当Servlet对象结束生命周期时容器调用此方法。
4.getServletConfig()方法:获取ServletConfig对象,其中包含了Servlet的初始化信息,也包括ServletContext对象
5.getServletInfo()方法:返回一个字符串,其中记录了Servle是由谁创建的,版本和版权等信息。
GenericServlet是实现了Servlet接口的抽象类。HttpServlet是GenericServlet的子类,也是抽象类。当我们想要写Servlet类时,可以继承GenericServlet也可以继承HttpServlet类。
在这里插入图片描述

GenericServlet抽象类

GenericServlet不仅实现了Servle接口同时也实现了ServletConfig接口和Serializable接口。GenericServlet类不依赖于任何应用层协议,他是Servlet的通用接口。
GenericServlet中只有一个抽象方法service。并且他的destory方法是一个空方法。
它还包含一个无参的init方法。GenericServlet会在有参的init方法中给ServletConfig赋值后调用无参的init方法。我们可以重写init方法和destory来完成我们需要的一些初始化和资源的释放的任务。

HttpServlet抽象类

HttpServlet抽象类是Generic的一个子类。它实现了GenericServlet的service(ServletRequest req,ServletResponse res)方法,并在servlet方法中调用了一个service的重载方法service(HttpServletRequest req,HttpServletResponse res)。也就是说实际工作的是这个重载方法。
HttpServlet是专门适用于采用了Http协议的容器和Web服务器的。
HttpServle重载的service方法中调用了req.getMethod方法获得客户的请求方式(get post put delete等)。然后根据返回值调用相应的doXX方法。
每个doXX方法的默认实现都会向客户端返回一个错误。

ServletRequest接口

ServletRequest类表示来自客户的请求。当Servlet容器接收到访问特定Servlet的请求时,容器先解析客户端的原始请求数据,把他包装成一个ServletRequest对象。当容器调用service方法时,将这个ServletRequest对象传进去。
在这里插入图片描述

HttpServletRequest接口

HttpServletRequest是ServletRequest的子接口。
他提供了用于读取HTTP请求中相关信息的方法:
在这里插入图片描述

ServletResponse接口

ServletResponse是Servlet接口中service方法中的参数。Servlet通过ServletResponse来生成响应结果。当容器接收到客户端想要访问特定Servlet的请求时。会生成一个ServletResponse对象。在容器调用servlet的service方法时传进去。
ServletResponse接口定义了一系列与生成响应结果相关的方法。
在这里插入图片描述
在这里插入图片描述
ServletResponse的ServletOutputStream和PrintWriter先把数据写到缓冲区内。然后在提交给客户端。当在以下情况下,缓冲区的数据会被发送给客户端。
1.缓冲区满了。
2.调用同ServleResponse的flushBuffer方法
3.调用了ServletOutputStream或PrintWriter的flush方法或者close方法。
注意:如果没有在方法中调用close方法。容器会在service方法结束后帮我们调用。
ServletOutputStream和PrintWriter是互斥的不能同时使用。当我使用ServletOutpuStream流之后,无论我调用close flush flushbuffer哪个方法后,我在执行getWriter方法后,该servle都会直接t自动结束。
ServletOutputStream的printf方法的参数只能是单字节字符(ISO-8859-1)write的参数为字节数组或者数字
PrintWriter的pritf如上。他的write方法可以直接输入字符串(编码方式由setCharacterEncoding指定,默认为ISO-8859-1)。
set方法需要在get方法使用之前调用,才能生效。(需要先指定编码再获得流)
setCharacterEncoding和setContentType的区别。https://blog.csdn.net/qq_30033509/article/details/109689931

HttpServletResponse接口

HttpServletResponse是ServletResponse的子接口。HttpServletResponse提供了一些与HTTP协议相关的方法。可以用来设置HTTP响应头或向客户端写Cookie;
在这里插入图片描述

ServletConfig接口

ServletConfig作为init的参数传给Servlet。当Servlet创建后容器会调用相应的init方法传入ServletConfig参数。在init方法中servlet会与ServletConfig对象产生关联。同时ServletConfig与ServletContext类也有关联关系。
GenericServlet实现了ServletConfig接口。而HttpServlet继承了GenericServlet接口,因此也能直接调用ServletConfig的方法。
ServletConfig中提供了一些获取Servlet初始化参数的方法。
在这里插入图片描述在这里插入图片描述

ServletContext接口

ServletContext在每个Web应用中是唯一的(单例模式)。一个Web应用中每个ServletConfig中引用的都是同一个ServletContext。ServletContext可以为Servlet提供Web应用范围内的数据共享。并能拥有Web应用范围内的初始化参数。Servlet可以通过ServletContext来获取容器中的各种资源。
在这里插入图片描述
在这里插入图片描述
ServletContext可以通过ServletConfig及实现了他的对象获取,也可以通过ServletRequest和实现了他的对象获取。
ServletContext的生命周期和Java Web的生命周期相同。它可以在JavaWeb范围内共享数据。把需要共享的数据作为属性以key-value的形式存放在ServletContext中就可以实现在Java Web范围内共享这些数据了。

Java Web对象的生命周期

Java Web有三个生命周期(由Servlet容器控制)
1.启动阶段:加载Web应用的有关数据,创建ServletContext对象,对Filter和一些Servlet进行初始化
2.运行时阶段:为客户端提供服务
3.终止阶段:释放Web应用所占用的各种资源。

ServletContextListener监听器

Servlet API中有一个ServletContextListener接口,它能够监听ServletContext对象的声明周期,实际上就是监听Web应用的生命周期。
Servlet容器启动或者终止Web应用时,会触发ServletContextEvent事件。该监听器定义了处理此时间的两个方法。分别是
1.contextInitialized(ServletContextEvent sce)方法:在Servlet容器启动Web应用时调用该方法,调用该方法后,容器再对Filter和某些Servlet进行初始化
2.contextDestroyed(ServletContextEvent sce)方法:当Servlet容器终止Web应用时,调用改方法。容器调用该方法前,容器会先销毁Servlet和Filter。
自定义ServletContextListener

public class MyServletContextListener  implements ServletContextListener {
    
    
    public void contextInitialized(ServletContextEvent sce) {
    
    
        //获取servletContext对象
        ServletContext servletContext = sce.getServletContext();
        //读出count.txt文件中的数据并存到ServletContext中
        InputStream is = servletContext.getResourceAsStream("/web/count.txt");
        try {
    
    
            System.out.println(is.available());
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        InputStreamReader reader = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(reader);
        try {
    
    
            String line = br.readLine();
            servletContext.setAttribute("count",Integer.parseInt(line));
        } catch (IOException e) {
    
    
        }
    }

    public void contextDestroyed(ServletContextEvent sce) {
    
    
        //获取servletContext对象
        ServletContext servletContext = sce.getServletContext();
        System.out.println("结束");
        //获得count
        int count =(Integer) servletContext.getAttribute("count");
        System.out.println(count);
        String realPath = servletContext.getRealPath("/web/count.txt");
        try {
    
    
            System.out.println(realPath);
            PrintWriter pw = new PrintWriter(realPath);
            pw.println(count);
            pw.close();
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        }



    }
}

web.xml

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
<welcome-file-list>
    <welcome-file>/login.html</welcome-file>
</welcome-file-list>
    <listener>
        <listener-class>com.sea.MyServletContextListener</listener-class>
    </listener>
<servlet>
        <servlet-name>dispatch</servlet-name>
        <servlet-class>com.sea.DispacherServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatch</servlet-name>
        <url-pattern>/dispatch</url-pattern>
    </servlet-mapping>
</web-app>

浏览器不缓存页面

//1.0 1.1都可以 设置失效时间
        re.setHeader("Expires","0");
        //1.1 设置不缓存网页
        re.setHeader("Cache-Control","no-cache");
        //1.0 设置不缓存网页
        re.addHeader("Pragma","no-cache");

注解

用注解配置Servlet

在这里插入图片描述

用注解配置ServletContextListener

在这里插入图片描述

处理HTTP请求参数中的中文字符编码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_30033509/article/details/109678698