Servlet

本文深入剖析Servlet的实现步骤,包括新建类、实现规范、重写方法及注解设置。讲解Servlet的生命周期,从实例化到销毁的过程。探讨HttpServletRequest与HttpServletResponse对象的使用,包括参数获取、响应数据与乱码处理。介绍请求转发与三大域对象的作用范围。

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

Servlet简析

1.Servlet的实现

1.1新建Servlet类
1.2实现Servlet规范(继承 HttpServlet 类)
1.3重写service方法
1.4设置注解
@WebServlet("/路径") 注:"/"一定要加上!
在完成好了一切代码的编写后,还需要向服务器说明,特定请求对应特定资源。
1.5发布项目并启动服务
1.6 访问并查看结果

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

@WebServlet("/ser01")
//@WebServlet(value = "/ser01")
//@WebServlet(urlPatterns = "/ser01")
//@WebServlet(value = {"/ser01","/ser001"})
//@WebServlet(urlPatterns = {"/ser01","/ser001"},name = "Servlet01",loadOnStartup = 1)
public class Servlet01 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Hello...");
        // 设置响应类型
        resp.setContentType("text/html");
        // 响应数据
        resp.getWriter().write("<h3>Hello</h3>");
    }
}

2.Servlet的生命周期

  • 实例和初始化时机
    当请求到达容器时,容器查找该 servlet 对象是否存在,如果不存在,则会创建实例并进行初始化。
  • 就绪/调用/服务阶段
    有请求到达容器,容器调用 servlet 对象的 service()方法,处理请求的方法在整个生命周期中可以被多次调用;
    HttpServlet 的 service()方法,会依据请求方式来调用 doGet()或者 doPost()方法。但是, 这两个 do 方法默认情况下,会抛出异常,需要子类去 override。
  • 销毁时机
    当容器关闭时(应用程序停止时),会将程序中的 Servlet 实例进行销毁。
    Servlet 的生命周期,简单的概括这就分为四步:servlet 类加载–>实例化–>服务–>销毁。
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/ser02")
public class Servlet02 extends HttpServlet {
    /**
     * 系统方法
     * 每当有请求访问时,都会执行。执行多次。
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet02 service...");
    }
    /**
     *  销毁方法
     * 系统方法,服务自动调用
     *  当servlet实例被销毁时(服务器关闭)执行,只会执行一次
     */
    @Override
    public void destroy() {
        System.out.println("Servlet02 destroy...");
    }
    /**
     * 初始化方法
     *  系统方法,服务器自动调用
     *   当第一次请求时(Servlet实例不存在时)执行,只会执行一次
     * @throws ServletException
     */
    @Override
    public void init() throws ServletException {
        System.out.println("Servlet02 init...");
    }
}

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

@WebServlet("/ser03")
public class Servlet03 extends HttpServlet {

    /**
     * GET请求
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       // 得到请求方式
        String method = req.getMethod();
        System.out.println(method);
        doPost(req,resp);
    }

    /**
     * POST请求
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("POST...");

    }
}

3.HttpServletRequest对象

  1. 常用方法
    获取请求路径
  2. 获取请求的参数(重要!!!)
    request.getParameter(“参数名”);
  3. 请求乱码问题
    乱码原因:request有默认的解析编码,ISO-8859-1,这种编码格式不支持中文,传递中文参数必定乱码。
    解决方案:
    1. 只针对POST请求的乱码问题 (处理所有参数)
    request.setCharacterEncoding(“UTF-8”);
    2. 任意请求方式都有效 (一次处理一个参数)
    new String(request.getParameter(“参数名”).getBytes(“ISO-8859-1”), “UTF-8”);
    目前Tomcat8及以上版本GET请求不会出现乱码,所以目前只需要处理POST请求的参数乱码即可。
  4. 请求转发
    一种跳转方式。
    1. 服务端跳转。
    2. 地址栏不会发生改变
    3. 只有一次请求
    4. 数据可以共享
  5. request作用域
    只在一次请求中有效,只在请求转发跳转有效
    request.setAttribute(“参数名”,“参数值”); 设置作用域(任意类型的数据)
    request.getAttribute(“参数名”); 获取指定作用域的值
    request.removeAttribute(“参数名”); 移除指定作用域的值
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/ser04")
public class Servlet04 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 设置请求乱码问题 (只针对POST有效)
        request.setCharacterEncoding("UTF-8");

        /**
         * 1. 常用方法
         *      1. 获取请求的方式 (GET|POST等)
         *      2. 获取请求的完整路径 (从http开始,到?结束)
         *      3. 获取请求的部分路径 (从项目路径开始,到?结束)
         *      4. 获取请求的参数字符串 (从?开始,到最后)
         *      5. 获取请求的协议版本
         *      6. 获取项目的访问路径 (站点名)
         */
        System.out.println(request.getMethod());
        System.out.println(request.getRequestURL());
        System.out.println(request.getRequestURI());
        System.out.println(request.getQueryString());
        System.out.println(request.getProtocol());
        System.out.println(request.getContextPath());

