【JavaWeb】Servlet API详解

【JavaWeb】Servlet API详解

目录

HttpServlet类

核心方法

init方法

destroy方法

doGet方法

doPost方法等其他方法

Servlet的生命周期

小结

HttpServletRequest类

核心方法

前端后端传参的方法

get中的query string

​编辑post中的form

post中的json(使用Postman)

HttpServletRespond类

核心方法


HttpServlet类

当写Servlet代码的时候,首先就是要创建类,然后继承这个HttpServlet这个类,重写里面的方法。

核心方法

方法 说明
init() 在HttpServlet实例化之后首先会调用这个方法。(HttpServlet只是在在程序启动时实例化一次,不是每次收到请求就创建实例。而且不是一实例化就会调用,而是收到了相关请求后才开始调用
destroy() 只有主动关闭才可以调用这个方法。如果是杀进程就可能执行不到。
service() 收到HTTP请求的时候调用
doGet() 收到get请求的时候调用(由service方法调用)
doPost() 收到post请求的时候调用(由service方法调用)
其他方法 收到其他方法请求的时候调用(由service方法调用)

init方法

java">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("/TestHttpServlet")
public class TestHttpServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        // 当这个类被实例化,会先执行 init方法
        System.out.println("init 方法执行");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet 方法被执行");
    }
}

destroy方法

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("/TestHttpServlet")
public class TestHttpServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet 方法被执行");
    }

    @Override
    public void destroy() {
        System.out.println("destroy 方法被执行");
    }
}

doGet方法

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("/TestHttpServlet")
public class TestHttpServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet 方法被执行");

        // 中文响应如果不设置字符,就会出现乱码
        resp.setContentType("text/html; charset=utf-8");
        
        resp.getWriter().write("这是服务器给你浏览器的响应!");
    }
}

doPost方法等其他方法

使用Postman构造浏览器请求

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("/TestHttpServlet")
public class TestHttpServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost 方法被执行");
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doDelete 方法被执行");
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPut 方法被执行");
    }
}

使用ajax构造浏览器请求

①建文件

②引入依赖

 ③构造请求代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajax构造请求</title>
</head>
<body>
    <script src="https://code.jquery.***/jquery-3.6.4.min.js"></script>
    <script>
        $.ajax(
            {
                // 改变type类型即可
                type: 'put',
                url: 'http://localhost:9000/J-20230316-TestHttpServlet/TestHttpServlet'
            }
        )
    </script>
</body>
</html>

Servlet的生命周期

Servlet程序的生命周期和它上面的方法息息相关。

Servlet程序启动的时候使用一次init方法

Servlet程序运行过程中会多次使用service方法

Servlet程序销毁前会使用一次destroy方法。


小结


HttpServletRequest类

该类是通过Tomcat解析构造后表示的HTTP请求。

核心方法

方法 描述
String getProtocol() 返回请求协议的名称和版本
String getMethod() 返回请求的HTTP方法的名称
String getRequestURL()

返回从协议名称到HTTP请求的得一行查询字符串

String getContextPath() 返回指示请求上下文的请求URL部分
String getQueryString() 返回在路径后的URL查询字符串
Enumeration<String> getParamenterNames() 返回一个String对象的枚举,是该请求中包含参数的名称
String getParameter(String name) 返回请求参数的值,不存在就返回null
String[] getParameterValues(String name) 返回一个字符串对象的数组,包含所有给定的
Enumeration<String> getHeaderNames() 返回一个枚举,是请求中报头的所有名字(Key)
String getHeader(String name) 返回指定请求报头中对应name的值(Value)
String getCharacterEncoding() 返回请求的字符编码的名称
String getContentType() 返回请求主题的MIME(请求消息的类型),不知道类型就返回null
int getContentLength() 返回请求主题的长度(单位:字节)长度未知返回 -1
InputStream getInputStream() 用于读取请求的正文内容,返回一个InputStream对象

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;
import java.util.Enumeration;

@WebServlet("/TestRequest")
public class TestHttpServletRequest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getMethod());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getRequestURI());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getContextPath());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getQueryString());
        stringBuilder.append("<br>");
        stringBuilder.append("<br>");
        stringBuilder.append("<br>");
        stringBuilder.append("<br>");
        stringBuilder.append("<br>");

//        请求报头
        Enumeration<String> headerKeys = req.getHeaderNames();
        while (headerKeys.hasMoreElements()) {
            String headKey = headerKeys.nextElement();
            String headerValue = req.getHeader(headKey);
            stringBuilder.append(headKey + ": " + headerValue);
            stringBuilder.append("<br>");
        }

//        把响应中的Content-Type设置一下,告诉浏览器是什么格式的数据
        resp.setContentType("text/html");
        resp.getWriter().write(stringBuilder.toString());
    }
}

前端给后端传参的方法

get中的query string

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("/getParameter")
public class TestGetParameter extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//      通过query string 来给后端传参
//      这里 服务器确定了query string中的 Key,浏览器发一个 /getParameter?studentId=1&classId=2 的请求
//      服务器通过 getParameter方法就可以拿到结果
        String sId = req.getParameter("studentId");
        String cId = req.getParameter("classId");

