专栏首页RendaJavaWeb - Servlet:基本概念,HTTP 协议,Tomcat 服务器

JavaWeb - Servlet:基本概念,HTTP 协议,Tomcat 服务器

基本概念

C/S 架构

C/S 架构(Client/Server,客户端/服务器模式),是一种比较早的软件体系结构,也是生活中很常见的结构。这种结构将需要处理的业务合理地分配到客户端和服务器端,客户端通常负责完成与用户的交互任务,服务器通常负责数据的管理。

主要优点:客户端的界面和功能可以很丰富;应用服务器的负荷较轻;响应速度较快。

主要缺点:适用面窄,用户群固定;维护和升级的成本高,所有的客户端都需要更新版本。

B/S 架构

B/S 架构(Browser/Server,浏览器/服务器模式),是互联网兴起后的软件体系结构,该结构将系统功能实现的主要业务逻辑集中到服务器端,极少数业务逻辑在浏览器实现,浏览器通常负责完成与用户的交互任务,服务器通常负责数据的管理。

主要优点:无需安装客户端,只要有浏览器即可;适用面广,用户群不固定;通过权限控制实现多客户访问的目的,交互性较强;维护和升级的成本低,无需更新所有客户端版本。

主要缺点:应用服务器的负荷较重;浏览器的界面和功能想要达到客户端的丰富程度需要花费大量的成本;在跨浏览器上不尽如人意,适配比较麻烦。

JavaWeb

Web 本意为网页的含义,这里表示互联网上供外界访问的资源。

互联网上供外界访问的资源主要分为两种:

  • 静态资源:主要指 Web 页面中供人们浏览的数据始终是不变。
  • 动态资源:主要指 Web 页面中供人们浏览的数据由程序产生,不同时间点访问页面看到的内容各不相同。

JavaWeb 主要指使用 Java 语言进行动态 Web 资源开发技术的统称,是解决相关 Web 互联网领域的技术总和。

HTTP 协议

概念

HTTP 协议(HyperText Transfer Protocol,超文本传输协议)是由 W3C(万维网联盟)组织制定的一种应用层协议,是用来规范浏览器与Web服务器之间如何通讯的数据格式,主要涉及浏览器的发请求格式和服务器的响应格式。

HTTP 协议通常承载于 TCP 协议之上,而承载于 TLS 或 SSL 协议层之上的协议就是常说的 HTTPS 协议。

HTTP 默认的端口号为 80,HTTPS 默认的端口号为 443。

请求格式

客户端发送一个 HTTP 请求到服务器的请求消息主要包括:请求行、请求头、空白行和请求体。

  • 请求行用来说明请求类型和要访问的资源以及所使用的 HTTP 版本:请求类型 请求的路径 协议的版本(1.1)
  • 请求头是紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息:key: value
  • 空白行就是请求头部的空行,即便后面的请求数据为空也必须有空行
  • 请求体也叫请求数据,可以添加任意的其他数据
POST /task01_demo01/demo1.html HTTP/1.1
Host: localhost:8088
Content-Length: 21
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64)

name=scott&pwd=123456
响应格式

通常情况下服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息,主要包括:响应行、响应头、空白行和响应体。

  • 响应行用来说明 HTTP 协议版本号和状态码以及状态消息:协议的版本(1.0 or 1.1) 状态码(200 - 成功 or 404 - 路径错误 or 500 - 服务错误) 状态信息
  • 响应头用来说明客户端要使用的一些附加信息:key: value
  • 空白行就是响应头部的空行,即便后面的请求数据为空也必须有空行
  • 响应体用来服务器返回给客户端的文本信息
HTTP/1.1 200 OK  
Content-Type: text/html
Content-Length: 588
Date: Thu, 08 Sep 2021 12:59:54 GMT

<html>
<head><title>示例1</title></head>
<body><h1>这是一个HTML页面</h1></body>
</html>

Tomcat 服务器

基本概念

Tomcat 服务器是一个开源的轻量级 Web 应用服务器,在中小型系统和并发量小的场合下被普遍使用,是开发和调试 Servlet、JSP 程序的首选。

安装方式

下载地址:http://tomcat.apache.org/

目录结构

bin:主要存放二进制可执行文件和脚本。

conf:主要存放各种配置文件。

lib:主要用来存放 Tomcat 运行需要加载的jar包。

logs:主要存放 Tomcat 在运行过程中产生的日志文件。

temp:主要存放 Tomcat 在运行过程中产生的临时文件。

webapps:主要存放应用程序,当 Tomcat 启动时会去加载该目录下的应用程序。

work:主要存放 tomcat 在运行时的编译后文件,例如 JSP 编译后的文件。