        /**
         * 获取请求的参数
         *  1. 获取指定参数名的参数值
         *      request.getParameter("参数名")
         *      注:
         *          1. 表单提交
         *              参数名表示的是表单元素的name属性值
         *          2. 地址栏输入
         *              参数名表示的是"?键=值&键=值"中的键
         *  2. 获取指定参数名的所有参数值
         *      request.getParameterValue("参数名")
         */
        // 获取指定参数
        String uname = request.getParameter("userName");
        System.out.println("姓名:" + uname);
        String upwd = request.getParameter("userPwd");
        System.out.println("密码:" + upwd);

        // 获取多个参数
        //System.out.println(request.getParameterValues("hobby").length);

        // 如果登录成功,跳转到index.jsp,欢迎xxx登录;如果失败,跳转到登录页面,显示错误原因
        if (uname.equals("admin") && upwd.equals("admin")) {

            /**
             * 设置请求域:设置数据存放在作用域中,让客户端能够获取数据
             */
            request.setAttribute("userName",uname);
            /**
             * 请求转发
             */
            request.getRequestDispatcher("index.jsp").forward(request,response);
        } else {

            /**
             * 设置请求域:设置数据存放在作用域中,让客户端能够获取数据
             */
            request.setAttribute("msg","姓名或密码不正确!");
            /**
             * 请求转发
             */
            request.getRequestDispatcher("login.jsp").forward(request,response);
        }
    }
}

4.HttpServletResponse对象

  响应数据
      字符输出流 getWriter()
      字节输出流 getOutputStream();
              注:两种流不能同时使用!
 响应乱码问题
      重定向
package com.shsxt.servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * HttpServletResponse对象
 *      1. 响应数据
 *          1. 字符输出流 getWriter()
 *          2. 字节输出流 getOutputStream();
 *          注:两种流不能同时使用!
 *      2. 响应乱码问题
 *      3. 重定向
 *
 */
@WebServlet("/ser05")
public class Servlet05 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /**
         * 响应乱码解决
         *      getWriter()
         *          服务器默认编码是ISO-8859-1,响应中文必定乱码,客户端与服务端的编码格式不一致
         *      getOutputStream()
         *          传输的是字节,如果客户端与服务端的编码格式一致时,不会乱码,否则乱码。
         *
         *
         *      乱码原因:
         *          1. 编码格式不支持中文
         *          2. 客户端与服务端的编码格式不一致
         *      解决方案:
         *          1. 设置编码格式支持中文
         *          2. 设置客户端与服务端编码格式一致
         *
         *
         *          1.设置服务端的编码格式
         *              response.setCharacterEncoding("UTF-8");
         *          2. 设置客户端的编码格式
         *              response.setHeader("content-type","text/html;charset=UTF-8");
         *          或者
         *          同时设置客户端与服务端的编码格式
         *              response.setContentType("text/html;charset=UTF-8");
         *
         */
         // 1.设置服务端的编码格式
         // resp.setCharacterEncoding("UTF-8");
         // 2. 设置客户端的编码格式
         // resp.setHeader("content-type","text/html;charset=UTF-8");

        // 同时设置客户端与服务端的编码
        resp.setContentType("text/html;charset=UTF-8");

        /**
         *  响应数据
         *         1. 字符输出流 getWriter()
         *         2. 字节输出流 getOutputStream();
         */
        // 得到字符输出流
        PrintWriter writer = resp.getWriter();
        // writer.write("Hello");
        writer.write("你好");


        // 得到字节输出流
        //ServletOutputStream outputStream = resp.getOutputStream();
        // outputStream.write("Hi".getBytes());
        //outputStream.write("你好".getBytes());

    }
}

在这里插入图片描述

5.Servlet的三大域对象

1. request域对象
在一次请求中有效。请求转发有效,重定向失效。
2. session域对象
在一次会话中有效。请求转发和重定向都有效,session销毁后失效。
3. servletContext域对象
在整个应用程序中有效。服务器关闭后失效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值