Servlet接口

以后我们要做的是bs系统,那Servlet就是处理请求和响应的。

为什么要使用Servlet

因为浏览器只能通过url访问一个路径,浏览器是不能直接访问java程序的一个类
Servlet是可以设置一个虚拟路径,正好浏览器是访问路径的。浏览器访问
了这个虚拟路径,所对应的方法就会被执行。

  1. Servlet是唯二服务器处理请求和响应的,filter也行
  2. 整个Servlet方法的调用都是tomcat
  3. 广义上来说,Servlet接口的实现类都叫Servlet

静态资源与动态资源

静态资源:每次访问的内容不会发生变化,如html、css、js、图片、音视频等等都属于静态资源

动态资源:不同的用户或者不同时间点访问web页面看到的内容各不相同 。Servlet、JSP(不学)、Thymeleaf。(如Servlet在登录验证的功能,不同情况运算的结果是不一样的)

静态指的是数据是静态的,就是说你看到的数据,它不管怎么变都是一样的。


Servlet入门案例

记得这个老师给我们说的那句话,要学习一门新的技术,应该怎么学??应该从入门案例开始

仔细品,确实是这样的!

1、创建一个Servlet类去实现Servlet接口,有5个方法需要被重写

Servlet接口如下:

public class FirstServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
         //向浏览器响应数据
        servletResponse.getWriter().write("FirstServlet");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

2、设置虚拟路径的俩种方式

方式一:Servlet类加一个注解搞定  @WebServlet("/FirstServlet")

方式二:在当前web应用的web.xml中进行标签配置

我们写的是一个Servlet处理一个请求路径

<?xml version="1.0" encoding="UTF-8"?>
<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_4_0.xsd"
                   version="4.0">

    <servlet>
<!--        相当于给该Servlet取个名,建议类名-->
        <servlet-name>FirstServlet</servlet-name>
<!--        要配置的那个Servlet的全限定名-->
        <servlet-class>com.atguigu.servlet.FirstServlet</servlet-class>
    </servlet>
    <servlet-mapping>
<!--        和servlet标签中的servlet-name保持一致-->
        <servlet-name>FirstServlet</servlet-name>
<!--        给FirstServlet配置的映射路径,以/开头-->
        <url-pattern>/FirstServlet</url-pattern>
    </servlet-mapping>
</web-app>

 方式二注意:

1.<url-pattern>可以设置多个
2.<url-pattern>中设置的路径格式

2.1 精确匹配: /FirstServlet(建议跟类名保持一致), /test.html 这么写也行,精确匹配中"/" 一定不能省略