启动和关闭

启动方式:使用 bin 目录下的批处理文件 startup.bat 来启动 Tomcat 服务器,若出现一个毫秒数说明启动成功。

关闭方式:使用 bin 目录下的批处理文件 shutdown.bat 来关闭 Tomcat 服务器。

注意事项:启动之前首先安装 JDK 并配置环境变量 JAVA_HOME,若希望 Tomcat 服务器可以在任意路径启动,则需要配置环境变量 CATALINA_HOME。

启动信息乱码的处理方式:logging.properties 文件修改为 java.util.logging.ConsoleHandler.encoding = GBK

配置文件

server.xml 文件是服务器的主配置文件,可以设置端口号、设置域名或 IP、默认加载的项目、请求编码等。

<Connector port="8888" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />

tomcat-users.xml 文件用来配置管理 Tomcat 服务器的用户与权限。

<role rolename="manager-gui"/>
<user username="admin" password="123456" roles="manager-gui"/>

Servlet 的概念和使用

基本概念

Servlet(Server Applet)是 Java Servlet 的简称,称为小服务程序或服务连接器,是 Java 语言编写的服务器端程序,换句话说,Servlet 就是运行在服务器上的 Java 类。

Servlet 用来完成 B/S 架构下客户端请求的响应处理,也就是交互式地浏览和生成数据,生成动态 Web 内容。

Servlet 的编程步骤

建立一个 Java Web Application 项目并配置 Tomcat 服务器。

自定义类实现 Servlet 接口或继承 HttpServlet 类(推荐) 并重写 service 方法。

将自定义类的信息配置到 web.xml 文件并启动项目,配置方式如下:

<!-- 配置 Servlet -->
<servlet>
    <!-- HelloServlet 是 Servlet 类的别名 -->
    <servlet-name> HelloServlet </servlet-name>
    <!-- com.renda.task01.HelloServlet 是包含路径的真实的 Servlet 类名 -->
    <servlet-class> com.renda.task01.HelloServlet </servlet-class>
</servlet>
<!-- 映射 Servlet -->
<servlet-mapping>
    <!-- HelloServlet 是 Servlet 类的别名,与上述名称必须相同 -->
    <servlet-name> HelloServlet </servlet-name>
    <!-- /hello 是供浏览器使用的地址 -->
    <url-pattern> /hello </url-pattern>
</servlet-mapping>

在浏览器上访问的方式为:

http://localhost:8080/工程路径/hello
Servlet 接口
基本概念

javax.servlet.Servlet 接口用于定义所有 servlet 必须实现的方法。

常用的方法

void init(ServletConfig config) 由 servlet 容器调用,以向 servlet 指示 servlet 正在被放入服务中

void service(ServletRequest req, ServletResponse res)由 servlet 容器调用,以允许 servlet 响应请求

ServletConfig getServletConfig() 返回 ServletConfig 对象,该对象包含此 servlet 的初始化和启动参数

String getServletInfo() 返回有关 servlet 的信息,如作者、版本和版权

void destroy() 由 servlet 容器调用,以向 servlet 指示该 servlet 正在退出服务

GenericServlet 类
基本概念

javax.servlet.GenericServlet 类主要用于定义一个通用的、与协议无关的 servlet,该类实现了 Servlet 接口,只需重写 service 抽象方法即可。

常用的方法

abstract void service(ServletRequest req, ServletResponse res) 由 servlet 容器调用允许servlet 响应请求

HttpServlet 类
基本概念

javax.servlet.http.HttpServlet 类是个抽象类并继承了 GenericServlet 类。

用于创建适用于网站的 HTTP Servlet,该类的子类必须至少重写一个方法。

常用的方法

void doGet(HttpServletRequest req, HttpServletResponse resp) 处理客户端的 GET 请求

void doPost(HttpServletRequest req, HttpServletResponse resp) 处理客户端的 POST 请求

void init() 进行初始化操作

void service(HttpServletRequest req, HttpServletResponse resp) 根据请求决定调用 doGet 还是 doPost 方法

void destroy() 删除实例时释放资源

Servlet 的生命周期
  • 实例化:Servlet 容器创建 Servlet 的实例
  • 初始化:该容器调用 init() 方法
  • 服务:如果请求 Servlet,则容器调用 service() 方法
  • 销毁:销毁实例之前调用 destroy() 方法
  • 不可用:销毁实例并标记为垃圾收集

构造方法只被调用一次,当第一次请求 Servlet 时调用构造方法来创建 Servlet 的实例。

init() 方法只被调用一次,当创建好 Servlet 实例后立即调用该方法实现 Servlet 的初始化。

service() 方法被多次调用,每当有请求时都会调用该方法来用于请求的响应。

