文章目录
- Tomcat
-
- 服务器概述
- Tomcat服务器
-
- Tomcat简介
- Tomcat下载
- Tomcat的版本
- 安装
- 启动和关闭
- 修改Tomcat端口号和手动部署工程
- 将Tomcat整合到IDEA中
- 将动态工程部署到Tomcat中
- HTTP
-
- HTTP协议简介
- 发展历程
- HTTP协议的会话方式
- HTTP1.0和HTTP1.1的区别
- 不同浏览器监听http操作
- 报文
-
- Servlet
-
- Servlet简介
-
- 为什么要学习servlet
- Servlet概述(Server Applet)
- Servlet特性
- 如何使用Servlet
-
- Servlet生命周期
- ServletConfig与ServletContext对象
-
- ServletConfig
- ServletContext对象【Servlet上下文对象】
- 最终创建Servlet方式
- request【请求】与response【响应】对象
-
- 转发与重定向的区别
- web应用中的乱码问题
-
- 基本术语
- 乱码种类【B/S】
- 服务器与浏览器默认的编码与解码语言
- 乱码的解决
- web应用中的路径问题
-
- 基于JavaEE6及以上版本【web3.0】,创建Servlert
Tomcat
服务器概述
- Web服务器通常由硬件和软件共同构成。
- 硬件:电脑,提供服务供其它客户电脑访问
- 软件:电脑上安装的服务器软件,安装后能提供服务给网络中的其他计算机,将本地文件映射成一个虚拟的url地址供网络中的其他人访问。
- Web服务器主要用来接收客户端发送的请求和响应客户端请求。
- 常见的JavaWeb服务器:
- Tomcat (Apache) :当前应用最广的JavaWeb服务器
- JBoss (Redhat红帽)︰支持JavaEE,应用比较广EJB容器->SSH轻星级的框架代替
- GlassFish (Orcale) : Oracle开发JavaWeb服务器,应用不是很广
- Resin (Caucho) :支持JavaEE,应用越来越广
- Weblogic (Orcale):要钱的!支持JavaEE,适合大型项目
- Websphere (IBM)︰要钱的!支持JavaEE,适合大型项目
Tomcat服务器
Tomcat简介
- Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache、Sun和其他一些公司及个人共同开发而成。由于有了Sun的参与和支持,最新的Servlet和SP规范总是能在
Tomcat中得到体现,因为Tomcat技术先进、性能稳定,而且免费,因而深受Java爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的web 应用服务器。
Tomcat下载
- Tomcat官方网站: http://tomcat.apache.org
- 安装版:需要安装,一般不考虑使用。
- 解压版:直接解压缩使用,我们使用的版本。
- 因为tomcat服务器软件需要使用java环境,所以需要正确配置JAVA_HOME。
Tomcat的版本
- 版本:目前最新版本是10.0l企业用的比较广泛的是7.0和8.0的
- tomcat6以下都不用了,所以我们从tomcat6开始比较:
- tomcat6 支持servlet2.5、jsp2.1、el
- tomcat7 支持servlet3.0、jsp2.2、el2.2、websocket1.1
- tomcat8 支持servlet3.1、jsp2.3、el3.0、websocket1.1
- tomcat9 支持servlet4.0、jsp2.3、el3.0、websocket1.1
安装
- 解压apache-tomcat-8.5.82-windows-x64.zip到非中文无空格目录中
启动和关闭
- bin目录下的
修改Tomcat端口号和手动部署工程
- conf下的server.xml
- 可将静态项目直接放到webapps目录下
- conf目录下的web.xml里有默认访问页面的配置顺序
将Tomcat整合到IDEA中
将动态工程部署到Tomcat中
- 代码实时更新,无序重启服务器
HTTP
HTTP协议简介
- HTTP超文本传输协议(HTTP-Hypertext transfer protocol),是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过十几年的使用与发展,得到不断地完善和扩展。它是一种详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。
- 客户端与服务端通信时传输的内容我们称之为报文。HTTP协议就是规定报文的格式。
- HTTP就是一个通信规则,这个规则规定了客户端发送给服务器的报文格式,也规定了服务器发送给客户端的报文格式。实际我们要学习的就是这两种报文。客户端发送给服务器的称为′请求报文",服务器发送给客户端的称为"响应报文”。
发展历程
- 超文本传输协议的前身是世外桃源(Xanadu)项目,超文本的概念是泰德·纳尔森(Ted Nelson)在1960年代提出的。进入哈佛大学后,纳尔森一直致力于超文本协议和该项目的研究,但他从未公开发表过资料。1989年,蒂姆·伯纳斯·李(Tim Berners Lee)在CERN(欧洲原子核研究委员会=European Organization for NuclearResearch)担任软件咨询师的时候,开发了一套程序,奠定了万维网(WWW =World Wide Web)的基础。1990年12月,超文本在CERN首次上线。1991年夏天,继Telnet等协议之后,超文本转移协议成为互联网诸多协议的一分子。
- 当时,Telnet协议解决了一台计算机和另外一台计算机之间一对一的控制型通信的要求。邮件协议解决了一个发件人向少量人员发送信息的通信要求。文件传输协议解决一台计算机从另外一台计算机批量获取文件的通信要求,但是它不具备一边获取文件一边显示文件或对文件进行某种处理的功能。新闻传输协议解决了一对多新闻广播的通信要求。而超文本要解决的通信要求是:在一台计算机上获取并显示存放在多台计算机里的文本、数据、图片和其他类型的文件;它包含两大部分:超文本转移协议和超文本标记语言(HTML)。HTTP、HTML以及浏览器的诞生给互联网的普及带来了飞跃。
HTTP协议的会话方式
- 浏览器与服务器之间的通信过程要经历四个步骤
- 浏览器与WEB服务器的连接过程是短暂的,每次连接只处理一个请求和响应。对每一个页面的访问,浏览器与WEB服务器都要建立—次单独的连接。
- 浏览器到WEB服务器之间的所有通讯都是完全独立分开的请求和响应对。
HTTP1.0和HTTP1.1的区别
- 在HTTP1.0版本中,浏览器请求一个带有图片的网页,会由于下载图片而与服务器之间开启一个新的连接;但在HTTP1.1版本中,允许浏览器在拿到当前请求对应的全部资源后再断开连接,提高了效率。
不同浏览器监听http操作
- Chrome中F12可查看
- FireFox中F12可查看
报文
报文格式
- 报文:
- 请球报文:浏览器发给服务器
- 响应报文:服务器发回给浏览器
请求报文
报文格式(4部分)
- 请求首行(请求行)
- 请求头信息(请求头)
- 空行
- 请求体
GET请求
- 由于请求参数在请求首行中已经携带了,所以没有请求体,也没有请求空行
- 请求参数拼接在url地址中,地址栏可见[url?name1=value1&name2=value2],不安全
- 由于参数在地址栏中携带,所以由大小限制[地址栏数据大小一般限制为4k],只能携带纯文本
- get请求参数只能上传文本数据
- 没有请求体。所以封装和解析都快,效率高,浏览器默认提交的请求都是get请求[比如:①地址栏输入url地址回车,②点击超链接a, ③form表单默认方式…]
- 请求首行
GET /web_tomcat/login_success.html?username=admin&password=123213 HTTP/1.1 请求方式 访问的服务器中的资源路径? get请求参数 协议版本
- 请求头
需要掌握以下三个: User-Agent:用户信息; Referer: 返回上一个URL; Cookie:
POST请求
- 请求行
POST /05_web_tomcat/login_success.html HTTP/1.1
- 请求头
需要掌握以下三个: User-Agent:用户信息; Referer: 返回上一个URL; Cookie:
- 请求空行
- 请求体:浏览器提交给服务器的内容
username=admin&password=123213
响应报文
报文格式(4部分)
- 响应首行(响应行)
- 响应头信息(响应头)
- 空行
- 响应体
具体情况
响应码
响应码对浏览器来说很重要,它告诉浏览器响应的结果。比较有代表性的响应码如下:
- 200:请求成功,浏览器会把响应体内容(通常是html)显示在浏览器中;
- 404:请求的资源没有找到,说明客户端错误的请求了不存在的资源;
- 500:请求资源找到了,但服务器内部出现了错误(代码写错了影响服务器);
- 302:重定向,当响应码为302时,表示服务器要求浏览器重新再发一个请求,服务器会发送一个响应头Location,它指定了新请求的URL地址;
Servlet
Servlet简介
为什么要学习servlet
例:以注册为例,如需实现注册的功能
- regist.html中的数据,提交到java中
- 【xxx.java文件默认不能直接以url方式访问,所以需要使用servlet解决当前问题】
- 在java使用jdbc技术,将数据在提交到database中
Servlet概述(Server Applet)
- Servlet:相当于具有【url特性】的java代码
- Servlet指的是javax.servlet.Servlet接口及其子接口,也可以指实现了Servlet接口的实现类。
Servlet特性
- Servlet的实例对象由Servlet容器负责创建;
- Servlet的方法由容器在特定情况下调用;
- Servlet容器会在Web应用卸载时销毁Servlet对象的实例。
如何使用Servlet
操作步骤
- 使用Servlet接口的方式:
-
搭建Web开发环境
-
创建动态Web工程
-
创建javax.servlet.Servlet接口的实现类:com.example.servlet.MyFirstServlet
-
在service(ServletRequest, ServletResponse)方法中编写如下代码,输出响应信息:
@Override
public void service(ServletRequest req,ServletResponse res) throws servletException,IOException {
System.out.println("Servlet worked. . . ");
Printwriter writer =res.getwriter();
writer.write("Servlet response ");
writer.close();
}
- 在web.xml配置文件中注册MyFirstServlet(web.xml: web应用部署描述符,主要用于各种web组件的注册。)
<servlet>
<servlet-name>MyFirstServletserv1et-name>
<servlet-class>com.example.servlet.MyFirstServletservlet-class>servlet>
<servlet-mapping>
<servlet-name>MyFirstservletservlet-name>
<ur1-pattern>/MyFirstservletur1-pattern>
servlet-mapping>
Servlet工作原理
- 请求MyFirstServlet
- 在web.xml中【中的】查找指定url
- 通过映射到【全类名】
- 执行MyFirstServlet中的相应方法
Servlet生命周期
- 构造器
- 执行时机:第一次接收请求时,执行
- 执行次数:在整个生命周期中,只执行一次【servlet单利】
- init()
- 执行时机:第一次接收请求时,执行构造器之后,执行
- 执行次数:在整个生命周期中,只执行一次
- service()
- 执行时机:每次接收请求,都会执行
- 执行次数:在整个生命周期中,执行多次
- destroy)
- 执行时机:在关闭服务器或重启服务器时,执行
- 执行次数:在整个生命周期中,只执行一次
总结:当Servlet第一次接收请求时,Servlet容器【web容器|web服务器】创建Servlet【执行构造器】,之后执行init()方法,进行初始化操作。最后执行service()方法,处理请求,做出响应。【以后再次接收请求,只执行service()方法】。当关闭或重启服务器时,执行destroy()方法,销毁Servlet
- Servlet生命周期扩展
- 此时,servlet生命周期,如下调整
- 构造器执行时机为:启动服务器时,执行
- init()方法的执行时机为:启动服务器,执行构造器后,执行
- 其他方法,无变化
ServletConfig与ServletContext对象
ServletConfig
- 概述:该对象相当于封装了servlet配置信息,每个servlet都有唯一对应的ServletConfig对象
- 作用:
- 获取当前servlet名称:servletConfig.getServletName()
- 获取ServletContext对象:servletConfig.getServletContext()
- 获取当前servlet初始化参数:servletConfig.getInitParameter()
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>MyFirstServletservlet-name>
<servlet-class>com.example.servlet.MyFirstServletservlet-class>
<init-param>
<param-name>urlparam-name>
<param-value>jdbc:mysql:///testparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>MyFirstServletservlet-name>
<url-pattern>/MyFirstServleturl-pattern>
servlet-mapping>
web-app>
package com.example.servlet;
import javax.servlet.*;
import java.io.IOException;
public class MyFirstServlet implements Servlet {
private ServletConfig servletConfig;
public MyFirstServlet() {
System.out.println("MyFirstServlet被创建了");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("MyFirstServlet->init()!!!");
this.servletConfig = servletConfig;
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("MyFirstServlet->service()!!!");
String servletName = this.servletConfig.getServletName();
System.out.println("servletName = " + servletName);
ServletContext servletContext = this.servletConfig.getServletContext();
System.out.println("servletContext = " + servletContext);
String url = this.servletConfig.getInitParameter("url");
System.out.println("url = " + url);
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("MyFirstServlet->destroy()!!!");
}
}
ServletContext对象【Servlet上下文对象】
- 概述:该对象相当于web应用,每个web应用程序都有唯一对象的ServletContext对象。该对象在启动服务器时,被web服务器创建
- 作用:
- 获取上下文路径【带/项目名,例:/tomcat_http_servlet】
String contextPath = servletContext.getContextPath();
- 获取虚拟url的映射的真实路径【d:/xxx(文件的上传&下载)】
String realPath = servletContext.getRealPath("index.html");
- 获取上下文的初始化参数
<context-param>
<param-name>stuNameparam-name>
<param-value>zhangSanparam-value>
context-param>
String stuName = servletContext.getInitParameter("stuName");
- 域对象【web域,共四个域对象】
最终创建Servlet方式
- 之前创建Servlet方式不足:
- 实现Servlet接口的实现类中,方法比较冗余。【只需要Service()】
- 没有提示注册Servlet
- EndServlet : HttpServlet: GenericServlet: Servlet
- GenericServlet作用:
- 提供获取ServletConfig和ServletContext对象方法
- getServletConfig()
- getServletContext()
- 将service()方法,抽象化
public abstract void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;
- HttpServlet作用:
- override service()【重写service()】
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
HttpServletRequest request;
HttpServletResponse response;
if (!(req instanceof HttpServletRequest &&
res instanceof HttpServletResponse)) {
throw new ServletException("non-HTTP request or response");
}
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
service(request, response);
}
- override service()【重载service()】
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
doGet(req, resp);
}
else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} ……
}
request【请求】与response【响应】对象
request
- 类型:HttpServletRequest
- 概述:request相当于浏览器向服务器发送请求报文,封装到request对象。该对象由服务器创建,并以参数的形式发送到service()中,最终传到doGet()或doPost()方法中
- 作用:
- 获取请求参数
- 什么是参数
- ?后面内容:
- 表单中参数:name属性值
- request.getParameter():获取单个请求参数
- request.getParameterValues():获取多个请求参数
- 获取请求头中的信息
- request.getHeader(“User-Agent|Cookie|Referer”)
- 获取URL信息
- 获取协议:request.getScheme()
- 获取服务器名称:request.getServerName()
- 获取服务器端口:request.getServerPort()
- 获取上下文路径【带/项目名】:request.getContextPath()
- 转发请求【路径跳转】
RequestDispatcher requestDispatcher =
request.getRequestDispatcher ("login_success.html");
requestDispatcher.forward(request,response);
- 域对象【共四个】
response
- 类型:HttpServletResponse
- 概述:response相当于服务器向浏览器做出的响应报文,封装到response对象。该对象由服务器创建,并以参数的形式发送到service()中,最终传到doGet()或doPost()方法中
- 作用:
- 获取响应流,响应数据
- PrintWriter writer = response.getWriter();
- writer.writer();|writer.print();
- 设置响应头
- response.setHeader(“Content-Type”,“text/html;charset=UTF-8”);
- 重定向【路径跳转】
- response.sendRedirect(“url”);
转发与重定向的区别
- 转发地址栏不变,重定向地址改变。
- 转发可以携带request对象到目标资源,重定向未携带request对象
- 转发浏览器发送一次,重定向浏览器发送两次请求
- 转发可以访问WEB-INF下的资源,重定向不能直接访问WEB-INF下的资源
- WEB-INF属于服务器私有目录【服务器内部可以访问,浏览器不能直接访问】
|
转发 |
重定向 |
浏览器感知 |
在服务器内部完成,浏览器感知不到 |
服务器以302状态码通知浏览器访问新地址,浏览器有感知 |
浏览器地址栏 |
不改变 |
改变 |
整个过程发送请求次数 |
一次 |
两次 |
执行效率 |
效率高 |
效率低 |
API(或发起者) |
Request对象 |
Response对象 |
能否共享request对象数据 |
能 |
否 |
WEB-INF下的资源 |
能访问 |
不能访问 |
目标资源 |
必须是当前web应用中的资源 |
不局限于当前WEB应用 |
- 说明:
- 默认情况下,浏览器是不能访问服务器WEB-INF下的资源,而服务器时可以访问的
- 浏览器默认的绝对路径:http://localhost:8080/
web应用中的乱码问题
基本术语
- 字符集:就是各种字符的集合,包括汉字,英文,标点符号等
- 常用字符集:UTF-8【支持大量中文】、GB2312【GBK:支持少量中文】
- 编码:将字符转换为二进制数
- 解码:将二进制数转换为字符
- 乱码:一段字符的编码与解码的过程使用了不同的字符集时,会出现乱码现象
乱码种类【B/S】
- 请求乱码:浏览器向服务器发送请求时出现的乱码
- 响应乱码:服务器向浏览器做出的响应时出现的乱码
服务器与浏览器默认的编码与解码语言
- 服务器默认的编码与解码一致:ISO-8859-1【不支持中文】
- 浏览器默认情况
- 编码:UTF-8【
】
- 解码:GBK【GB2312】
乱码的解决
- 解决请求乱码
-
GET请求:
- 思路:找到设置URL字符集的位置
- 代码:
-
POST请求:
- 思路:将服务器解码设置为UTF-8。【浏览器编码:UTF-8与服务器解码:ISO-8859-1】
- 代码:
request.setCharacterEncoding ("UTF-8");
- 解决响应乱码
- 思路:【服务器编码:ISO-8859-1,浏览器解码:GBK】
- 设置服务器编码:GBK【支持少量中文】:
response.setCharacterEncoding("GBK");
- 设置服务器编码与浏览器解码:UTF-8【推荐使用】
response.setHeader ("content-Type","text/htm1;charset=UTF-8");
response.setContentType( "text/html;charset=UTF-8");
web应用中的路径问题
- 由于使用转发跳转路径,地址栏不变。此时使用相对路径【…/】可能会出现404,所以不建议使用相对路径,建议使用绝对路径
什么是绝对路径
“/”代表什么
- 如果是服务器解析“/”,“/”代表当前上下文路径【当前web应用路径】例:http://localhost:8080/_servlet
- 以下两种路径中的“由服务器解析
- web.xml中配置的"/"
/Registservlet
- 转发请求中的“/”
- 如果是浏览器解析“/”,“/”代表当前服务器路径。例:http://localhhost:8080/
- 以下两种路径中的“/”由浏览器解析
- 重定向中的“/”
- 书写在静态资源中的“/”【最终在浏览器中加载运行的内容】
代码
- 页面中的代码【html|jsp】
- servlet中代码
- 转发:
request.getRequestDispatcher("/pages/login_success.html").forward(request,response);
- 重定向:
response.sendRedirect(request.getContextPath()+"/pages/login.html");
基于JavaEE6及以上版本【web3.0】,创建Servlert
@webServlet(name = "Servlet30" , value = "/Servlet30")
public class Servlet30 extends HttpServlet {
protected void doPost(HttpServletRequest request,HttpServletResponse response)throws servletException,IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request,HttpServletResponse response) throwsservletException,IOException {
System.out.println("servlet 30! ");
}
}