ServletAPI的使用

目录

一、HttpServlet

1.1 HttpServlet的核心方法

1.2 Servlet的生命周期

1.3 代码示例:通过postman来发送请求

1.4 代码示例:通过ajax来发送请求

二、HttpServletRequest

2.1 代码示例:打印请求信息:

2.2 代码示例:获取Get请求中的参数

2.2 代码示例:通过form表单获取POST请求中的参数

2.3 代码示例:通过json获取POST请求中的参数

三、HttpServletResponse

3.1 代码示例: 设置状态码

3.2 代码示例: 重定向


虽然Servlet提供的类和方法很多,但是最主要的其实也就三个:HttpServlet、HttpServletRequest、HttpServletResponse。

一、HttpServlet

1.1 HttpServlet的核心方法

写servlet代码时,创建的类往往都继承自HttpServlet,并重写其中的方法。

方法名称 调用时机
init 在 HttpServlet 实例化之后被Tomcat调用一次
destory 在 HttpServlet 实例不再使用的时候调用一次
service 收到 HTTP 请求的时候调用
doGet 收到 GET 请求的时候调用(由 service 方法调用)
doPost 收到 POST 请求的时候调用(由 service 方法调用
doPut/doDelete/doOptions/... 收到其他请求的时候调用(由 service 方法调用)

我们实际开发的时候主要重写 doXXX 方法, 很少会重写 init / destory / service

需要注意的是:

1)  init方法是在HttpServlet首次实例化的时候被Tomcat调用(非自己调用)。

HttpServlet什么时候被实例化呢?

当Tomcat首次收到和该类相关联的请求的时候(这种模式类似于懒汉模式)

举个例子:

ServletAPI的使用_第1张图片

ServletAPI的使用_第2张图片

ServletAPI的使用_第3张图片

2) destory是不一定能够执行到的。

因为如果是通过直接杀死进程的方式,那么destroy就可能来不及执行就没了

如果是通过smart tomcat的停止按钮(本质是通过控制tomcat上的8005这个端口进行主动停止),是可以的。

3)Tomcat每次收到请求后(收到的前提是路径得匹配),实际上是先调用service 。

在service中再根据方法,调用不同的doXXX方法。实际开发的过程中很少重写service,基本是重写doXXX方法。

1.2 Servlet的生命周期

Servlet 生命周期可被定义为:从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

  1. 当一个请求从Http服务器转发给Servlet容器的时候,容器检查对应的Servlet是否创建,没有创建就实例化该Servlet,并调用init()方法,init()方法只调用一次,之后的请求都是从第二步开始。
  2. Servlet 调用 service() 方法,根据请求类型转发给对应的方法来处理,如doGet,doPost等等。
  3. Servlet 销毁前调用 destroy() 方法,该方法只调用一次。
  4. 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

ServletAPI的使用_第4张图片

1.3 代码示例:通过postman来发送请求

ServletAPI的使用_第5张图片

1.4 代码示例:通过ajax来发送请求

什么是Ajax?

Ajax即”Asynchronous JavaScript and XML“(异步的JavaScript与XML技术),指的是一套综合了多项技术的浏览器端网页开发技术。

传统的Web应用允许用户端填写表单(form),当提交表单时就向网页服务器发送一个请求。服务器接收并处理传来的表单,然后送回一个新的网页,但这个做法浪费了许多带宽,因为在前后两个页面中的大部分HTML码往往是相同的。由于每次应用的沟通都需要向服务器发送请求,应用的回应时间依赖于服务器的回应时间。这导致了用户界面的回应比本机应用慢得多。

与此不同,AJAX应用可以仅向服务器发送并取回必须的数据,并在客户端采用JavaScript处理来自服务器的回应。因为在服务器和浏览器之间交换的数据大量减少,服务器回应更快了。同时,很多的处理工作可以在发出请求的客户端机器上完成,因此Web服务器的负荷也减少了。

ServletAPI的使用_第6张图片

ServletAPI的使用_第7张图片

二、HttpServletRequest

在 Servlet API 中,定义了一个 HttpServletRequest 接口,它继承自 ServletRequest 接口。HttpServletRequest 对象专门用于封装 HTTP 请求消息,简称 request 对象。

