您的位置:首页 > 游戏 > 游戏 > 【JavaWeb】Servlet 详解(处理逻辑及常见方法)

【JavaWeb】Servlet 详解(处理逻辑及常见方法)

2024/10/6 8:40:01 来源:https://blog.csdn.net/weixin_46531416/article/details/141938789  浏览:    关键词:【JavaWeb】Servlet 详解(处理逻辑及常见方法)

文章目录

    • 1. Tomcat
      • 1.1 常见的错误
        • 1.1.1 出现 404
        • 1.1.2 出现 405
        • 1.1.3 出现 500
      • 1.2 HttpServlet
        • 1.2.1 Tomcat 的处理逻辑
        • 1.2.2 相关方法
      • 1.3 HttpServletRequest
        • 1.3.1 常见方法
        • 1.3.2 jackson 处理逻辑
      • 1.4 HttpServletResponse
        • 1.4.1 常见方法

1. Tomcat

tomcat 是一个 HTTP 服务器程序,对 HTTP 协议进行了封装,提供了一组 API,即 Servlet

开发者自己写的代码(类),会被加载到 Tomcat 中,Tomcat 接收到请求就会执行开发者写的代码,来完成相应的业务逻辑

Maven 是一个项目构建工具,可以进行项目的依赖的管理,代码编译和打包

tomcat 收到请求之后,就有可能执行子类中的方法,HttpServletRequest 对象是 Tomcat 解析请求后构造好的对象,HttpServletResponse 对象是个输出型参数

war 是 Tomcat 专属的压缩包,不仅有 .class 文件,还有 web.xml 等 Tomcat 要求的文件以及前端代码。

Tomcat 加载 webapp 的时候,用的是自定义的类加载器,只在 webapp 指定目录中查找,找不到就抛异常,不会去标准库中查找

1.1 常见的错误

1.1.1 出现 404
  1. url 路径有问题
  2. webapp 没有正确加载(如 web.xml 有问题)
1.1.2 出现 405
  1. 请求的方法与实际写的方法不一致(如前端请求 GET,但后端写的是 POST)
  2. 没有删掉super.doGet(req, resp),导致 HTTP 响应的格式出现了问题,浏览器无法正常解析
1.1.3 出现 500
  • 服务器内部出错

1.2 HttpServlet

写 Servlet 的代码,并不需要写 main 方法,而是直接重写 HttpServlet 中的相关方法即可,Tomcat 中有 main 方法,也可以视为是一个框架。

继承 HttpServlet,重写其中的方法,就是为了将自己的代码插入到 Tomcat 中

1.2.1 Tomcat 的处理逻辑
// 通过 TCP Socket 读取请求
String requestString = readRequest();// 解析请求
HttpServletRequest req = parse(requestString);// 构造响应对象
HttpServletResponse resp = new HttpServletResponse();// 创建一个 HttpServlet 对象
HttpServlet s = new 自己写的Servlet子类();
s.doGet(req, resp);//将得到的响应 resp 返回给浏览器// ...
1.2.2 相关方法
方法名调用时机作用
init在 HttpServlet 实例化之后被调用一次完成初始化
destroy在 HttpServlet 实例不再使用的时候调用一次(HttpServlet 被销毁之前)释放资源(若直接在任务资源管理器中结束任务,则来不及调用 destroy,若通过 8005 管理端口给 Tomcat 发送一个 “停机” 指令,则会执行 destroy,大多数情况下会直接杀进程)
service收到 HTTP 请求的时候调用根据不同的方法将请求分发给 doGet、doPost 等
doGet收到 Get 请求的时候被调用计算 Get 请求的响应
doPost收到 Post 请求的时候被调用计算 Post 请求的响应

前三个方法体现了 Servlet 的生命周期

1.3 HttpServletRequest

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

1.3.1 常见方法
方法名解释
String getProtocol()返回请求协议的名称和版本
String getMethod()返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT
String getRequestURI()从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分
String getContextPath()返回指示请求上下文的请求 URI 部分
String getQueryString()返回查询字符串
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 对象(得到一个流对象,读取这个流对象就能得到整个请求的 body,不必一次性处理完所有数据,可以一次处理一点,也可以一次处理完全部)
Cookie[] getCookies()获取到请求中的所有 Cookie
HttpSession getSession()从 Cookie 中获取到 sessionId,并查询出对应的 session。若未查到,就自动创建 session,分配新的 sessionId,创建新的 HttpSession 对象,将 sessionId 和 HttpSession 存入 hash 表中,并将 sessionId 添加到响应报文的 header 中(Set-Cookie 字段)

在代码中表示一个 “不定长” 的数据时,经常会想到使用 “流对象”

1.3.2 jackson 处理逻辑

将 json 字符串转为 Java 对象,或将 Java 对象转为 json 字符串

// 将 json 字符串转为 Java 对象
Request request = objectMapper.readValue(req.getInputStream(), Request.class);
  1. json 字符串是在 http 的 body 中,需要通过 HttpServletRequest 的 getInputStream 获取到,直接将 流对象 传给 readValue, readValue 内部会读取 InputStream 中的所有数据(http 请求的 body)

  2. 将 json 字符串按照 json 的格式解析成 Map(键值对)

  3. 将 Map 转换成 java 对象(通过 Request.class 告诉 readValue 方法,将 Map 转成什么对象)

  4. readValue 内部,通过反射 API 创建 Request.class 实例,并根据其中的属性名来查询 Map,将查询结果赋值给相应的属性

    jackson 只会处理 public 的属性

// 将 Java 对象转为 json 字符串
String respJson = objectMapper.writeValueAsString(response)
  1. 通过参数 response 获取到类对象,再通过反射拿到属性名字
  2. 根据属性名拿到属性值
  3. 根据属性名和属性值构造 json 格式的字符串

1.4 HttpServletResponse

1.4.1 常见方法
方法名解释
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 中写入二进制格式数据
void addCookie(Cookie cookie)向响应中添加指定的 cookie(添加到了浏览器中)

session 不是持久化存储的

  1. 将会话进行持久化保存(文件、数据库、redis)
  2. 使用令牌的方式,将用户信息在服务器端加密,保存在浏览器

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com