javaEE - 24( 20000 字 Servlet 入门 -2 )

一: Servlet API 详解

1.1 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 中写入二进制格式数据。

注意:

  • 响应对象是服务器要返回给浏览器的内容, 这里的重要信息都是程序猿设置的. 因此上面的方法都是 “写” 方法.
  • 对于状态码/响应头的设置要放到 getWriter / getOutputStream 之前. 否则可能设置失效.

1.2 代码示例: 设置状态码

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

创建 StatusServlet 类

@WebServlet("/statusServlet")
public class StatusServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
    String statusString = req.getParameter("status");
    if (statusString != null) {
      resp.setStatus(Integer.parseInt(statusString));
   }
    resp.getWriter().write("status: " + statusString);
 }
}

部署程序, 在浏览器中通过 URL http://127.0.0.1:8080/ServletHelloWorld/statusServlet?
status=200 访问, 可以看到

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

HTTP/1.1 200
Content-Length: 11
Date: Mon, 21 Jun 2021 08:05:37 GMT
Keep-Alive: timeout=20
Connection: keep-alive

status: 200

变换不同的 status 的值, 就可以看到不同的响应结果

1.3 代码示例: 自动刷新

实现一个程序, 让浏览器每秒钟自动刷新一次. 并显示当前的时间戳.

创建 AutoRefreshServlet 类

@WebServlet("/autoRefreshServlet")
public class AutoRefreshServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
    resp.setHeader("Refresh", "1");
    long timeStamp = new Date().getTime();
    resp.getWriter().write("timeStamp: " + timeStamp);
 }
}
  • 通过 HTTP 响应报头中的 Refresh 字段, 可以控制浏览器自动刷新的时机.
  • 通过 Date 类的 getTime 方法可以获取到当前时刻的毫秒级时间戳.

部署程序, 通过 URL http://127.0.0.1:8080/ServletHelloWorld/autoRefreshServlet 访问, 可以看到浏览器每秒钟自动刷新一次.

javaEE - 24( 20000 字 Servlet 入门 -2 )_第1张图片
抓包结果

HTTP/1.1 200
Refresh: 1
Content-Length: 24
Date: Mon, 21 Jun 2021 08:14:29 GMT
Keep-Alive: timeout=20
Connection: keep-alive

timeStamp: 1624263269995

1.4 代码示例: 重定向

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

创建 RedirectServlet 类

@WebServlet("/redirectServlet")
public class RedirectServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
    resp.sendRedirect("http://www.sogou.com");
 }
}

部署程序, 通过 URL http://127.0.0.1:8080/ServletHelloWorld/redirectServlet 访问, 可以看到, 页面自动跳转到 搜狗主页 了.

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

HTTP/1.1 302
Location: http://www.sogou.com
Content-Length: 0
Date: Mon, 21 Jun 2021 08:17:26 GMT
Keep-Alive: timeout=20
Connection: keep-alive

二: 表白墙服务器版本

结合上述 API, 我们可以把之前实现的表白墙程序修改成服务器版本. 这样即使页面关闭, 表白墙的内容也不会丢失.

2.1 准备工作

  1. 创建 maven 项目.
  2. 创建必要的目录 webapp, WEB-INF, web.xml

javaEE - 24( 20000 字 Servlet 入门 -2 )_第2张图片

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 Applicationdisplay-name>
web-app>
  1. 调整 pom.xml

引入依赖, 配置生成 war 包, 以及 war 包名字


<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0modelVersion>
  <groupId>org.examplegroupId>
  <artifactId>表白墙服务器版artifactId>
  <version>1.0-SNAPSHOTversion>
  <dependencies>
    
    <dependency>
      <groupId>javax.servletgroupId>
      <artifactId>javax.servlet-apiartifactId>
      
      <version>3.1.0version>
      
      <scope>providedscope>
    dependency>
    
  <properties>
    <encoding>UTF-8encoding>
    <maven.compiler.source>1.8maven.compiler.source>
    <maven.compiler.target>1.8maven.compiler.target>
  properties>
  <dependencies>
    
    <dependency>
      <groupId>javax.servletgroupId>
      <artifactId>javax.servlet-apiartifactId>
      
      <version>3.1.0version>
      
      <scope>providedscope>
    dependency>
    <dependency>
      <groupId>mysqlgroupId>
      <artifactId>mysql-connector-javaartifactId>
      <version>5.1.45version>
    dependency>
    
  <packaging>warpackaging>
  <build>
    
    <finalName>testfinalName>
  build>
project>

6.3 web.xml

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 Applicationdisplay-name>
web-app>

6.4 hello world

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
    resp.getWriter().write("hello");
 }
}

6.5 读取请求报头

@WebServlet("/getParameter")
public class GetParameter extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String contentType = req.getHeader("Content-Type");
    // 或者使用
    String contentType = req.getContentType();
 }
}

6.6 读取 GET 请求的 query string

@WebServlet("/getParameter")
public class GetParameter extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
    String userId = req.getParameter("userId");
    String classId = req.getParameter("classId");
 }
}

6.7 读取 POST 请求的 body

@WebServlet("/postParameter")
public class PostParameter extends HttpServlet {
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
    resp.setContentType("text/html; charset=utf-8");
    req.setCharacterEncoding("utf-8");
    String userId = req.getParameter("userId");
    String classId = req.getParameter("classId");
    resp.getWriter().write("userId: " + userId + ", " + "classId: " +
classId);
 }
}

6.8 设置状态码

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

6.9 设置响应报头

@WebServlet("/autoRefreshServlet")
public class AutoRefreshServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
    resp.setHeader("Refresh", "1");
 }
}

6.10 重定向

@WebServlet("/redirectServlet")
public class RedirectServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
    resp.sendRedirect("http://www.sogou.com");
 }
}

6.11 创建新 Session

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
    HttpSession session = req.getSession(true);
    session.setAttribute("username", "admin");
    session.setAttribute("loginCount", "0");
 }
}

6.12 获取已有 Session

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
  HttpSession session = req.getSession(false);
  if (session == null) {
    // 用户没有登陆, 重定向到 login.html
    resp.sendRedirect("login.html");
    return;
 }
  // 如果已经登陆, 则从 Session 中取出数据
  String userName = (String)session.getAttribute("username");
  String countString = (String)session.getAttribute("loginCount");
}

6.13 上传文件

@MultipartConfig
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
    Part part = req.getPart("MyImage");
    System.out.println(part.getSubmittedFileName());
    System.out.println(part.getContentType());
    System.out.println(part.getSize());
    part.write("d:/MyImage.jpg");
    resp.getWriter().write("upload ok");
 }
}
<form action="upload" enctype="multipart/form-data" method="POST">
  <input type="file" name="MyImage">
  <input type="submit" value="提交图片">
form>

你可能感兴趣的:(javaEE,java-ee,servlet,java)