【浅学Java】Servlet详解

1. 什么是Servlet

Servlet是TomCat提供给程序员的一组API,帮助程序员简单高效的开发一个Web app.

Servlet 主要做的工作:

  1. 允许程序猿注册一个类, 在 Tomcat 收到某个特定的 HTTP 请求的时候, 执行这个类中的一些代码.
  2. 帮助程序猿解析 HTTP 请求, 把 HTTP 请求从一个字符串解析成一个 HttpRequest 对象.
  3. 帮助程序猿构造 HTTP 响应. 程序猿只要给指定的 HttpResponse 对象填写一些属性字段, Servlet 就会自动的安装 HTTP 协议的方式构造出一个 HTTP 响应字符串, 并通过 Socket 写回给客户端.

2. 创建一个Servlet程序

1. 创建项目 (Maven)

new project ——> 选择Maven ,即可创建一个Maven项目

项目的目录结构:
在这里插入图片描述

2. 引入依赖

这里引入的依赖就是写Servlet程序需要的依赖(Servlet的 jar 包)。
之前在JDBC变成时,引入mysql的驱动包时手动导入,这里我们依赖maven来实现自动导入

  1. 在 https://mvnrepository.com/ 找到servlet,然后选择3.1.0版本
    在这里插入图片描述
  2. 选中这一串1内容,将其拷贝到pom.xml文件中
    在这里插入图片描述
    注意:第一次使用会有如下标红
    在这里插入图片描述
    一般会自动下载,如果没有自动下载,那就点击如下刷新按钮:
    在这里插入图片描述

3. 创建一些新目录

在这里插入图片描述

<!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>
</web-app>

4. 编写代码

  1. 创建HelloServlet,继承HttpServlet
    在这里插入图片描述
  2. 构造响应在这里插入图片描述
  3. 注意:
    在这里插入图片描述

5. 打包

在这里插入图片描述
此时打成的包是一个jar包,但是Tomcat只能识别war包,所以要打成war包。此时就得修改pom.xml,让打成的包是一个war包

<packaging>war</packaging>//打成war包
    <build>
        <finalName>hello_servlet</finalName>//打成的包名叫做hello_servlet
    </build>

此时就会形成一个war包:
在这里插入图片描述

6. 部署

将刚才打成的war包拷贝到Tomcat的webapp当中

  1. 打开war目录复制war
    在这里插入图片描述
  2. 粘贴到Tomcat的webapp,然后启动Tomcat

在这里插入图片描述

7. 验证程序

执行结果:
在这里插入图片描述
URL分析:
在这里插入图片描述

3. 简化创建Servlet的步骤

上述的7个步骤中,1 ~ 3在一个项目中操作一次就行了,而5 ~ 7在每次修改代码之后,都得进行一遍。所以,我们就从5 ~ 7入手进行简化。

1. 安装plugin插件——Smart Tomcat

Smart Tomcat的功能就是在idea中调用Tomcat。
安装之后,启动Tomcat就不需要找到Tomcat脚本来启动,直接在idea中就直接可以启动。

在这里插入图片描述
安装后进行重启。

2. Smart Tomcat的使用

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

4. Servlet API详解

1. HttpServlet

我们写 Servlet 代码的时候, 首先第一步就是先创建类, 继承自 HttpServlet, 并重写其中的某些方法.
在这里插入图片描述
我们实际开发的时候主要重写 doXXX 方法, 很少会重写 init / destory / service

1. 如何构造一个post请求

在前面,我们王浏览器中之家输入一个URL构造的都是get请求,下面我们看看怎么构造一个post请求:

  1. form表单(只支持get和post)
  2. ajax

这里我们采用ajax构造一个get请求:

  1. 创建一个html文件(注意文件目录的位置)
    在这里插入图片描述
  2. 写html代码
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<div>

</div>
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
<script>
        $.ajax({
            type:'post',
            url:'hello',
            success:function(body){
                console.log(body);
            }
        });
     </script>
</body>>
</html>
  1. 测试请求
    在这里插入图片描述

2. 利用Postman构造请求

在这里插入图片描述

【面试】谈谈HttpServlet的生命周期

这个主要考查的就是啥时机调用啥方法

  1. 首次使用,先调用一次init
  2. 每次收到请求,调用service,在service内部通过方法来决定调用哪个doXXX
  3. 销毁之前调用destroy

2. HttpServletRequest

当 Tomcat 通过 Socket API 读取 HTTP 请求(字符串), 并且按照 HTTP 协议的格式把字符串解析成HttpServletRequest 对象.

