JavaWeb之Servlet

本文详细介绍了Servlet的基础概念、生命周期、GET/POST请求处理、继承体系、配置与部署,包括HttpServletRequest和HttpServletResponse的使用,以及请求转发和重定向示例。从Servlet原理到实践应用,适合Java EE开发者深入学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是Servlet

Servlet是JavaEE的规范之一,它是一个运行在服务器上的java小程序,它通常通过HTTP协议接收和响应来自Web客户端的请求。

实现一个Servlet程序

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

Servlet的生命周期

在这里插入图片描述

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

public class HelloServlet implements Servlet {

    public HelloServlet() {
        System.out.println("1 构造器方法");
    }

    // service方法是专门用来处理请求和响应的
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("3 service方法:Hello Servlet 被访问了");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("2 init初始化方法");
    }

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

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

    @Override
    public void destroy() {
        System.out.println("4 destroy 销毁方法");
    }
}

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

Get和Post

在这里插入图片描述

获取请求方式

如何根据不同的请求方式来进行不同的处理呢?

  • 在webaqq目录下新建一个HTML页面a.html来进行演示
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/servlet_01_war/hello" method="get">
    <input type="submit">
</form>
</body>
</html>
  • 在HelloServlet类的service方法里里根据请求方式来进行不同的处理
// service方法是专门用来处理请求和响应的
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    System.out.println("3 service方法:Hello Servlet 被访问了");

    // servletRequest就是请求的方式,需要借助HttpServletRequest接口中的getMethod()方法来获取
    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    // 获取到请求的方式
    String method = httpServletRequest.getMethod();

    if ("Get".equals(method)){
        System.out.println("Get请求");
    }else if ("Post".equals(method)){
        System.out.println("Post");
    }
}

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

通过HttpServlet接口来实现Servlet程序

在现实开发中通常都是使用继承HttpServlet类的方式来实现Servlet程序的,其具体步骤是:

  1. 编写一个类去继承HttpServlet类
  2. 根据业务重写doGet和doPost方法
  3. 到web.xml中去配置,把java类部署到web服务器中
  • 创建一个HelloHttpServlet类,继承HttpServlet类,并重写doGet和doPost方法
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HelloHttpServlet extends HttpServlet {
    // doGet()方法在get请求时调用
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HelloHttpServlet 的 doGet 方法");
    }

    // doPost()方法在post请求时调用
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HelloHttpServlet 的 doPost 方法");
    }
}

  • 在web.xml中进行部署
<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>Archetype Created Web Application</display-name>
    <!--    <servlet>:把Servlet程序配置给Tomcat服务器-->
    <servlet>
        <servlet-name>HelloHttpServlet</servlet-name>
        <servlet-class>HelloHttpServlet</servlet-class>
    </servlet>

    <!--    <servlet-mapping>:给Servlet程序配置访问地址-->
    <servlet-mapping>
        <servlet-name>HelloHttpServlet</servlet-name>
        <url-pattern>/hellohttp</url-pattern>
    </servlet-mapping>
</web-app>

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

Servlet的继承体系

在这里插入图片描述

ServletConfig类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此外我们也可以在别的方法中使用ServletConfig,比如在继承了HttpServlet的HelloHttpServlet类的doGet、doPost等方法中:

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HelloHttpServlet extends HttpServlet {
    // doGet()方法在get请求时调用
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HelloHttpServlet 的 doGet 方法");
        ServletConfig servletConfig = getServletConfig();
        System.out.println("Servlet程序的别名servlet-name:" + servletConfig.getServletName());
    }

    // doPost()方法在post请求时调用
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HelloHttpServlet 的 doPost 方法");
        ServletConfig servletConfig = getServletConfig();
        System.out.println("初始化参数username:" + servletConfig.getInitParameter("username"));
        System.out.println("初始化参数url:" + servletConfig.getInitParameter("url"));
    }
}

在web.xml中配置:

<servlet>
    <servlet-name>HelloHttpServlet</servlet-name>
    <servlet-class>HelloHttpServlet</servlet-class>
    <init-param>
        <param-name>username</param-name>
        <param-value>root</param-value>
    </init-param>
    <init-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/test</param-value>
    </init-param>
</servlet>
<servlet-mapping>
        <servlet-name>HelloHttpServlet</servlet-name>
        <url-pattern>/hellohttp</url-pattern>
    </servlet-mapping>

在这里插入图片描述

ServletContext类

ServletContext是一个接口,它表示Servlet上下文对象,每个web工程,只有一个ServletContext对象实例。并且它是在web工程部署启动的时候创建,停止的时候销毁。

域对象

