Servlet详解(下)

简介: Servlet详解

三. Servlet常用API


3.1 HttpServlet

HttpServlet是Servlet接口的一个实现类,并且它是一个抽象类,servlet.http包中定义了采用HTTP通信协议(一个无状态协议)的HttpServlet类;

核心方法:

方法名称

调用时机

init

在 HttpServlet 实例化之后被调用一次
destory

在 HttpServlet 实例不再使用的时候调用一次

service 收到 HTTP 请求的时候调用
doGet 收到 GET 请求的时候调用(由 service 方法调用)
doPost 收到 POST 请求的时候调用(由 service 方法调用)
doPut/doDelete/doOptions/...

收到其他请求的时候调用(由 service 方法调用)


1)关于 init 方法:


HttpServlet被实例化之后,当首次收到匹配的请求的时候,才会调用到,一般使用这个方法来做一些初始化相关的工作,init只会调用一次;


2)关于 destroy 方法:


这个方法是webapp被销毁前执行一次,用来做一些收尾工作(不建议使用);


3)关于 servlet 方法:


每次收到路径匹配的请求调用一次;


✅常见面试题:让你说一说Servlet的生命周期?

  1. init 是初始情况下调用一次;
  2. destroy 是结束之前调用一次;
  3. service 是每次收到路径匹配的请求调用一次;


3.2 HttpServletRequest

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息;


核心方法:


方法 描述
String getProtocol() 返回请求协议的名称和版本。
String getMethod() 返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
String getRequestURI()

从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请

求的 URL 的一部分。

String getQueryString() 返回指示请求上下文的请求 URI 部分。
Enumeration
getParameterNames()
返回一个 String 对象的枚举,包含在该请求中包含的参数的名
称。
String getParameter(String
name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回
null。
String[]
getParameterValues(String
name)
返回一个字符串对象的数组,包含所有给定的请求参数的值,如
果参数不存在则返回 null。
Enumeration
getHeaderNames()
返回一个枚举,包含在该请求中包含的所有的头名。
String getHeader(String
name)
以字符串形式返回指定的请求头的值。
String
getCharacterEncoding()
返回请求主体中使用的字符编码的名称。
String getContentType() 返回请求主体的 MIME 类型,如果不知道类型则返回 null。
int getContentLength() 以字节为单位返回请求主体的长度,并提供输入流,或者如果长
度未知则返回 -1
InputStream
getInputStream()
用于读取请求的 body 内容. 返回一个 InputStream 对象
@WebServlet("/ServletRequest")
public class ServletRequest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        StringBuilder stringBuilder = new StringBuilder();
        // 返回请求协议的名称和版本
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("<br>");
        // 返回请求的 HTTP 方法的名称
        stringBuilder.append(req.getMethod());
        stringBuilder.append("<br>");
        // 返回URI
        stringBuilder.append(req.getRequestURI());
        stringBuilder.append("<br>");
        // 返回在路径后的请求 URL 中的查询字符串
        stringBuilder.append(req.getQueryString());
        stringBuilder.append("<br>");
        // 在响应中设置body的类型
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write(stringBuilder.toString());
    }
}

603b4a4a30d44f0989d79f8831f57903.png


这里介绍一个最常用的API,就是getParameter,我们在开发的需求中,前端给后端传递数据时是非常常见的需求,假设这里我们把前端的姓名和密码传到后端,就可以这样写:


1)通过 query string 传递


@WebServlet("/getParameter")
public class GetParameter extends HttpServlet {
    // 通过 query string 传递
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if(username == null){
            System.out.println("username 在 query string 中不存在");
        }
        if(password == null){
            System.out.println("password 在 query string 中不存在");
        }
        System.out.println("username = " + username + " ,password = " + password);
        resp.getWriter().write("ok");
    }
}

05528f2b33c44c779385a357c9563970.png

2)通过body传递