2.2 模糊匹配:“/*” 能匹配到jsp, “/ ”不能匹配到jsp

2.3 后缀匹配:*.do

配置好了后,就可以在浏览器里访问了。问题是怎么知道是这么写的呢?http://localhost:8080/day05_web/FirstServlet

 老师教的办法,以index.html为参考,

<url-pattern>/FirstServlet</url-pattern>
这个里面的/就是上下文路径,

也就是下面地址栏这个路径,直接访问就是欢迎页了


Servlet的生命周期

说:Tomcat是Servlet的容器。那Tomcat是怎么来管理Servlet的??

Servlet接口有5个方法,servlet生命周期只涉及3个方法 init、service、destroy

init初始化:第一次访问Servlet时执行,在服务器工作的整个过程中只执行一次
service服务:每次访问servlet都执行service方法,可以执行多次
destroy销毁:服务器关闭时调用destroy,在服务器工作的整个过程中,只执行一次(如重新部署)

1.如果有人说Servlet周期是4个阶段:

那就加一个实例化阶段(即创建对象),一定在上面说的三个阶段之前,在最前面。

2.如果要求在服务器启动时将Servlet初始化:(调用init方法)

则在web.xml的 <servlet></servlet>加一个标签<load-on-startup>

为什么要加这个标签呢?因为如果不这么做在第一次访问Servlet的时候,既要初始化,又要服务,会影响性能。

<!--
    <load-on-startup>可以将Servlet的初始化时间提前到服务器启动时
    只能设置正整数,若设置0或负整数则没有任何效果
    所设置的正整数越小,优先级越高
-->
<load-on-startup>1</load-on-startup>

ServletConfig 接口

ServletConfig表示Servlet的配置对象,因此可以通过此对象获取Servlet的配置信息

alt+7 查看ServletConfig类的内部结构

 在web.xml中的<Servlet>中配置如下:我们可以通过ServletConfig去拿到这些配置信息

    <servlet>
<!--        相当于给该Servlet取个名,建议类名-->
        <servlet-name>FirstServlet</servlet-name>
<!--        要配置的那个Servlet的全限定名-->
        <servlet-class>com.atguigu.servlet.FirstServlet</servlet-class>
        <init-param>
            <param-name>configLocation</param-name>
            <param-value>springMVC.xml</param-value>
        </init-param>
    </servlet>

下面少测试了一个方法,

getInitParameterNames()  //获取所有初始化参数名组成的Enumeration对象

    public void init(ServletConfig servletConfig) throws ServletException {
        //获取<servlet-name>中的名字
        String servletName = servletConfig.getServletName();
        System.out.println("Servlet的友好名称:" + servletName);
        //获取Servlet的初始化参数  <init-param>中的值
        String configLocation = servletConfig.getInitParameter("configLocation");
        System.out.println("Servlet的初始化参数:" + configLocation);
        //获取 上下文对象 ServletContext ,这个最重要
        ServletContext servletContext = servletConfig.getServletContext();
    }


ServletContext 上下文对象

ServletContext 表示当前的整个web应用,获取当前web应用相关的信息

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

        //获取上下文对象 ServletContext ,这个最重要
        ServletContext servletContext = servletConfig.getServletContext();
        //动态获取当前web应用的上下文路径
        String contextPath = servletContext.getContextPath();
        System.out.println("当前web应用的上下文路径:"+contextPath);
        //获取当前web应用的初始化参数 <context-param> 也叫上下文参数,配置在web.xml
        String testContextParam = servletContext.getInitParameter("testContextParam");
        System.out.println("当前web应用的初始化参数:"+testContextParam);
    }

当前web应用的初始化参数是啥呢,就是web.xml中这个 <context-param>

context-param 就在web-app 标签下,所以它对所有的 Servlet 都是有效的

之后又我们会使用它配置视图前缀和视图后缀,如下:

    <context-param>
        <param-name>view-prefix</param-name>
        <param-value>/WEB-INF/pages/</param-value>
    </context-param>

    <context-param>
        <param-name>view-suffix</param-name>
        <param-value>.html</param-value>
    </context-param>

那上面程序的执行结果:通过ServletContext获取到了当前web应用相关的信息

    <context-param>
        <param-name>testContextParam</param-name>
        <param-value>hello,ServletContext</param-value>
    </context-param>


ServletContext 还有2个更为重要的方法

获取项目的部署路径:

文件上传与文件下载都是文件复制的过程,会用专门的文件服务器保存文件,会用到项目的部署路径
        //获取上下文对象 ServletContext ,这个最重要
        ServletContext servletContext = servletConfig.getServletContext();
        //文件上传与文件下载都是文件复制的过程,会用专门的文件服务器保存文件,会用到项目的部署路径
        //获取当前web应用的部署路径,在idea中,是在out下
        String realPath1 = servletContext.getRealPath("");
        System.out.println("当前web应用的部署路径:" + realPath1);
        //("")有参数就是简单的拼接,用来获取当前web应用下某个文件路径
        String realPath2 = servletContext.getRealPath("abc");
        System.out.println("当前web应用的部署路径:" + realPath2);


域对象

域对象可以在指定的范围共享数据

请求域:可以共享数据是因为请求对象是同一个
会话域:浏览器开启到浏览器关闭,一次会话中获取的session都是同一个。
范围小的域对象能实现功能的,范围大得也一定能实现

ServletContext作为一个域对象(最大的域对象),在整个web应用的范围共享数据

域对象底层是map集合,域对象操作共享数据的三个方法:

  1. void setAttribute(String name, Object value):设置共享的数据
  2. Object getAttribute(String name):获取共享的数据
  3. void removeAttribute(String name):删除共享的数据

怎么理解ServletContext在整个web应用的范围共享数据?

原因:ServletContext在服务器启动时创建,服务器关闭时销毁,ServletContext在服务器工作的 整个过程中,只创建一次,任何地方获取的都是同一个。


我们在FirstServlet设置了共享数据,范围是在整个web应用的范围。

    public void init(ServletConfig servletConfig) throws ServletException {
        /*
         * ServletContext作为一个域对象,在整个web应用的范围共享数据
           设置共享的数据
        */
        servletContext.setAttribute("testScope", "你好");
    }

然后在SecondServlet中去获取放置在共享域中的数据

    @Override
    public void init(ServletConfig servletConfig) {
        //获取上下文对象ServletContext
        ServletContext servletContext = servletConfig.getServletContext();
        //获取域对象共享的数据
        Object testScope = servletContext.getAttribute("testScope");
        System.out.println(testScope);
    }


GenericServlet 【Servlet的扩展实现类】

(Ctrl+H 查看类的继承实现关系)

GenericServlet类把不用的方法【init()、getServletConfig()、getServletInfo()、destroy()】进行了重写,把真正有用的方法service进行了抽象

这里有俩个init方法,哪个是重写后的呢?有个小技巧,就是后面有箭头的就是重写的

alt+7  查看当前类结构


HttpServlet  [ Servlet的扩展实现类 ]

HttpServlet:将service()进行了重写,调用重载的service方法。重载的service方法方法中,根据请求方式的不同,调用了不同的方法。

1、重写的service("请求报文和响应报文")调用了重载的service("HTTP前缀的请求报文和响应报文")

2、根据请求方式的不同,调用了不同的方法。

GET请求-->doGet()

POST请求-->doPost()


快速创建Servlet

到此,以后我们创建Servlet,有了快速的创建方法:直接继承HttpServlet

用这种方式创建的Servlet会自动继承HttpServlet

如果不取消那个勾,idea就用注解的方式注册了虚拟路径 

@WebServlet(name = "ServletMM")

@WebServlet(name = "ServletMM")
public class ServletMM extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        因为post和get处理请求的方式一摸一样
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

如果取消了这个勾,idea就会自动在web.xml中去生成<servlet>的配置,还需要再配置<servlet-mapping>这个标签

<servlet-mapping>
    <servlet-name>ServletMM</servlet-name>
    <url-pattern>/ServletMM</url-pattern>
</servlet-mapping>
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