ServletContext对象是一个域对象。它是一种可以像Map一样存取数据的对象。这里的域指的是存取数据的操作范围,也就是整个web工程。

在这里插入图片描述

ServletContext 类的四个作用

  1. 获取web.xml中配置的上下文参数context-param
  2. 获取当前的工程路径,格式:/ 工程路径
  3. 获取工程部署后在服务器硬盘上的绝对路径
  4. 像Map一样存取数据

演示

  • 获取上下文参数context-param

创建一个新的类ContextServlet,继承HttpServlet类,重写doGet方法:

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

public class ContextServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        1. 获取web.xml中配置的上下文参数context-param
        ServletContext servletContext =  getServletConfig().getServletContext();
        String username = servletContext.getInitParameter("username");
        String password = servletContext.getInitParameter("password");
        System.out.println("context-param参数其username是:" + username);
        System.out.println("context-param参数其password是:" + password);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

在web.xml中配置:

<context-param>
    <!--    <context-param>:它是上下文参数,属于整个web工程-->
    <param-name>username</param-name>
    <param-value>context</param-value>
</context-param>
<context-param>
    <param-name>password</param-name>
    <param-value>12345678</param-value>
</context-param>

运行,查看结果:
在这里插入图片描述

  • 获取当前的工程路径
  • 获取工程部署后在服务器硬盘上的绝对路径

修改doGet类:

@Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        1. 获取web.xml中配置的上下文参数context-param
        ServletContext servletContext =  getServletConfig().getServletContext();
        String username = servletContext.getInitParameter("username");
        String password = servletContext.getInitParameter("password");
        System.out.println("context-param参数其username是:" + username);
        System.out.println("context-param参数其password是:" + password);
//        2. 获取当前的工程路径,格式:/ 工程路径
        System.out.println("当前工程路径为:" + servletContext.getContextPath());
//        3. 获取工程部署后在服务器硬盘上的绝对路径
//        ”/“斜杠表示服务器解析地址为:http://ip:port/工程名/
        System.out.println("工程部署的路径为:" + servletContext.getRealPath("/"));

    }

运行,查看结果:
在这里插入图片描述

  • 像Map一样存取数据

修改doGet类:

@Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("set之前:");
        System.out.println("ContextServlet 中获取key1的值是:" + servletContext.getAttribute("key1"));
        servletContext.setAttribute("key1", "value1");
        System.out.println("set之后:");
        System.out.println("ContextServlet 中获取key1的值是:" + servletContext.getAttribute("key1"));

    }

运行,查看结果:
在这里插入图片描述
在这里插入图片描述

HttpServletRequest类

每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。 然后传递到service方法(doGet和doPost)中给我们使用。我们可以通过 HttpServletRequest对象,来获取所有请求的信息。
在这里插入图片描述

部分演示

创建一个新的类RequestAPIServlet,继承HttpServlet类,重写doGet方法:

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

public class RequestAPIServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        getRequestURI() 获取请求的资源路径
        System.out.println("获取请求的资源路径:" + request.getRequestURI());
//        getRequestURL() 获取请求的统一资源定位符(绝对路径)
        System.out.println("获取请求的绝对路径:" + request.getRequestURL());
//        getRemoteHost() 获取客户端的ip地址
        System.out.println("获取客户端的ip地址:" + request.getRemoteHost());
//        getHeader() 获取请求头
        System.out.println("获取请求头:" + request.getHeader("User-agent"));
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

在web.xml中配置:

<servlet>
    <servlet-name>RequestAPIServlet</servlet-name>
    <servlet-class>RequestAPIServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>RequestAPIServlet</servlet-name>
    <url-pattern>/request</url-pattern>
</servlet-mapping>

运行,查看结果:

在这里插入图片描述

获取请求的参数值演示

创建一个form.html

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/servlet_01_war/parameterservlet" method="get">
    用户名:<input type="text" name="username"></br>
    密码:<input type="text" name="password"></br>
    兴趣爱好:<input type="checkbox" name="hobby" value="java">java
    <input type="checkbox" name="hobby" value="c++">c++
    <input type="checkbox" name="hobby" value="c">c</br>
    <input type="submit">
</form>
</body>
</html>

创建一个新的类ParameterServlet,继承HttpServlet类,重写doGet方法:

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

public class ParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取请求的参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
				// 兴趣爱好有多项,使用数组接收
        String[] hobbys = request.getParameterValues("hobby");

        System.out.println("用户名:" + username);
        System.out.println("密码:" + password);
        System.out.println("兴趣爱好:" + Arrays.toString(hobbys));
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
				// 获取请求的参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String[] hobbys = request.getParameterValues("hobby");

        System.out.println("用户名:" + username);
        System.out.println("密码:" + password);
        System.out.println("兴趣爱好:" + Arrays.toString(hobbys));
    }
}