HTTP 请求消息分为请求行、请求消息头和请求消息体三部分,所以 HttpServletRequest 接口中定义了获取请求行、请求头和请求消息体的相关方法:

方法 描述
String getProtocol() 返回请求协议的名称和版本。
String getMethod() 返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
String getRequestURI() 从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该
请求的 URL 的一部分。
String getContextPath() 返回指示请求上下文的请求 URI 部分。
String getQueryString() 返回包含在路径后的请求 URL 中的查询字符串。
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 对象.

 2.1 代码示例:打印请求信息:

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("/showRequest")
public class ShowRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        这里给响应的数据类型设置Content-type
        resp.setContentType("text/html");
//        定义一个StringBuilder,把这些操作api结果拼起来,统一写到响应中
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("
"); stringBuilder.append(req.getMethod()); stringBuilder.append("
"); stringBuilder.append(req.getRequestURI()); stringBuilder.append("
"); stringBuilder.append(req.getContextPath()); stringBuilder.append("
"); stringBuilder.append(req.getQueryString()); stringBuilder.append("
"); resp.getWriter().write(stringBuilder.toString()); resp.getWriter().write("
"); // 获取header的所有键值对 Enumeration headerNames = req.getHeaderNames(); while(headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); resp.getWriter().write(headerName+" :"+req.getHeader(headerName)); resp.getWriter().write("
"); } } }

 响应界面:

ServletAPI的使用_第8张图片

2.2 代码示例:获取Get请求中的参数

Get请求中的参数一般是通过query string 传递给服务器的,形如;

http://127.0.0.1:8080/hello_servlet2/getParameter?classId=2&name=22

此时的浏览器是通过query string 给服务器传递两个参数,classId和name,分别为2和22.

这时候服务器端可以通过getParameter的方式来获取数据打印到页面上:

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

@WebServlet("/getParameter")
public class GetParameterServlet extends HelloServlet{
//    假设前端传来的数据是classId和name
//    我们可以通过req里面的getParameter(返回的对象是String)来解决
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String classId = req.getParameter("classId");
        String name = req.getParameter("name");
        //需要注意的是这里的setContentType需要写在resp.getWriter().write()的上面
        resp.setContentType("text/html; charset=utf8");
        resp.getWriter().write("班级Id = "+classId + " 姓名 = "+name);
    }
}

ServletAPI的使用_第9张图片

 当然 如果query string里没有对应的值的时候,返回的对象是null:

ServletAPI的使用_第10张图片

2.2 代码示例:通过form表单获取POST请求中的参数

ServletAPI的使用_第11张图片

ServletAPI的使用_第12张图片

2.3 代码示例:通过json获取POST请求中的参数

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

class Student {
    public int studentId;
    public int classId;
}
@WebServlet("/postParameter2")
public class PostParameter2Servlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //使用jackson所涉及到的核心对象
        ObjectMapper objectMapper = new ObjectMapper();
        //readValue就是把json格式的字符串转化成java对象
        Student student = objectMapper.readValue(req.getInputStream(),Student.class);
        System.out.println(student.studentId + " , " + student.classId);

    }
}

ServletAPI的使用_第13张图片

三、HttpServletResponse

Servlet 中的 doXXX 方法的目的就是根据请求计算得到相应, 然后把响应的数据设置到
HttpServletResponse 对象中.
然后 Tomcat 就会把这个 HttpServletResponse 对象按照 HTTP 协议的格式, 转成一个字符串, 并通过Socket 写回给浏览器

核心方法

方法 描述
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 中写入二进制格式数据

3.1 代码示例: 设置状态码

实现一个程序, 用户在浏览器通过参数指定要返回响应的状态码:

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("/status")
public class StatusServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String status = req.getParameter("status");
        if (status != null) {
            resp.setStatus(Integer.parseInt(status));
        }
        resp.getWriter().write("status: " + status);
    }
}


ServletAPI的使用_第14张图片

3.2 代码示例: 重定向

实现一个程序, 返回一个重定向 HTTP 响应, 自动跳转到另外一个页面:

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 RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        resp.sendRedirect("https://www.sogou.com");
        resp.setStatus(302);
        resp.setHeader("Location","https://www.sogou.com");
    }

}

 以下为fiddler抓包结果:ServletAPI的使用_第15张图片

你可能感兴趣的:(servlet,java,前端)