Servlet详解

本文为视频教程https://www.bilibili.com/video/BV1Y7411K7zz摘录笔记而得。

JavaWeb三大组件,三大组件分别是:Servlet程序、Filter过滤器、Listener

什么是Servlet?

Servlet是运行在服务器上的小型Java程序,通过HTTP接受并响应来自Web客户端的请求。


如何实现Servlet程序

*Tomcat配置此处略去。

  1. 编写一个类去实现Servlet接口

创建MyServlet类来实现Servlet接口,并重写Servlet中方法

import javax.servlet.*;
import java.io.IOException;

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

    }

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

    /**
     *
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("MyServlet被访问了。");
    }

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

2… 实现Service方法,处理请求,并响应数据
在service添加输出语句,证明service方法被访问到。

@Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("MyServlet被访问了。");
    }
  1. web.xml中去配置servlet程序的访问地址
    代码如下:
    此处需要注意的是 .xml文件中有两个标签需要编写
  • < servlet>
  • < servlet-mapping>

两个标签中的< servlet-name>必须一致

此外,< servlet-class>中应包含步骤1所写的Servlet接口的全类名

<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>MyServlet</servlet-name>
        <!--全类名        -->
        <servlet-class>MyServlet</servlet-class>
    </servlet>
	
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/servlet</url-pattern>
    </servlet-mapping>

</web-app>

测试
  1. 启动Tomcat,启动成功后控制台会输出一下内容并弹出index页面
    在这里插入图片描述
  2. 将我们所添加的.xml中< url-pattern>中的url后缀加到浏览器地址栏并访问。
<url-pattern>/servlet</url-pattern>

新的URL:
http://localhost:8080/ServletDemo_war_exploded/servlet

此时观察控制台,MyServlet中的service方法中的输出语句已经输出到控制台,证明service方法被访问。

	public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws  ServletException, IOException {
        System.out.println("MyServlet被访问了。");
    }

控制台输出:
在这里插入图片描述


Servlet生命周期方法
  1. 执行Servlet构造器方法
  2. 执行init初始化方法
  3. 执行service方法
  4. 执行destroy方法

请求的分发处理原理

我们希望在service方法中对不同的HTTP请求建立各自的对应方法,实现请求分法处理的目的。下面将以get和post两种请求做演示。

  1. 首先重写service()方法
    此处应注意httpServletRequest为向下转型,因为HttpServletRequest为Servlet的子类,且只有HttpServletRequest包含getMethod()方法。

    为了使service里面内容清晰,我们用doGet()和doPost()来封装处理请求的代码。

/**
     *
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("MyServlet被访问了。");

        //子类HttpServletRequest继承自servletRequest并拥有getMethod()方法,因此需要向下转型
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String method = httpServletRequest.getMethod();

        //if判断方法类型
        if(method.equals("GET")){
            doGet();
        }else if (method.equals("POST")){
            doPost();
        }
    }

doGet()和doPost()

private void doGet() {
        System.out.println("已接受GET请求");
    }
    
    private void doPost() {
        System.out.println("已接受POST请求");
    }

  1. 在web路径下新建测试html文件
    此处注意html文件也在web路径下而不是WEB-INF!
    在这里插入图片描述
    html内容为一个提交表单,点击提交按钮后会跳转至对应的url地址
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <form action="http://localhost:8080/ServletDemo_war_exploded/servlet" method="get">
            <input type="submit">
        </form>
    </div>
</body>
</html>
  1. 访问html文件的url:
    http://localhost:8080/ServletDemo_war_exploded/a.html

测试结果
控制台可以看到doGet()中的输出语句已经被执行。

private void doGet() {
        System.out.println("已接受GET请求");
    }

在这里插入图片描述

ServletConfig类

涉及方法为**init()**方法,init()方法在首次访问时调用,接上面的例子,我们将继续访问http://localhost:8080/ServletDemo_war_exploded/servlet,然后观察控制台是否正确返回我们所调用的方法。

作用
  1. 可以获取servlet-name的值
@Override
    public void init(ServletConfig servletConfig) throws ServletException {
        //获取ServletName的属性并打印
        System.out.println("ServletName:"+servletConfig.getServletName());
        
    }

.xml文件中servlet-name为“MyServlet

    <servlet>
        <!--给servlet标签起一个别名-->
        <servlet-name>MyServlet</servlet-name>
        <!--全类名        -->
        <servlet-class>MyServlet</servlet-class>
        <!--在Servlet内中添加init-param标签-->
        <init-param>
            <param-name>url</param-name>
            <param-value>www.baidu.com</param-value>
        </init-param>
    </servlet>

控制台输出如下:
可以看到init()z中的打印语句被正确输出
在这里插入图片描述

  1. 可以获取初始化参数init-param
  • 首先在xml对应的servlet标签中添加init-param标签,并传入param-name和param-value。
    <servlet>
        <!--给servlet标签起一个别名-->
        <servlet-name>MyServlet</servlet-name>
        <!--全类名        -->
        <servlet-class>MyServlet</servlet-class>
        <!--在Servlet内中添加init-param标签-->
        <init-param>
            <param-name>url</param-name>
            <param-value>www.baidu.com</param-value>
        </init-param>
    </servlet>
  • 然后在自己定义的MyServlet类中使用init方法
public void init(ServletConfig servletConfig) throws ServletException {
        //获取ServletName的属性并打印
        System.out.println("ServletName:"+servletConfig.getServletName());

        //传入param-name,获取param-value
        System.out.println(servletConfig.getInitParameter("url"));

    }

控制台输出如下:
可以看到.xml中的url被正确输出
在这里插入图片描述
3. 获取ServletContext对象

public void init(ServletConfig servletConfig) throws ServletException {
        //获取ServletName的属性并打印
        System.out.println("ServletName:"+servletConfig.getServletName());

        //传入param-name,获取param-value
        System.out.println(servletConfig.getInitParameter("url"));

        //获取ServletContext对象
        System.out.println(servletConfig.getServletContext());
    }

控制台输出:
在这里插入图片描述


ServletContext类

什么是ServeletContext对象?

  1. ServletContext是一个接口,表示Servlet上下文对象
  2. 一个web工程只有一个ServletContext对象实例
  3. ServletContext对象是一个域对象
  4. ServletContext在web工程部署启动时创建,在web工程停止的时候销毁

什么是域对象?
可以像Map一样存取数据的对象,域指的是存取数据的操作范围。
在这里插入图片描述

ServletContext类的四个作用

作用1. 获取web.xml中配置的上下文参数context-param

代码实现
我们将尝试访问.xml中的param-value,看是否能成功获取

1.1 再.xml文件中添加context-parm标签,并赋值。

    <!--上下文参数   -->
    <context-param>
        <param-name>username</param-name>
        <param-value>abc</param-value>
    </context-param>
    <context-param>
        <param-name>password</param-name>
        <param-value>123</param-value>
    </context-param>

1.2 创建新的ContextServlet类继承HttpServlet类

public class ContextServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    	//获取servletContext
        ServletContext context = getServletConfig().getServletContext();
		//获取param-name为username对应的value
        System.out.println(context.getInitParameter("username"));
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

1.3 在.xml文件中为新建的ContextServlet类创建servlet标签和servlet-mapping标签

<!--    ContextServlet对象-->
    <servlet>
        <servlet-name>ContextServlet</servlet-name>
        <servlet-class>ContextServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ContextServlet</servlet-name>
        <url-pattern>/contextServlet</url-pattern>
    </servlet-mapping>

访问http://localhost:8080/ServletDemo_war_exploded/contextServlet

控制台输入如下,对应我们在1.1部分.xml文件中写的context-param标签中的值"abc"。
在这里插入图片描述

    <!--上下文参数   -->
    <context-param>
        <param-name>username</param-name>
        <param-value>abc</param-value>
    </context-param>

作用2. 获取工程路径

2.1 调用context的getContextPath()方法,减第二条注解,获取2工程路径

public class ContextServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = getServletConfig().getServletContext();
        //1. 获取context
        System.out.println(context.getInitParameter("username"));
        //2. 获取工程路径
        System.out.println(context.getContextPath());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

访问http://localhost:8080/ServletDemo_war_exploded/contextServlet
控制台输出如下,
在这里插入图片描述

作用3. 过去部署后再服务器硬盘的路径

此处"/"对应的是web文件夹的路径
在这里插入图片描述

public class ContextServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = getServletConfig().getServletContext();
        //1. 获取context
        System.out.println(context.getInitParameter("username"));
        //2. 获取工程路径
        System.out.println(context.getContextPath());
        //3. 获取工程部署后再服务器硬盘上的绝对路径
        System.out.println(context.getRealPath("/"));
    }

作用4. 像Map一样存取数据

可参考上文中的 ***什么是域对象?***部分

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值