JavaWeb
简介
- 什么是 JavaWeb
JavaWeb 是指通过所有的 Java 语言编写的可以通过浏览器访问的程序的总称,叫 JavaWeb
JavaWeb 是基于请求和响应来开发的 - 什么是请求
请求是指客户端给服务端发送数据,叫请求 request - 什么是响应
响应是指服务器给客户端回传数据,叫响应 response - 请求和响应之间的关系
请求和响应式成对出现的,有请求就有响应
程序的分类:C/S B/S
B/S : 浏览器
C/S:app应用
Web 资源的分类
根据实现的技术和呈现的效果不同,分为:
- 静态资源:html、 css、 js、 txt、 mp4 视频 , jpg 图片
- 动态资源:jsp 页面、 Servlet 程序
常用的 Web 服务器
- Tomcat: 由 Apache 组织提供的一种 Web 服 器, 提供对 jsp 和 Servlet 的支持。 它是一种轻量级的 javaWeb 容器(服务器) , 也是当前应用最广的 JavaWeb 服务器(免费) 。
- Jboss: 是一个遵从 JavaEE 规范的、 开放源代码的、 纯 Java 的 EJB 服务器, 它支持所有的 JavaEE 规范(免费) 。
- GlassFish: 由 Oracle 公司开发的一款 JavaWeb 服务器, 是一款强健的商业服务器, 达到产品级质量(应用很少) 。
- Resin: 是 CAUCHO 公司的产品, 是一个非常流行的服务器, 对 servlet 和 JSP 提供了良好的支持,性能也比较优良, resin 自身采用 JAVA 语言开发(收费, 应用比较多) 。
- WebLogic: 是 Oracle 公司的产品, 是目前应用最广泛的 Web 服务器, 支持 JavaEE 规范,而且不断的完善以适应新的开发要求, 适合大型项目(收费, 用的不多, 适合大公司) 。
Tomcat
Tomcat 服务器和 Servlet 版本的对应关系
Servlet Spec | JSP Spec | EL Spec | Apache Tomcat version | Supported Java Versions |
---|---|---|---|---|
4.0 | TBD (2.4?) | TBD (3.1?) | 9.0.x | 8 and later |
3.1 | 2.3 | 3.0 | 8.5.x | 7 and later |
3.1 | 2.3 | 3.0 | 8.0.x (superseded) | 7 and later |
3.0 | 2.2 | 2.2 | 7.0.x | 6 and later (7 and later for WebSocket) |
2.5 | 2.1 | 2.1 | 6.0.x | 5 and later |
2.4 | 2.0 | N/A | 5.5.x (archived) | 1.4 and later |
2.3 | 1.2 | N/A | 4.1.x (archived) | 1.3 and later |
2.2 | 1.1 | N/A | 3.3.x (archived) | 1.1 and later |
Servlet 程序从 3.0 版本是现在世面使用最多的版本(xml 配置)
到了 Servlet3.0 之后。 就是注解版本的 Servlet 使用。
以 3.0 版本为主线讲解 Servlet 程序。
Tomcat 的使用
安装
https://tomcat.apache.org/download-90.cgi
找到你需要用的 Tomcat 版本对应的 zip 压缩包, 解压到需要安装的目录即可。
目录介绍:
名称 | 说明 |
---|---|
bin | 专门用来存放 Tomcat 服务器的可执行程序 |
conf | 专门用来存放 Tocmat 服务器的配置文件 |
lib | 专门用来存放 Tomcat 服务器的 jar 包 |
logs | 专门用来存放 Tomcat 服务器运行时输出的日记信息 |
temp | 专门用来存放 Tomcdat 运行时产生的临时数据 |
webapps | 专门用来存放部署的 Web 工程。 |
work | 是 Tomcat 工作时的目录, 用来存放 Tomcat 运行时 jsp 翻译为 Servlet 的源码, 和 Session 钝化的目录。 |
tomcat 的运行与停止
点击文件 startup.bat
在浏览器中输入:http://localhost:8080,即可打开 tomcat 页面
常见问题:
-
出现了cmd窗口,但是cmd窗口一闪而过,没有启动运行窗口
Tomcat是基于 java 语言开发的,因此tomcat的运行需要依赖 jdk、jvm,所以 tocmat 要正常启动,首先必须保证你的 jdk 的环境变量配置必须正确
解决方案:检查你的环境变量的配置
-
启动时报错
确定问题:查看tomcat的启动日志
这个原因是因为我们电脑的8080端口被其他程序占用。
解决端口占用问题:修改配置文件 修改端口
-
tomcat 启动时,cmd 窗口中文乱码
修改conf/logging.properties
- tomcat 的停止
- 将启动的 cmd 窗口直接关闭
- 通过 tomcat 命令来关闭:在 bin 目录下,运行 shutdown.bat 即可停止
tomcat 的相关配置
应用管理与主机管理的设置:conf/tomcat-user.xml
输入密码即可登录:
应用管理页面:
主机管理页面:
在 tomcat 中部署 web 应用
欢迎页面的访问
apache-tomcat-9.0.43\webapps\ROOT这个目录就是欢迎页面项目所在的目录
ROOT 目录 是tomcat 的一个默认访问目录。
localhost:8080 改地址默认访问的就是ROOT目录下的 index.html/index.jsp 等这样的页面
手动部署应用到 tomcat
方式一:将应用部署到webapps目录下
将《零点读书》网上书城的项目部署到tomcat中
部署的步骤:
- 在webapps目录下创建一个目录 books(项目名称)
- 将webcontent目录下的所有文件及目录拷贝到books目录下
- 重启tomcat
- 访问项目:http://localhost:8080/books/ 默认会访问项目下的index.html
方式二:采用目录映射的方式
- 如果不想将项目部署到webapps下 则可以将项目放置到服务器的任意目录下
- 在tomcat的conf\Catalina\localhost目录下 新建一个文件 app.xml
<!--
Context 表示一个工程上下文
path 表示工程的访问路径:/abc
docBase 表示你的工程目录在哪里
-->
<Context path="/app" docBase="E:\books” />
- 重启tomcat
- 访问我们的应用
http://localhost:8080/app/
直接访问 和使用web服务器访问的区别
- 直接访问:
- Web访问
http://localhost:8080/app/
区别:
- 协议不同:直接访问 使用file协议 web访问:http
- 访问方式: 直接访问就是打开一个文件,web访问基于请求响应模式
使用 idea 创建一个 web 工程
创建工程
File -> New -> Project
对 Java 项目提供 web 支持
最终目录结构:
在 idea 中将项目部署到 tomcat
- 给 idea 配置 tomcat
将项目工程部署到 tomcat 中
动态 web 技术
什么是Servlet
- Servlet 是JavaEE 规范之一。规范就是接口
- Servlet 是JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。
- Servlet 是运行在服务器上的一个java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。
开发一个 servlet 程序
-
需要在工程中引入 tomcat 容器对 serlvet 规范的实现 引入相关依赖(jar 包的添加)
此 jar 包在 tomcat 安装路径下的 lib 文件中:
-
创建一个类
import javax.servlet.*;
import java.io.IOException;
public class HelloServlet extends Servlet {
// 进行servlet初始化,init方法只执行一次,只在servlet第一次请求的时候执行,先于servlet方法执行
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("servlet 初始化方法执行");
}
// 获取配置
@Override
public ServletConfig getServletConfig() {
return null;
}
// 提供服务,是真正提供服务的方法
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("提供服务");
}
@Override
public String getServletInfo() {
return null;
}
// 销毁的时候需要执行的方法,也只执行一次,在servlet从servlet(tomcat)卸载的时候执行
@Override
public void destroy() {
System.out.println("servlet销毁");
}
}
- 配置 servlet
<?xml version="1.0" encoding="UTF-8"?>
<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>
<servlet-name>hello</servlet-name>
<servlet-class>cn.lanqiao.HelloServlet</servlet-class>
<!-- 配置初始化时机,配置为0,则servlet随着容器的启动而完成构造和初始化-->
<!-- <load-on-startup></load-on-startup>-->
</servlet>
<!-- 配置servlet映射路径 -->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
- 部署并启动
http://localhost:8080/web01/hello
请求的分析
url-pattern的配置
第一种 :以/开头
<url-pattern>/hello</url-pattern>
http://localhost:8080/web01/hello/abc/def
<url-pattern>/hello/abc/def</url-pattern>
http://localhost:8080/web01/hello/abc/def
<url-pattern>/</url-pattern>
http://localhost:8080/web01/
第二种:使用通配符配置
<url-pattern>*.do</url-pattern>
使用通配符的时候 前边不能有/
<url-pattern>*.action</url-pattern>
*代表任意字符
servlet 的生命周期
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
init 方法在整个过程中,只执行一次 而且默认是在serlvet第一次请求的时候执行。先于service方法执行。
@Override
public void destroy() {
System.out.println("servlet 销毁。。。。。");
}
destroy也只执行一次 ,是在 servlet 从 servlet 容器(tomcat)中卸载的时候执行。
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("serlvet提供服务.......");
}
servlet 方法是真正提供服务的方法。可以处理请求和响应。
在serlvet中存在构造方法,它也只执行一次,而且先于 init 方法执行。从而说明 servlet 是一个单例的。
Servlet的 构造和初始化时机(< load-on-startup > 0 </ load-on-startup> 中间的参数):
- 默认情况下(<0) 是在第一次请求servlet的时候,构造和初始化 servlet
- 配置构造和初始化的时机 load-on-startup
配置为 >=0 时,则 servlet 随着容器的启动而完成构造和初始化;当参数大于等于0的时候,参数数值越小,构造和初始化的时机越早。
servlet 的另一种开发方式
public class AppServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("do post方法执行......");
}
}
在以后的开发中,我们开发servlet只需要继承httpServlet即可,并需要重写其中的doGet和doPost方法
自定义的Servlet --> HttpServlet(抽象类)–> GenericServlet(抽象类)–> 实现了Servlet接口
在idea中快捷创建servlet:
若新建中没有,可这样设置
新建 servlet 文件
servlet 的相关对象 servletConfig
- servletConfig 是 servlet 程序的配置信息类,servlet 和 servletConfig 对象都是由 tomcat 负责创建,我们负责使用
- servlet 程序默认是首次访问时创建,servletConfig 是每个 servlet 程序创建时,就创建一个对应的 servletConfig 对象
public void init(ServletConfig servletConfig) throws ServletException {
String servletName = servletConfig.getServletName();
ServletContext context = servletConfig.getServletContext();
Enumeration<String> pameterNames = servletConfig.getInitParameterNames();//获取配置的所有的初始化参数的名称
System.out.println(servletName);//hello
System.out.println(context);//Servlet的上下文对象
while (pameterNames.hasMoreElements()){
String name = pameterNames.nextElement();
//根据初始化参数的名称获取对应的值
String value = servletConfig.getInitParameter(name);
System.out.println(name+"--"+value);
}
}
servletConfig 的三大作用:
- 可以获取 Servlet 程序的别名 servlet-name 的值
- 获取初始化参数 init-param
- 获取 ServletContext 对象
在通过继承HttpServlet的Servlet中 如何获取ServletConfig对象?
ServletConfig servletConfig = this.getServletConfig();
servlet 的相关对象 servletContext
什么是servletContext:
- servletContext是一个接口,它表示 Servlet 上下文对象
- 一个 web 工程,只有一个 servletContext 对象实例。
- servletContext 对象是一个域对象。
- servletContext 是在 web 工程部署启动的时候创建,在 web 工程停止的时候销毁。
什么是域对象?
- 域对象,是可以像 Map 一样存取数据的对象,叫域对象。
- 这里的域指的是存取数据的操作范围,整个web 工程。
Map 与域对象的区别:
存数据 | 取数据 | 删除数据 | |
---|---|---|---|
Map | put() | get() | remove() |
域对象 | setAttribute() | getAttribute() | removeAttribute() |
servletContext 类的四个作用:
- 获取web.xml 中配置的上下文参数 context-param
- 获取当前的工程路径,格式: /工程路径
- 获取工程部署后在服务器硬盘上的绝对路径
- 像Map 一样存取数据
@Override
public void init(ServletConfig servletConfig) throws ServletException {
ServletContext context = servletConfig.getServletContext();//servlet的上下文对象
String contextPath = context.getContextPath();///web01
System.out.println(contextPath);
//获取初始化参数
Enumeration<String> names = context.getInitParameterNames();
while(names.hasMoreElements()){
String name = names.nextElement();
String value= context.getInitParameter(name);
System.out.println(name+"---"+value);
}
//使用servletContext域对象存取数据
context.setAttribute("name","张三");
String n =(String) context.getAttribute("name");
System.out.println(n);
}
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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">
<context-param>
<param-name>school</param-name>
<param-value>中北大学</param-value>
</context-param>
<context-param>
<param-name>address</param-name>
<param-value>太原</param-value>
</context-param>
<!-- 注册servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>cn.lanqiao.servlet.HelloServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123455</param-value>
</init-param>
<!--load-on-startup 必须位于init-param之后-->
<load-on-startup>10</load-on-startup>
</servlet>
<!-- 配置serlvet的映射路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>test</servlet-name>
<servlet-class>cn.lanqiao.servlet.TestServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>cn.lanqiao.servlet.AppServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>
</web-app>
在继承了httpservlet的servlet中获取ServletContext对象:
//获取servletContext对象
ServletContext context1 = this.getServletContext();
ServletContext context2 = servletConfig.getServletContext();
XML
简介
可拓展标记语言
作用:
- 用来保存数据,而且这些数据有自我描述性
- 作为项目或模块的配置文件
- 作为网络传输数据的格式(现在主要是 JSON)
xml 语法:
<?xml version="1.0" encoding="UTF-8" ?>
其中:
1. version:版本号
2. encoding-:xml的文件编码
3. standalone="yes/no" :表示 xml 文件是否是独立的 xml 文件
元素(标签):< book> 内容< book> 是指从开始标签到结束标签的内容,中间可以有元素内容,也可以有其他元素,元素本身可以拥有属性
xml 命名规则:
- 名称可以包含字母、数字、以及其他字符
- 名称不能以数字或标点符号开始
- 名称不能以字符 xml 开始
- 名称不能包含空格
xml 属性:
- 一个标签上可以写多个属性,每个属性的值必须用引号引起来
- 书写规则和标签的书写规则相同
语法规则:
- 所有 XML 标签都必须有关闭(闭合 >)标签
- XML 标签对大小写敏感
- XML 必须正确的嵌套
- XML 文档必须有根元素(可以理解为最外边的便签只能有一个,唯一)
- XML 的属性值必须加引号
- XML 中的特殊字符可以用 一些来替代(比如大于,小于)
文本(CDATA区):
- 其中的文本为纯文本,不会被解析
- 格式:< ![CDATA[ 这里是文本内容 ]]>
xml 解析技术:
- xml 文件是标记型文档,可以使用 w3c 组织制定的 dom 技术解析
- 早期 JDK 为我们提供了两种 xml 解析技术 DOM 和Sax简介(已经过时,但我们需要知道这两种技术)
- dom 解析技术是 W3C 组织制定的,而所有的编程语言都对这个解析技术使用了自己语言的特点进行实现。Java 对 dom 技术解析标记也做了实现。
- sun 公司在 JDK5 版本对 dom
- 解析技术进行升级:SAX ( Simple APl forXML )
- SAX解析,它跟 W3C 制定的解析不太一样。它是以类似事件机制通过回调告诉用户当前正在解析的内容。它是一行一行的读取 xml 文件进行解析的。不会创建大量的 dom 对象。所以它在解析xml 的时候,在内存的使用上和性能上,都优于Dom解析。
- 第三方的解析:
- jdom在dom基础上进行了封装、dom4j又对jdom进行了封装。
- pull主要用在 Android 手机开发,是在跟sax非常类似都是事件机制解析xml文件。
Dom4j 它是第三方的解析技术。我们需要使用第三方给我们提供好的类库才可以解析 xml 文件。
dom4j 的使用:
-
下载网址:https://dom4j.github.io/
-
dom4j 编程步骤:
- 第一步:先加载xml文件创建Document对象
- 第二步:通过Document对象拿到根元素对象
- 第三步:通过根元素.elelemts(标签名);可以返回一个集合,这个集合里放着。所有你指定的标签名的元素对象
- 第四步:找到你想要修改、删除的子元素,进行相应在的操作第五步,保存到硬盘上
- 获取 document 对象
- 导入 jar 包
- 解析获取 document 对象的代码
// 首先创建一个 SAXReader 对象
SAXReader reader = new SAXReader;
// 创建一个 document 对象,用于读取 xml 文件
Document document = reader.read("xml/books.xml");
// 通过 Document 对象,拿到 XML 的根元素对象
Element root = document.getRootElement;
// 通过根元素对象,获取所有的 book 标签对象
List<Element> books = root.element("book");
// 遍历每个 book 标签对象,获取到 book 标签对象内的每一个元素,再通过 getText() 获取到开始标签和结束标签的文本内容
for(Element book : books){
Element nameElement = book.element("name");
Element priceElement = book.element("price");
System.out.println(nameElement.getText() + priceElement.getText())
需要分四步操作:
- 第一步,通过创建SAXReader对象。来读取xml文件,获取Document对象
- 第二步,通过Document对象。拿到XML的根元素对象
- 第三步,通过根元素对象。获取所有的 book标签对象
- 第四步,遍历每个book标签对象。然后获取到 book标签对象内的每一个元素,再通过getText)方法拿到起始标签和结束标签之间的文本内容