destroy() 方法只被调用一次,当该 Servlet 实例所在的 Web 应用被卸载前调用该方法来释放当前占用的资源。

POST 和 GET 请求

GET 请求

发出 GET 请求的主要方式:

  1. 在浏览器输入 URL 按回车
  2. 点击 <a> 超链接
  3. 点击 submit 按钮,提交 <form method="get"> 表单

GET 请求特点:会将请求数据添加到请求 URL 地址的后面,只能提交少量的数据、不安全

POST 请求

发出 POST 请求的主要方法:点击 submit 按钮,提交 <form method="post"> 表单

POST请求的特点:请求数据添加到 HTTP 协议体中,可提交大量数据、安全性比较好

ServletRequest 接口
基本概念

javax.servlet.ServletRequest 接口主要用于向 servlet 提供客户端请求信息,可以从中获取到任何请求信息。

Servlet 容器创建一个 ServletRequest 对象,并将其作为参数传递给 Servlet 的 service() 方法。

常用的方法

String getParameter(String name) 以字符串形式返回请求参数的值,如果该参数不存在,则返回空值

String[] getParameterValues(String name) 返回一个字符串对象数组,其中包含给定请求参数所具有的所有值,如果该参数不存在,则返回空值

Enumeration getParameterNames() 返回包含此请求中包含的参数名称的字符串对象的枚举。如果请求没有参数,则方法返回空枚举

Map<String, String[]> getParameterMap() 返回请求参数的键值对,一个键可以对应多个值

String getRemoteAddr() 返回发送请求的客户端或最后一个代理的 IP 地址

int getRemotePort() 返回发送请求的客户端或最后一个代理的端口号

HttpServletRequest 接口
基本概念

javax.servlet.http.HttpServletRequest接口是 ServletRequest 接口的子接口,主要用于提供 HTTP 请求信息的功能。

不同于表单数据,在发送 HTTP 请求时,HTTP 请求头直接由浏览器设置。

可直接通过 HttpServletRequest 对象提供的一系列 get 方法获取请求头数据。

常用的方法

String getRequestURI() 返回此请求的资源路径信息

StringBuffer getRequestURL() 返回此请求的完整路径信息

String getMethod() 返回发出此请求的 HTTP 方法的名称,例如 GET、POST

String getQueryString() 返回路径后面请求中附带的参数

String getServletPath() 返回此请求中调用 servlet 的路径部分

ServletResponse 接口
基本概念

javax.servlet.ServletResponse 接口用于定义一个对象来帮助 Servlet 向客户端发送响应。

Servlet 容器创建 ServletResponse 对象,并将其作为参数传递给 servlet 的 service() 方法。

常用的方法

PrintWriter getWriter() 返回可向客户端发送字符文本的 PrintWriter 对象

String getCharacterEncoding() 获取响应内容的编码方式

void setContentType(String type) 如果尚未提交响应,则设置发送到客户端响应的内容类型。内容类型可以包括字符编码规范,例如 text/html;charset=UTF-8

HttpServletResponse 接口
基本概念

javax.servlet.http.HttpServletResponse 接口继承 ServletResponse 接口,以便在发送响应时提供特定于HTTP 的功能。

常用的方法

void sendRedirect(String location) 使用指定的重定向位置 URL 向客户端发送临时重定向响应

使用示例
// 继承 HttpServlet
public class HelloWorld extends HttpServlet {
    // 重写 HttpServlet 中的 doGet 方法
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        // 设置响应输出编码,避免中文乱码
        response.setContentType("text/html;charset=utf-8");
        // 获取响应输出流
        PrintWriter out= response.getWriter();
        // 利用输出流输出信息
        out.println("<html><body> Hello world!</body></html>");
        // 关闭流
        out.close();
    }
}

Servlet 接收中文乱码

接收乱码原因

浏览器在提交表单时,会对中文参数值进行自动编码。当 Tomcat 服务器接收到浏览器请求后自动解码,当编码与解码方式不一致时,就会导致乱码。

解决 POST 接收乱码

接收之前设置编码方式:request.setCharacterEncoding(“utf-8”)

必须在调用 request.getParameter(“name”) 之前设置

解决 GET 接收乱码

将接收到的中文乱码重新编码:

// 接收到 get 请求的中文字符串
String name = request.getParameter("name");
// 将中文字符重新编码,默认编码为 ISO-8859-1
String userName = new String(name.getBytes("ISO-8859-1"), "utf-8");

ServletConfig 接口

基本概念

javax.servlet.ServletConfig 接口用于描述 Servlet 本身的相关配置信息,在初始化期间用于将信息传递给Servlet 配置对象。

