Servlet详解 2

HttpServletRequest

打印请求信息

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 HelloServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        // 此处返回一个 html, 在 html 里面显示刚才看到的这些 API 的接口
        // 把这些 API 的返回结果往这个 StringBuilder 里面来拼~
        StringBuilder html = new StringBuilder();
        html.append(req.getProtocol());
        html.append("<br>");
        html.append(req.getMethod());
        html.append("<br>");
        html.append(req.getRequestURI());
        html.append("<br>");
        html.append(req.getContextPath());
        html.append("<br>");
        html.append(req.getQueryString());
        html.append("<br>");
        html.append("<br>");
        html.append("<br>");
        html.append("<br>");
        // 获取到请求的 header 头
        //请求中的header是一组键值对结构
        //下面这个循环,相当于拿到键值对中所有的key
        Enumeration<String> headers = req.getHeaderNames();
        while (headers.hasMoreElements()) {
            String headerName = headers.nextElement();
            html.append(headerName);
            html.append(": ");
            html.append(req.getHeader(headerName));
            //req.getHeader(headerName)这个操作就是根据key来获取value
            html.append("<br>");
        }

        resp.getWriter().write(html.toString());
    }
}

浏览器输出结果:
在这里插入图片描述

StringBuilder和StringBuffer有啥区别?

StringBuilder:线程不安全
StringBuffer:线程安全,核心方法上带有synchronized关键字

上面的打印请求确实能够获取到请求的一些信息,但是这些方法其实用的并不是特别多
更常用的,还是获取到请求中的一些程序猿传来的参数

  • query string(按照键值对
  • body

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 GetParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 约定请求是一个 /getParameter?username=1234&password=5678
        // 就可以通过 getParameter 方法拿到用户名和密码的值.
        resp.setContentType("text/html;charset=utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        resp.getWriter().write("username=" + username + "<br>" + "password=" + password);
    }
}

当通过一下路径进行访问时可以看到
http://127.0.0.1:8080/TestServlet/getParameter

在这里插入图片描述

当没有query string的时候,getParameter获取的值为null

但是如果通过一下路径进行访问,服务器就可以获取到客户端传递过来的参数。
http://127.0.0.1:8080/TestServlet/getParameter?username=1234&password=5678

在这里插入图片描述

处理HTTP请求的body中的数据

  1. 如果body里的内容格式,是按照x-www-form-urlencoded也是使用getParameter进行处理
  2. 如果body里的内容格式,是按照form-data,此时有单独方式处理
  3. 如果body里的内容格式,是json,此时需要借助第三方库来处理

方式一

这种情况,数据的格式就是和query string是一样的

创建类:PostParameterServlet

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 PostParameterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 此处是要获取 body 的数据. 由于 GET 方法一般没有 body, 就使用 POST 方法来演示.
        // 约定请求的 body 里面是这个格式: username=123&password=456
        resp.setContentType("text/html;charset=utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        resp.getWriter().write("username=" + username + "<br>" + "password=" + password);
    }
}

创建login.html,将其放置到webapp目录中

<!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>login</title>
</head>
<body>
<form action="postParameter" method="post">
  <input type="text" name="username">
  <input type="text" name="password">
  <input type="submit" value="提交">
</form>
</body>
</html>
  • 部署程序,通过http://127.0.0.1:8080/TestServlet/login.html来进行访问

在这里插入图片描述

在这里插入图片描述

方式三

此处约定,HTTP请求形如:

{
    "username":"123",
    "password":"456"
}

创建JsonParameterServlet类

import com.fasterxml.jackson.databind.ObjectMapper;
import jdk.internal.util.xml.impl.Input;

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 UserInfo {
    public String username;
    public String password;
}

@WebServlet("/jsonParameter")
public class JsonParameterServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        // 1. 先把整个请求的 body 都读取出来.
        String body = readBody(req);
        System.out.println(body);
        // 2. 在按照 json 的格式来进行解析. (对于 json 的解析, Java 标准库没有内置的方法. Servlet 也没有现成的方法. 就需要使用第三方库来完成)
        //    此处我们想拿到的是用户名和密码~~ 因此就需要针对这里的 json 数据进行解析, 变成一个键值对结构/或者是变成一个对象.
        //    如果我们是想自己实现 json 的解析, 非常麻烦的. (json 里面能嵌套, json 的 value 也可以是另一个 json)
        //    因此, 我们就直接使用第三方库来完成~ 在 Java 中解析 json 的第三方库有很多. 此处用的是 Jackson 这个库.
        //    Jackson 是 spring 官方推荐的库.
        ObjectMapper objectMapper = new ObjectMapper();
        UserInfo userInfo = objectMapper.readValue(body, UserInfo.class);
        resp.getWriter().write("username=" + userInfo.username + "<br>" + "password=" + userInfo.password);
    }

    private String readBody(HttpServletRequest req) throws IOException {
        // 通过这个方法来读取请求中的整个 body
        // 核心操作就是 req.getInputStream 这个方法. 这个方法会得到 InputStream 对象~ 然后就可以进一步的读取里面的内容了.
        // InputStream 这个本来是咱们前面要介绍的内容. (文件操作章节) , 但是由于咱们要尽量赶一赶实习, 调整课程顺序~~

        // 1. 先拿到 body 的长度, 单位是字节
        int contentLength = req.getContentLength();
        // 2. 准备一个字节数组, 来存放 body 内容
        byte[] buffer = new byte[contentLength];
        // 3. 获取到 InputStream 对象
        InputStream inputStream = req.getInputStream();
        // 4. 读取数据, 就是从 inputStream 对象中, 读取到数据, 放到 buffer 这字节数组中
        inputStream.read(buffer);
        // 5. 得到的结果构造成一个 String
        return new String(buffer, "UTF-8");
    }
}

使用postman构造一个json格式的HTTP请求
在这里插入图片描述

使用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.1</version>
</dependency>

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伦敦看日出

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值