@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置编码方式,以防乱码
        req.setCharacterEncoding("utf8");
        // 前端通过body,以form表单的格式,把用户名和密码传给服务器
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if(username == null){
            System.out.println("username 在 query string 中不存在");
        }
        if(password == null){
            System.out.println("password 在 query string 中不存在");
        }
        System.out.println("username = " + username + " ,password = " + password);
        resp.getWriter().write("ok");
    }

94c7bc38b5e545e08ee6023afecce62b.png

我们通过Postman构造请求可以发现:

8a596e7ee6a64f56bab75b9225ce2216.png

3)通过json传递(最常用的)


 在使用json之前,我们引入一个第三方库,这里可以去Maven中央仓库下载:

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.15.0</version>
        </dependency>
class User {
    public String username;
    public String password;
}
@WebServlet("/json")
public class JsonServlet extends HttpServlet {
    // 这个对象可以把 json 格式的字符串解析成 java 对象,同时也可以把 java 对象转化成一个 json 格式字符串
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 通过 post 请求的 body 传递一个 json 格式的字符串
        User user = objectMapper.readValue(req.getInputStream(), User.class);
        System.out.println("username = " + user.username + ", password = " + user.password);
        resp.getWriter().write("ok");
    }
}

通过Postman构造请求可以发现:

0216cbaa5c17448296022895b3c25f72.png

3616d4bb255d4c579433b31d812a8639.png

上述的 readValue 方法主要做的是:


1.解析json字符串,转换成若干个字符串;

2.根据第二个参数类对象(Use.class),去找到 User 里的 public 的属性;

3.遍历属性,根据属性的名字,去查询键值对,看看这个属性的名字是否存在对应的 value,如果存在,就把 value 赋值到该属性中;

3.2 HttpServletResponse

HttpServletResponse表示一个HTTP响应


核心方法:

方法 描述
void setStatus(int sc) 为该响应设置状态码。
void setHeader(String name,
String value)
设置一个带有给定的名称和值的 header. 如果 name 已经存在,
则覆盖旧的值.
void addHeader(String
name, String value)
添加一个带有给定的名称和值的 header. 如果 name 已经存在,
不覆盖旧的值, 并列添加新的键值对
void setContentType(String
type)
设置被发送到客户端的响应的内容类型。
void
setCharacterEncoding(String
charset)
设置被发送到客户端的响应的字符编码(MIME 字符集)例如,
UTF-8。
void sendRedirect(String
location)
使用指定的重定向位置 URL 发送临时重定向响应到客户端。
PrintWriter getWriter() 用于往 body 中写入文本格式数据.
OutputStream
getOutputStream()
用于往 body 中写入二进制格式数据.
@WebServlet("/response")
public class ServletResponse extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(200);
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("返回200响应");
    }
}

055298edb3a54806805ccf14d009e8c8.png


设置重定向:


@WebServlet("/redirect")
public class ServletRedirect extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置状态码
        resp.setStatus(302);
        // 设置重定向的网页地址
        resp.setHeader("location","https://www.baidu.com");
    }
}

这里就直接跳转到了百度的网页了!

目录
相关文章
|
XML Java 应用服务中间件
Servlet详解(上)
Servlet详解
83 0
|
6月前
|
JSON Java 应用服务中间件
|
6月前
|
XML 前端开发 Java
servlet使用
servlet使用
|
6月前
|
Oracle Java 关系型数据库
浅谈Servlet
浅谈Servlet
28 0
|
小程序 Java 应用服务中间件
Servlet这些你可能还不知道
Servlet这些你可能还不知道
63 0
|
前端开发 JavaScript 应用服务中间件
Servlet1(2)
Servlet1(2)
67 0
|
XML JavaScript 前端开发
servlet详解
servlet详解
|
小程序 Java 应用服务中间件
Servlet1(1)
Servlet1(1)
77 0
|
应用服务中间件
Servlet的详细使用(上)
Servlet的详细使用(上)
93 0
Servlet的详细使用(下)
Servlet的详细使用(下)
54 0