配置方式
<!-- 在 web.xml 中配置 ServletConfig 初始化参数 -->
<servlet> 
    <servlet-name>actionservlet</servlet-name> 
    <servlet-class>com.renda.demo01.ActionServlet</servlet-class> 
    <!-- 配置 Serlvet 的初始化参数 -->
    <init-param>
        <!-- 参数名 -->
        <param-name>config</param-name> 
        <!-- 参数值 -->
        <param-value>struts.xml</param-value> 
    </init-param> 
</servlet>
常用的方法

String getServletName() 返回 Servlet 的别名

String getInitParameter(String name) 返回包含初始化参数值的字符串,如果该参数不存在,则返回 null

Enumeration getInitParameterNames() 将 servlet 的初始化参数的名称作为字符串对象的枚举返回,如果 servlet 没有初始化参数,则返回空枚举

ServletContext getServletContext() 返回对调用方正在其中执行的 ServletContext 的引用

ServletContext 接口

基本概念

javax.servlet.ServletContext 接口主要用于定义一组方法,Servlet 使用这些方法与它的 Servlet 容器通信。

服务器容器在启动时会为每个项目创建唯一的一个 ServletContext 对象,用于实现多个 Servlet 之间的信息共享和通信。

在 Servlet 中可以通过 getServletConfig().getServletContext() 获得 ServletContext 对象

在 Servlet 中还可以通过 this.getServletContext() 方法可以获得 ServletContext 对象。

配置方式
<!--在 web.xml 中配置 ServletContext 初始化参数 -->
<context-param>
    <param-name>username</param-name>
    <param-value>scott</param-value>
<context-param>
<context-param>
    <param-name>password</param-name>
    <param-value>tiger</param-value>
<context-param>
常用的方法

String getInitParameter(String name) 返回包含初始化参数值的字符串,如果该参数不存在,则返回 null

Enumeration getInitParameterNames() 将 servlet 的初始化参数的名称作为字符串对象的枚举返回,如果 servlet 没有初始化参数,则返回空枚举

String getRealPath(String path) 返回包含给定虚拟路径的实际路径的字符串。getRealPath("/") 获取到的是部署工程路径信息,对应的是当前工程中的 web 目录。

/ 在服务器被解析为:http://ip地址:端口号/工程名

String getContextPath() 返回与此上下文关联的主路径。本质上就是获取工程路径:/工程名

InputStream getResourceAsStream(String path) 将位于指定路径的资源作为 InputStream 对象返回

void setAttribute(String name, Object object) 将指定的属性名和属性值绑定到当前对象

Object getAttribute(String name) 根据执行的属性名获取属性值

void removeAttribute(String name) 删除指定的属性名信息

本文分享自微信公众号 - Renda(Renda_Zhang),作者:Renda Zhang

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-10

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SpringMVC:基本应用

    MVC 是软件工程中的一种软件架构模式,它是一种分离业务逻辑与显示界面的开发思想。

    RendaZhang
  • JavaWeb - JSP:概述和语法,内置对象,JavaBean 组件,MVC 设计模式

    JSP 是 Java Server Pages 的简称,跟 Servlet 一样可以动态生成 HTML 响应, JSP 文件命名为 xxx.jsp。

    RendaZhang
  • Spring:IOC 控制反转

    Spring 是分层的 Java SE/EE 应用 full-stack (全栈式) 轻量级开源框架。

    RendaZhang
  • Servlet 详解

    当服务器每次接收到请求时,都会调用 service 方法,该方法是会被多次调用的。

    wsuo
  • Java Lombok 常用注解

    生成toString方法 可使用参数排除部分字段 @ToString(exclude="someField")

    heasy3
  • Java入门 - 面向对象 - 05.封装

    原文地址:http://www.work100.net/training/java-encapsulation.html

    光束云
  • Effective Java-嵌套类(内部类)

    嵌套类(nested class)是指被定义在另一个类内部的类。嵌套类的存在目的应该只是为外围类(enclosing class)提供服务。嵌套类有四种:

    用户2146693
  • Java常用API(ArrayList类)

    为了更加方便的储存对象,因为使用普通的数组来存储对象太过麻烦了,因为数组的一个很大的弱点就是长度从一开始就固定了,所以Java提供了另一个容器 java.uti...

    一只胡说八道的猴子
  • 如果让我回到大学,我会这样学习Servlet

    前言 工作已经有一段时间了,如果让我重新学Servlet,我会怎么学呢?下面抛出两个常见的问题,我分开来解答

    Java3y
  • JAVA设计模式-观察者模式

    观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,他的所有依赖者都会收到通知并自动更新。

    DH镔

扫码关注云+社区

领取腾讯云代金券