在web.xml中配置:

<servlet>
    <servlet-name>ParameterServlet</servlet-name>
    <servlet-class>ParameterServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ParameterServlet</servlet-name>
    <url-pattern>/parameterservlet</url-pattern>
</servlet-mapping>

运行,访问form.html,输入并提交:
在这里插入图片描述
在这里插入图片描述

请求转发演示

在这里插入图片描述
新建一个Servlet1和一个Servlet2,都继承继承HttpServlet类,重写doGet方法:

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

public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 查看请求参数
        String username = request.getParameter("tablename");
        System.out.println("学生(Servlet1)查看一下表格" + username);
        // 学生1在表格上写下姓名
        request.setAttribute("name1", "tom");
        System.out.println("学生(Servlet1)填写:" + request.getAttribute("name1"));
        //把表格给下一个学生 ————> 请求转发
        // 找到下一个学生Servlet2
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/servlet2");
        // 传表格给下一个学生
        requestDispatcher.forward(request,response);
    }
}
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 查看请求参数
        String username = request.getParameter("tablename");
        System.out.println("学生(Servlet2)查看一下表格" + username);

        //查看Servlet1学生是否已经填好
        Object name1 = request.getAttribute("name1");
        System.out.println("学生(Servlet1)已经填写了:" + name1);

        //Servlet2学生填表
        request.setAttribute("name2", "jerry");
        System.out.println("学生(Servlet2)填写:" + request.getAttribute("name2"));
    }
}

在web.xml中配置:

<servlet>
    <servlet-name>Servlet1</servlet-name>
    <servlet-class>Servlet1</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Servlet1</servlet-name>
    <url-pattern>/servlet1</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>Servlet2</servlet-name>
    <servlet-class>Servlet2</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Servlet2</servlet-name>
    <url-pattern>/servlet2</url-pattern>
</servlet-mapping>

运行,传入tablename参数:
在这里插入图片描述

HttpServletResponse类

  • HttpServletResponse类的作用

HttpServletResponse类和HttpServletRequest类一样。每次有请求进来,Tomcat服务器都会创建一个 Response对象传递给Servlet程序去使用。HttpServletRequest表示请求过来的信息,HttpServletResponse表示所有响应的信息,我们如果需要设置返回给客户端的信息,可以通过 HttpServletResponse对象来进行设置。

  • 两个输出流(两个流同时只能使用一个)
  1. 字节流getOutputStream():常用于下载(传递二进制数据)
  2. 字符流getWriter():常用于回传字符串(常用)
  • 演示

修改Servlet2类的doGet方法:

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

public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 查看请求参数
        String username = request.getParameter("tablename");
        System.out.println("学生(Servlet2)查看一下表格" + username);

        //查看Servlet1学生是否已经填好
        Object name1 = request.getAttribute("name1");
        System.out.println("学生(Servlet1)已经填写了:" + name1);

        //Servlet2学生填表
        request.setAttribute("name2", "jerry");
        System.out.println("学生(Servlet2)填写:" + request.getAttribute("name2"));

        // 演示往客户端回传字符流数据
        PrintWriter writer = response.getWriter();
        writer.write("学生(Servlet2)把表格还给老师了");
    }
}

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

请求重定向

在这里插入图片描述

  • 演示

新建一个Response1和一个Response2,都继承继承HttpServlet类,重写doGet方法:

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

public class Response1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("我来过这:Response1");
        // 设置响应状态码302,表示重定向
        response.setStatus(302);
        // 设置相应头,指明新地址在哪
        response.setHeader("Location", "http://localhost:8080/servlet_01_war/response2");
    }
}
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class Response2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
				// 同时设置服务器和客户端字符集
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("欢迎光临:Response2");
    }
}

在web.xml中配置:

<servlet>
    <servlet-name>Response1</servlet-name>
    <servlet-class>Response1</servlet-class>
</servlet>
<servlet>
    <servlet-name>Response2</servlet-name>
    <servlet-class>Response2</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Response1</servlet-name>
    <url-pattern>/response1</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>Response2</servlet-name>
    <url-pattern>/response2</url-pattern>
</servlet-mapping>

运行,访问/response1:
在这里插入图片描述
另外一种方式,直接使用sendRedirect方法(推荐):

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

public class Response1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("我来过这:Response1");
        response.sendRedirect("http://localhost:8080/servlet_01_war/response2");
    }
}

文章notion链接

https://www.notion.so/Servlet-6cb37a12749b4ed8a9873beb5459817f

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值