关于Servlet编程(2)

1.常用类的关键API介绍

Servlet中常见的类有三个.介绍过了HttpServlet类.我们再来看看另外两个.

HttpServletRequest

这个类对应到发送的HTTP请求.

方法 描述
String getProtocol() 返回请求协议的名称和版本
String getMethod() 返回请求的 HTTP 方法的名称 (GET,POST 或 PUT)
String getRequestURI() 返回该请求中的 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() 返回请求类型,如果不知道类型则返回 null
int getContentLength() 以字节为单位返回请求主体的长度, 如果长度未知则返回 -1
InputStream getInputStream() 用于读取请求的 body 内容. 返回一个 InputStream 对象.

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) 设置响应的字符编码
void sendRedirect(String location) 设置并发送重定向URL到客户端
PrintWriter getWriter() 用于往 body 中写入文本格式数据
OutputStream getOutputStream() 用于往 body 中写入二进制格式数据

2.构造和获取JSON数据

这里我们用到一个新的依赖 jackson

首先要在pom.xml中的 标签中添加jackson的依赖.


    <dependency>
        <groupId>com.fasterxml.jackson.coregroupId>
        <artifactId>jackson-databindartifactId>
        <version>2.12.6.1version>
    dependency>

2.1.使用jackson

在html中构造JSON数据

doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>jacksontitle>
head>
<body>
<h2>JSONh2>
<input type="text" id="userId"> <br/>
<input type="text" id="classId"> <br/>
<input type="submit" value="提交" id="submit"> <br/>

<script src="https://code.jquery.com/jquery-3.6.1.min.js">script>
<script>
    let userIdInput = document.querySelector('#userId');
    let classIdInput = document.querySelector('#classId');
    let button = document.querySelector('#submit');

    button.onclick = function () {
        $.ajax({
            type: 'post',
            url: 'postJson',
            contentType: 'application/json',
            data: JSON.stringify({
                userId: userIdInput.value,
                classId: classIdInput.value
            }),
            success: function (body) {
                console.log(body);
            }
        });
    }
script>
body>
html>

在后端中读取JSON数据

  • ObjectMapper : jackson提供的工具类
  • readValue方法 : 把JSON格式字符串转成Java的对象
    • 第一个参数,表示对哪个字符串进行转换
      • 这个参数可以填写成一个String
      • 可以是一个流对象
      • 可以是一个File
    • 第二个参数,表示要把这个JSON格式字符串转成哪个Java对象
class User {
    public int userId;
    public int classId;
}

@WebServlet(name = "PostJsonServlet", value = "/postJson")
public class PostJsonServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //jackson提供的工具类
        ObjectMapper objectMapper = new ObjectMapper();
        //readValue方法.把JSON格式字符串转成Java的对象
        //第一个参数,表示对哪个字符串进行转换,这个参数可以填写成一个String,也可以是一个流对象,还可以是一个File
        //第二个参数,表示要把这个JSON格式字符串转成哪个Java对象.
        User user = objectMapper.readValue(request.getInputStream(), User.class);
        response.getWriter().write("userId=" + user.userId + "classId=" + user.classId);
    }
}

readValue是怎么完成转换的?

  1. 先把 getInputStream对应的流对象里面的数据都读取出来
  2. 针对这个json字符串进行解析
    • 从字符串=>键值对
  3. 遍历这个键值对赋值
    • 依次获取到每一个key,根据这个key的名字,和User类里面的属性名字对比,看有没有匹配的名字
    • 如果发现匹配的属性则把当前key 对应的value赋值到该User类的属性中
      • 赋值的过程中同时会进行类型转换
    • 如果没有匹配到的属性就跳过

3.编写代码来理解这两个API的方法.

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

