[JavaWeb]Web 服务器 Tomcat 和 Servlet 服务程序
Posted Spring-_-Bear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JavaWeb]Web 服务器 Tomcat 和 Servlet 服务程序相关的知识,希望对你有一定的参考价值。
一、Tomcat
1. JavaWeb 概念及 Web 资源分类
- JavaWeb 概念:所有通过 Java 语言编写的可以通过浏览器访问的程序的总称,JavaWeb 是基于请求和响应来进行开发的
- web 资源按照实现的技术和呈现的效果的不同,又分为静态资源(html、css、js、mp4、png······)和动态资源(jsp 页面、Servlet 程序······)
2. 常见的 Web 服务器
- Tomcat:由 Apache 组织提供的一种 Web 服务器,提供对 jsp 和 Servlet 的支持,是一种轻量级的 javaweb 服务器,是当前应用最广泛的的免费服务器
- Jboss:遵从 JavaEE 规范、开源、纯 Java 的 EJB 服务器,支持所有的 JavaEE 规范,免费使用
- GlassFish:由 Oracle 公司开发的一款 JavaWeb 服务器,是一款强健的商业服务器,达到产品级质量(应用很少)
- Resin:由 CAUCHO 开发,是一个非常流行的服务器,对 servlet 和 jsp 提供了良好的支持,性能较为优良,resin 自身采用 Java 语言开发,收费但应用较多
- WebLogic:是 Oracle 公司的产品,是目前收费产品中应用最广泛的 Web 服务器,支持 JavaEE 规范,不断地完善以适应新的开发需求,适合大型项目(收费,应用不广、适合大公司)
3. Tomcat 和 Servlet 版本对应关系
Tomcat | Servlet/JSP | JavaEE | JDK |
---|---|---|---|
4.1 | 2.3/1.2 | 1.3 | jdk1.3 |
5.0 | 2.4/2.0 | 1.4 | jdk1.4 |
5.5/6.0 | 2.5/2.1 | 5.0 | jdk5.0 |
7.0 | 3.0/2.2 | 6.0 | jdk6.0 |
8.0 | 3.1/2.3 | 7.0 | jdk7.0 |
- Servlet 程序 2.5 版本是现在市面上使用最多的版本(xml 配置)
- 从 Servlet 3.0 之后,使用的是注解版本的 Servlet
- Tomcat work 目录:是 Tomcat 的工作目录,用来存放 Tomcat 运行时 jsp 翻译为 Servlet 的源码和 Session 钝化的目录
- 修改 tomcat 的监听端口:修改 conf 目录下 server.xml 配置文件下的 Connector 标签,Http 协议默认的端口号是 80
4. 部署 web 工程的两种方式
- 将工程文件拷贝到 Tomcat 安装目录下的 webapps 目录下
- 在 Tomcat 安装目录的 conf/Catalina/localhost 目录下新建项目 xml 配置文件
<!--
Context 表示一个工程上下文
path 表示 /conf/Catalina/localhost/ 下的配置文件名
docBase 表示工程目录
-->
<Context path="/book" docBase="D:\\Bear\\Project\\JavaWeb\\05Book" />
5. 动态 web 工程目录的介绍
- webapp 目录用来存放 web 工程的资源文件,如 html、css、js ······
- WEB-INF 目录是一个受服务器保护的目录,浏览器无法直接访问此目录中的内容
- web.xml 是整个动态 web 工程的配置部署描述配置文件,可以在此配置很多的 web 工程的组件,比如 Servlet 程序、Filter 过滤器、Listener 监听器、Session 超时······
- 热部署:所谓热部署,就是在应用正在运行的时候升级软件,却不需要重新启动应用
二、Servlet
1. Servlet 的定义
- Servlet 是 JavaEE 规范之一,规范就是接口
- Servlet 是 JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器
- Servlet 是运行在服务器上的一个 java 小程序,它可以接受客户端发送过来的请求,并响应数据给客户端
2. 第一个 Servlet 程序
- 编写一个类去实现 Servlet 接口
- 实现 service 方法,处理请求,并响应数据
- 到 web.xml 配置文件中配置 servlet 程序的访问地址
<servlet>
<!-- 给 Servlet 程序起一个别名,一般是类名 -->
<servlet-name>HelloWorld</servlet-name>
<!-- Servlet 程序的全类名 -->
<servlet-class>com.bear.javaweb.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<!-- 告知服务器,当前配置的地址给哪个 Servlet 程序使用 -->
<servlet-name>HelloWorld</servlet-name>
<!--
/ 服务器解析的时候,表示地址为:http://ip:port/工程路径 http://localhost:8080/javaweb_war_exploded/
/hello 表示地址为 http://ip:port/工程路径/hello http://localhost:8080/javaweb_war_exploded/hello
-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
3. url 如何定位 Servlet 程序
4. Servlet 生命周期方法
- 执行 Servlet 构造方法
- 执行 init 初始化方法
- 执行 service 方法
- 执行 destory 方法,在 web 工程停止的时候调用
5. 请求的分发处理
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException
System.out.println("Hello Servlet 程序被访问了");
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String requestMethod = httpServletRequest.getMethod();
if ("GET".equals(requestMethod))
System.out.println("处理 GET 请求");
else if ("POST".equals(requestMethod))
System.out.println("处理 POSt 请求");
6. 继承 HttpServlet 类实现 Servlet 程序
- 一般在实际项目开发中,都是使用继承 HttpServlet 类的方式来实现 Servlet 程序
- 根据业务需要重写 doGet 或 doPost 方法
/**
* @author Spring-_-Bear
* @datetime 2022/2/12 21:42
*/
public class HelloServlet2 extends HttpServlet
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
System.out.println("doGet 方法被调用了");
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
System.out.println("doPost 方法被调用了");
7. ServletConfig 类的三大常用作用
-
可以获取 web.xml 中 Servlet 程序的别名
servlet-name
的值 -
获取初始化参数 web.xml 中
init-param
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.bear.servlet.HelloServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>Spring-_-Bear</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
- 获取 ServletContext 对象
@Override
public void init(ServletConfig servletConfig) throws ServletException
System.out.println("Servlet:" + servletConfig.getServletName());
System.out.println("username:" + servletConfig.getInitParameter("username"));
System.out.println("url:" + servletConfig.getInitParameter("url"));
System.out.println("Servlet Context:" + servletConfig.getServletContext());
- Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建,程序员负责使用。Servlet 程序默认是第一次访问时创建,ServletConfig 是每个 Servlet 程序创建时就创建一个对应的 ServletConfig 对象
8. ServletContext 对象
- ServletContext 是一个接口,它表示 Servlet 上下文对象
- 一个 web 工程,有且仅有一个 ServletContext 对象实例
- ServletContext 对象是一个域对象,所谓域对象是指可以像 Map 一样存取数据的对象
存数据 | 取数据 | 删除数据 | |
---|---|---|---|
Map | put() | get() | remove() |
域对象 | setAttribute() | getAttribute() | removeAttribute() |
9. ServletContext 类的四大常用作用
- 获取 web.xml 中配置的上下文参数
context-param
- 获取当前的工程路径
- 获取工程部署后在服务器磁盘上的绝对路径
- 像 map 一样存取数据
- 一个 web 工程,有且仅有一个 ServletContext 对象实例,在 web 工程启动时创建,停止时销毁
<context-param>
参数由 ServletContext 对象获取,<init-param>
参数由 ServletConfig 对象获取
ServletContext servletContext = getServletContext();
// 获取上下文参数
System.out.println("username:" + servletContext.getInitParameter("username"));
// 获取当前工程路径
System.out.println("CurrentProjectPath:" + servletContext.getContextPath());
// 获取工程由服务器部署后在磁盘上的绝对路径
// "/" 被放服务器解析为 http://ip:port/工程名/,映射到 IDEA 项目的 web 目录
System.out.println("RealPath:" + servletContext.getRealPath("/"));
// 存取数据
servletContext.setAttribute("password","123456");
System.out.println("password:" + servletContext.getAttribute("password"));
10. GET 请求
Http 协议中数据又叫报文
第一行为请求行(请求方式、请求资源路径、协议以及版本号),其余为请求头
Accept:告知服务器,客户端可以接收的数据类型
Accept-Language:可以接收的语言类型
User-Agent:浏览器信息
Accept-Encoding:客户端可以接收的数据编码(压缩)格式
Host:表示请求的服务器 ip 和 port
Connection:告知服务器请求连接如何处理
Keep-Alive:告知服务器回传数据后保持一小段时间的连接
Closed:回传完数据立即关闭连接
11. POST 请求
第一行为请求头,接着是 key - value 形式的请求头 + 空行,最后是请求体(发送给服务器的数据)
Referer:表示请求发起时,浏览器地址栏中的地址(从哪来)
Content-Type:表示发送的数据的类型
application/x-www-form-urlencoded:表示提交的数据格式是:name=value&name=value,然后对其进行 url 编码,url 编码是把非英文内容转换为 %xx%xx
multipart/form-data:表示以多段的形式提交数据给服务器(以流的方式提交,用于上传)
Content-Length:表示发送的数据的长度
Cache-Control:表示如何控制缓存 no-cache(不缓存)
12. 常见 GET 请求和 POST 请求
以下为 GET 请求
- form 标签 method=get
- a 标签
- link 标签引入 css
- script 标签引入 js 文件
- img 标签引入图片
- iframe 引入 html 页面
- 在浏览器输入地址后敲回车
以下为 POST 请求
- from 标签 method=post
13. 响应头
- 首先是响应行(响应的协议和版本号、响应状态码、响应状态码描述符),接着是响应头(key:value + 空行),最后是响应体(回传给客户端的数据)
- 200:请求成功
- 302:请求重定向
- 404:请求地址错误
- 500:服务器内部错误
- Server:服务器信息
- Date:请求响应的时间(格林时间)
14. MIME 数据类型
MIME(Multipurpose Internet Mail Extentions)多功能 Internet 邮件扩充服务是 HTTP 协议中的数据类型,MIME 类型的格式是 “大类型/小类型”,并与某一种文件的扩展名相对应
15. HttpServletRequest 类
每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。然后传递到 service 方法(doGet 和 doPost)中以供使用。可以通过 HttpServletRequest 对象获取到所有的请求信息
解决 post 请求中文乱码问题:在 doPost 方法中设置请求体的字符集为 UTF-8
req.setCharacterEncoding("UTF-8");
,在获取参数之前调用才有效
方法名 | 功能 |
---|---|
getRequestURI() | 获取请求的资源路径 |
getRequestURL() | 获取请求的统一资源定位符(绝对路径) |
getRemoteHost() | 获取客户端的 ip 地址 |
getHeader() | 获取请求头 |
getParameter() | 获取请求的参数 |
getParameterValues() | 获取请求的参数(多个值时使用,如获取 checkbox 的值) |
getMethod() | 获取请求的方式(GET 或 POST) |
setAtttribute(key,value) | 设置域数据 |
getRequestDispatcher() | 获取请求转发对象 |
16. 请求转发
- 请求的转发是指,服务器收到请求后,从一个资源跳转到另一个资源的操作
- 请求转发虽然访问了两个资源,但只属于一次请求,共享 Request 域数据
- 可以转发到 WEB-INF 目录下的资源
- 不可以访问工程外的资源
/**
* @author Spring-_-Bear
* @datetime 2022/2/15 7:55
*/
public class Servlet1 extends HttpServlet
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
// 获取客户端请求的参数
String username = req.getParameter("username");
System.out.println("username:" + username);
// 加盖 Servlet1 的证明
req.setAttribute("Servlet1", "Yes");
// 查询 Servlet2 的地址
/*
* 请求转发必须以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名,对应 IDEA 项目的 web 目录
*/
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
// 请求转发到 Servlet2
requestDispatcher.forward(req, resp);
/**
* @author Spring-_-Bear
* @datetime 2022/2/15 7:55
*/
public class Servlet2 extends HttpServlet
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
// 获取客户端请求的参数
String username = req.getParameter("username");
System.out.println("username:" + username);
// 查看 Servlet1 的证明
Object servlet1 = req.getAttribute("Servlet1");
System.out.println("Servlet1-" + servlet1);
// Servlet2 处理自己的业务
System.out.println("Deal with matter");
17. base 标签及 / 斜杠说明
- 所有相对路径在工作时都会参照当前浏览器地址栏中的地址来进行跳转
- base 标签可以设置当前页面中所有相对路径工作时,参照哪个路径来进行跳转
- base 标签放在
<head></head>
中- / 也是一种绝对路径,如果被浏览器解析,得到的地址是
http://ip:port/
- / 如果被服务器解析,得到的地址是
http://ip:port/工程路径
,如<url-pattern>/servlet1</url-pattern>
、servletContext.getRealPath("/");
、request.getRequestDispatcher("/");
- 特殊情况:
response.sendRediect("/")
请求重定向,把斜杠发送给浏览器解析,得到http://ip:port/
18. HttpServletResponse 类
- HttpServletResponse 类和 HttpServletRequest 类一样。每次接到请求,Tomcat 服务器都会创建一个 Response 对象并传递给 Servlet 程序使用
- 字节流:resp.getOutputStream(),常用于下载(传递二进制数据)
- 字符流:resp.getWriter(),常用于回传字符串,两个响应流同时只能使用一个
19. 解决响应中文乱码
解决方案一:
- 获取响应字符集
resp.getCharacterEncoding() // 默认 ISO-8859-1;
- 设置服务器响应字符集
resp.setCharacterEncoding("UTF-8");
- 通过请求头,设置浏览器也是用 UTF-8 字符集
resp.setHeader("Content-Type","text/html; charset=UTF-8" )
解决方案二:
- 同时设置服务器和客户端都使用 UTF-8 编码,并且设置请求头
resp.setContentType("text/html; charset=UTF-8");
,此方法一定要在获取流对象之前才有效
20. 请求重定向
- 请求重定向是指客户端给服务器发请求,然后服务器告诉客户端说,我给你一些新地址,你去新地址访问
- 浏览器地址栏会发生变化
- 请求重定向是两次独立的请求
- 不共享 Request 域中的数据,因为两次请求创建了两个 Request 对象
- 不能访问 WEB-INF 目录下的资源
- 可以访问工程外的资源
// 请求重定向实现方式一
// 设置响应状态码为 302,表示重定向处理请求
resp.setStatus(302);
// 设置响应头,说明新的访问地址
resp.setHeader("Location","http://localhost:8080");
// 请求重定向实现方式二
resp.sendRedirect("http://localhost:8080");
21. JavaEE 三层架构
web 阶段使用 base + 相对路径,框架阶段使用绝对路径
以上是关于[JavaWeb]Web 服务器 Tomcat 和 Servlet 服务程序的主要内容,如果未能解决你的问题,请参考以下文章