//      拿到数据可以做其他事情,这里原封不动的返回
        resp.setContentType("text/html");
        resp.getWriter().write("studentId = " + sId + " classId = " + cId);
    }
}

post中的form

WEB-INF目录写一下前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>通过form表单构造请求</title>
</head>
<body>
     <!-- 相对路径 -->
    <form action="postParameter" method="post">
        <input type="text" name="studentId">
        <input type="text" name="classId">
        <input type="submit" value="提交">
    </form>
</body>
</html>

Java代码

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("/postParameter")
public class TestPostParameter extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        通过form 表单提交数据给服务器
        String sId = req.getParameter("studentId");
        String cId = req.getParameter("classId");

        //        把数据返回去
        resp.setContentType("text.html");
        resp.getWriter().write("studentId = " + sId + " classId = " + cId);
    }
}

 浏览器发送请求

使用Fiddler抓包查看报文

post中的json(使用Postman)

Java后端代码

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;
import java.io.InputStream;


@WebServlet("/postParameter2")
public class TestPostParameter2 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//      获取请求的长度
        int len = req.getContentLength();
//      使用buffer数据来存储req的数据
        byte[] buffer = new byte[len];
//      通过该方法获取body中的数据
        InputStream inputStream = req.getInputStream();
//      把获取的数据填入buffer数据中
        inputStream.read(buffer);
        String body = new String(buffer);
        System.out.println(body);
    }
}

Postman构造的前端请求 

通过上面的方法,我们只是获取到了全部的数据,并没有解析出键值对

此时需要通过maven引入第三方库——Jackson

Maven Repository: ***.fasterxml.jackson.core » jackson-databind » 2.14.2 (mvnrepository.***)

  

<!-- https://mvnrepository.***/artifact/***.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>***.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.14.1</version>
</dependency>

pom.xml文件下粘贴进去

创建出对应的的类 (最开始的时候前端和后端约定好的)

// 这个类和前端的json要匹配
class Student {
//  这里的成员要么用public修饰
//  如果用其他修饰符修饰,就必须提供对应的getter和setter方法
//  否则jackson就无法获取到成员,也就无法给其解析赋值
    public String studentId;
    public String classId;
}

完整代码

import ***.fasterxml.jackson.databind.ObjectMapper;

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;

// 这个类和前端的json要匹配
class Student {
//  这里的成员要么用public修饰
//  如果用其他修饰符修饰,就必须提供对应的getter和setter方法
//  否则jackson就无法获取到成员,也就无法给其解析赋值
    public String studentId;
    public String classId;
}

@WebServlet("/postParameter2")
public class TestPostParameter2 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//      该类是使用jackson的核心类
        ObjectMapper objectMapper = new ObjectMapper();
//      这个readValue是把请求流中解析然后变成指定的Java类
        Student student = objectMapper.readValue(req.getInputStream(), Student.class);
//      在服务器这里打印日志
        System.out.println("studentId: " + student.studentId + " studentClass: " + student.classId);
    }
}

 抓包结果

服务器

 


HttpServletRespond类

上面的代码中或多或少已经使用到了这个类,这个类就是服务器给客户端返回响应用的。

核心方法

方法 说明
void setStatus(int sc) 设置响应状态码
void setHeader(String name, String value) 设置名称为name值为value的头部,如果name已经存在,覆盖旧的,添加新的键值对
void addHeader(String name, String value) 添加名称为name值为value的头部,如果name已经存在,不覆盖旧的,添加成新的键值对
void setContentType(String type) 设置响应内容的格式(同时也可以设置字符编码集,在type字符串中,使用分号和前面的格式字符串隔开)
void setCharacterEncoding(String
charset)
设置字符编码集。如果不设置,浏览器则会随机选一个编码集,这样可能出现乱码
void sendRedirect(String location)
发送重定向的URL到浏览器
PrintWriter getWriter()
往正文中写文本格式数据
OutputStream getOutputStream() 往正文中写二进制格式数据

①状态码和响应头的位置要放到 getWriter和getOutputStream方法前面,否则可能会失效。

②setContentType 和setCharacterEncoding 要也要放到前面,否则会不生效。

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("/testRespond")
public class TestHttpServletRespond extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//      使用query string 来给后端传参数
        String sId = req.getParameter("studentId");
        String cId = req.getParameter("classId");

//      如果成功 默认是200,不设置也可以
        resp.setStatus(200);
//      这里设置响应内容的格式 同时也设置了字符集
        resp.setContentType("text/html; charset = utf8");

//      给浏览器返回正文响应
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("学生ID:" + sId + "<br>" + "学生班级:" + cId);
        resp.getWriter().write(stringBuilder.toString());

    }
}

测试重定向

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("/ReDirect")
public class TestReDirect extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//      重定向状态码是 302
        resp.setStatus(302);
//      转到bing
        resp.sendRedirect("https://***.bing.***");
    }
}

 

 


有什么错误评论区指出。希望可以帮到你。 

转载请说明出处内容投诉
CSS教程_站长资源网 » 【JavaWeb】Servlet API详解

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买