@WebServlet(name = "ShowRequestServlet", value = "/show")
public class ShowRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //注意是 text  !!不是test
        //设置返回的数据格式.
        response.setContentType("text/html; charset=utf8");
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("

首行部分

"
); //返回请求协议的名称和版本 stringBuilder.append(request.getProtocol()); stringBuilder.append("
"
); //返回请求使用的方法 stringBuilder.append(request.getMethod()); stringBuilder.append("
"
); //返回请求中从一级目录开始到到请求中查询字符串以前 stringBuilder.append(request.getRequestURI()); stringBuilder.append("
"
); //返回请求中上下文的请求 URI 部分 stringBuilder.append(request.getContextPath()); stringBuilder.append("
"
); //返回请求中的查询字符串(参数部分) stringBuilder.append(request.getQueryString()); stringBuilder.append("
"
); stringBuilder.append("

header部分

"
); //获取请求头中的内容(枚举的方式返回) Enumeration<String> headerNames = request.getHeaderNames(); //循环读取返回的请求头中的内容 while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); String headerVlaue = request.getHeader(headerName); stringBuilder.append(headerName + ": " + headerVlaue + "
"
); } response.getWriter().write(stringBuilder.toString()); } }

在浏览器路径中输入 http://localhost:8080/e/show?a=10&b=20 来查看结果.

关于Servlet编程(2)_第1张图片


3.2.获取请求中的参数

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(name = "GetParameterServlet", value = "/getParameter")
public class GetParameterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html; charset=utf8");
        //预期请求格式 /getParameter?userId=123&classId=456
        String userId = request.getParameter("userId");
        String classId = request.getParameter("classId");
        response.getWriter().write("userId = " + userId + " classId = " + classId);
    }
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html; charset=utf8");
        //假设前端传过来的参数是 userId=10&classId=20
        //服务器可以通过req.getParameter来获取参数.
        String userId = request.getParameter("userId");
        String classId = request.getParameter("classId");
        response.getWriter().write("userId = " + userId + " classId = " + classId);
    }
}

直接在浏览器路径中输入 http://localhost:8080/e/getParameter?userId=31&classId=10 .构造的是GET请求.获得如下结果. 因为逻辑代码相同,所以使用Postman构造POST请求获取的结果相同.

在这里插入图片描述


3.3.设置响应状态码并显示到页面

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(name = "StatusServlet", value = "/status")
public class StatusServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置响应状态码并显示到页面
        response.setStatus(200);
        response.getWriter().write(response.getStatus());
    }
}

在浏览器路径中输入 http://localhost:8080/e/status 得到如下结果.

关于Servlet编程(2)_第2张图片


3.4.网页自动刷新

Header中有一个的 Refresh:xx 表示每隔多久刷新网页.单位是秒.所以我们在header中添加这个信息就可以实现网页自动刷新的功能.

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(name = "AutoRefreshServlet", value = "/auto")
public class AutoRefreshServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html; charset=utf8");
        //Refresh Header中的Refresh:表示每隔多久刷新网页.
        //这里表示1秒刷新一次
        response.setHeader("Refresh", "1");
        //获得时间戳并返回
        response.getWriter().write("timeStamp: " + System.currentTimeMillis());
    }
}

在浏览器路径中输入 http://localhost:8080/e/auto 得到如下结果.
关于Servlet编程(2)_第3张图片

等待一下会发现页面会一直自动刷新.

关于Servlet编程(2)_第4张图片


3.5.重定向

重定向 : 返回一个 302 重定向响应,并重定向到新页面

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(name = "RedirectServlet", value = "/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //重定向 返回一个 302 重定向响应,自动跳转
        response.setStatus(302);
        response.setHeader("Location", "https://blog.csdn.net/m0_58154870/article/details/128259772");
    }
}

Servlet提供的更简便的重定向写法.一句话完成两步工作.

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(name = "RedirectServlet", value = "/redirect")
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        response.setStatus(302);
//        response.setHeader("Location", "https://blog.csdn.net/m0_58154870/article/details/128259772");
        //重定向 Servlet提供的更简便的重定向写法.一句话完成上述两步工作.
        response.sendRedirect("https://blog.csdn.net/m0_58154870/article/details/128259772");
    }
}

地址栏输入 http://localhost:8080/e/redirect 后会重定向到新页面

关于Servlet编程(2)_第5张图片

关于Servlet编程(2)_第6张图片

你可能感兴趣的:(鱼小飞代码之旅,servlet,java,后端)