1. 核心方法

在这里插入图片描述

2. 测试代码:

@WebServlet("/showRequest")
public class ShowRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //调用一下RequestServlet里面的常用方法
        //把调用的结果显示到页面上
        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>");

        Enumeration<String> headerNames = req.getHeaderNames();
        while(headerNames.hasMoreElements()){
            String name=headerNames.nextElement();
            stringBuilder.append(name+":"+req.getHeader(name));
            stringBuilder.append("<br>");
        }

        resp.setContentType("text/html; charset=utf-8");//让浏览器知道body的数据格式是啥
        resp.getWriter().write(stringBuilder.toString());
    }
}

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

3. 注意事项:

在这里插入图片描述
2.在这里插入图片描述
两者之间的先后顺序不能乱

3. 传参的方式

1. 通过query string传参

@WebServlet("/studentInfo")
public class StudentInfoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //假设客户端发来的请求形如:/studentInfo?studentId=104&studentId=20
        //就可以通过getParameter方法拿到两个Id的值
        String queryString = req.getQueryString();
        System.out.println(queryString);
        //getParameter方法的效果就是拿到queryString中的键值对
        String classId=req.getParameter("classId");
        String studentId=req.getParameter("studentId");
        System.out.println("classId: "+classId + " studentId: "+studentId);
        resp.getWriter().write("classId: "+classId + " studentId: "+studentId);
    }
}

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

2. 通过post请求的body传参(格式为x-www-from-urlencoded)

代码:

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html; charset=utf-8");
        //获取到body中的参数
        //约定 body 使用 application/x-www-from-urlencoded 这种格式来传参
        //这个格式就相当于calssId=104&studentId=20
        //这个格式和query string相同,只是数据在body中
        String classId = req.getParameter("calssId");
        String studentId = req.getParameter("studentId");
        System.out.println("classId: "+classId + " studentId: "+studentId);
        resp.getWriter().write("classId: "+classId + " studentId: "+studentId);
    }

postman构造post请求:
在这里插入图片描述
运行结果:
在这里插入图片描述

3. 利用form标签

创建文件:
在这里插入图片描述
代码展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>通过form构造请求</title>
</head>
<body>
    <form action="studentInfo" method="post">
        <input type="text" name="classId">
        <input type="text" name="studentId">
        <input type="submit" name="提交">
    </form>
</body>
</html>

浏览器访问:
在这里插入图片描述

利用fiddler抓包:
在这里插入图片描述

4. 构造JSON格式的HttpServletResponse

问题分析:
在这里插入图片描述
Jackson下载安装:

将下面得代码复制到pom.xml并刷新:

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

核心代码(将json转换成字符串):

//这里属性得名字,应该与 json 的key保持一致
//这里的属性是public或者提供的public的getter方法
class Student{
    public int classId;
    public int studentId;
}
@Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理JSON格式的请求
        ObjectMapper objectMapper = new ObjectMapper();
        //从请求的body中进行读取,并解析
        //使用 readValue 来吧json字符串转称java对象
        //第一个参数是一个 String 或者是一个InputStream
        //第二个参数是转换的结果对应得 Java类对象
        Student student=objectMapper.readValue(req.getInputStream(),Student.class);
        System.out.println(student.classId+","+student.studentId);
        resp.getWriter().write(student.classId+","+student.studentId);
    }

运行结果:
在这里插入图片描述
方法总结:

objectMapper.readValue()——把json字符串转成java对象
objectMapper.writeValue()——把java对象转成json字符串

3. HttpServletResponse

0. HttpServletResponse的核心方法

在这里插入图片描述

1. 设置状态码

以404为例

@WebServlet("/status")
public class StatusCodeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(404);
    }
}

运行结果:
在这里插入图片描述
抓包结果:
在这里插入图片描述

2. 自动刷新

自动刷新就是给报文header设置Refresh属性,设置的value值就是N秒之后刷新。

@WebServlet("/refresh")
public class RefreshServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setHeader("Refresh","1");
        resp.getWriter().write(System.currentTimeMillis()+"");
    }
}

运行结果:
在这里插入图片描述
抓包结果:
在这里插入图片描述

3. 重定向

@WebServlet("/rediret")
public class RediretServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //约定跳转到搜狗主页
        resp.setStatus(302);
        resp.setHeader("Location","http://www.sogou.com");
    }
}

运行结果:在浏览器输入127.0.0.1:8080/hello_servlet/rediret
在这里插入图片描述
抓包结果:
在这里插入图片描述
提示,也可以这样,效果一样:
在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值