引入
相关概念
-
软件架构
- C/S:客户端 / 服务器端
- B/S:浏览器 / 服务器端
所谓CS是指 Client—Server(CS架构:客户端和服务器要分离,分别要开发出来客户端和服务器)
优势:传输的数据是可以自定义的、传输的通道时加密的、对于数据具有更好的安全性
缺点:开发成本大、使用成本大(必须要下载客户端装上才能用)
Java不适合做CS架构,做出来的用户界面奇丑无比
所谓的BS是指 Browser—Server
特点:传输使用协议一般是HTTP协议(超文本传输协议),而HTTP承载层使用TCP协议,而对于开发人员,要做的事情就是去实现一个前端的界面,让浏览器可以解析出来这个界面就可以了,传输的数据不是那么的安全,传输数据的格式是既定的。
优点:开发成本低,特别低、使用成本低,也特别低。
-
资源分类
-
静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源。静态资源可以直接被浏览器解析。
如:HTML、CSS、JavaScript
-
动态资源:每个用户 访问相同资源后,得到的结果可能不一样,称为动态资源。动态资源被访问后,需要先转换为静态资源,在返回给浏览器。
如:servlet、jsp、php、asp
-
-
网络通信三要素
-
IP:电子设备(计算机)在网络中的唯一标识
-
端口:应用程序在计算机中的唯一标识。0~65535
-
传输协议:规定了数据传输的规则(就比如浏览器和客户端交流需要用什么语言,英语?汉语?)
TCP协议:安全,三次握手,速度慢
UDP协议:不安全,速度快
-
一、Web服务器软件
引入
服务器:安装了服务器软件的计算机
服务器软件:接受用户的请求,处理请求,做出响应
Web服务器软件(也称:Web容器):接受用户的请求,处理请求,做出响应
- 在Web服务器软件中,可以部署Web项目,让用户通过浏览器访问这个项目
常见的Java相关的网络容器
- webLogic(Oracle公司)、webSphere(IBM公司)、JBOSS(JBOSS公司):支持所有的JavaEE规范,收费
- Tomcat:Apache基金组织,中小型JavaEE服务器,仅支持少量的JavaEE规范(如:Servlet、JSP)
1. Tomcat
Tomcat:Web容器
1.1 下载、安装、启动、配置、部署
官网:https://tomcat.apache.org/download-80.cgi
根据需求,下载zip压缩包
下载成功后解压文件夹即安装成功!
目录结构:
启动
- bin/startup.bat:运行即可
- 访问:浏览器输入:http://localhost:8080
- 可能遇到的问题
- 黑框一闪而过(JAVA_HOME没有配置)
正确配置方式
startup.bat是批处理文件,里面写的就是dos命令。
catalina.bat中有一条dos命令,使用环境变量的JAVA_HOME,找到JDK,然后才能运行Tomcat。Tomcat是纯Java编写的,他的启动依赖于电脑上安装的JDK
**修改端口号(默认是8080):**在conf/server.xml中修改
部署:
-
直接将项目放在webapps目录下即可。
或者:将项目打包成war包,再将war包放在webapps目录下。(war包会自动解压缩)
2. 将Tomcat集成到IDEA中,并且创建JavaEE的项目,部署项目
2.1 手动集成Tomcat
Run—>Edit Configurations
接下来点击apply就成功了
2.2 创建Web项目
一般Tomcat的启动都伴随这Web项目的启动。所以接下来创建Web项目(创建web项目时其实就会自动集成好了Tomcat)
File—>New—>Project
部署:
虚拟路径指项目的访问路径
热部署:
二、Servlet
概念:server applet:运行在服务器端的小程序
- Servlet就是一个接口,这个接口定义了Java类被浏览器访问到(Tomcat识别)的规则
将来自定义一个类,实现Servlet接口,覆写方法。
配置Servlet
写一个Servlet就要配置一个Servlet
web.xml是Tomcat找到其他类的指路标,然后用类加载反射机制加载这些类,所以要在web-app里写好路标(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">
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>com.home.java.service.ServletDemo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1.do</url-pattern>
</servlet-mapping>
</web-app>
1. Tomcat执行Servlet的执行原理:
- 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
- 查找web.xml文件,看是否有对应的标签体内容
- 如果有,则在找到对应的全类名
- Tomcat会将字节码文件加载今内存,并创建其对象
- 调用其方法
如图:
2. Servlet的生命周期
- init():初始化方法,在Servlet被创建时执行。且只会执行一次
- service():提供服务方法,每一次Servlet被访问时,执行。执行多次
- destroy():销毁方法,在服务器正常关闭时,才会执行。执行一次
package com.home.java.service;
/**
* @author ZAQ
* @create 2020-04-05 18:49
*/
public class ServletDemo1 implements Servlet {
public ServletDemo1() {
System.out.println("我是构造方法");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("我是init方法");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("我是Service");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
Servlet什么时候被创建?
-
默认情况下,第一次被访问时,Servlet被创建
-
但是也可以配置执行Servlet的创建时机
在标签下配置
-
设置第一次被访问时创建
<load-on-startup>
的值为负数 -
设置在服务器启动时创建
<load-on-startup>
的值为0或正整数
-
执行顺序:先执行ServletDemo1()方法创建对象(构造器),然后执行init()方法,然后是Service()方法
Servlet的init方法只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的
- 多个用户同时访问时,可能存在线程安全问题
- 解决:尽量不要在servlet中定义成员变量。即使定义了成员变量,也不要修改其值
destroy()方法在Servlet被销毁之前执行,一般用于释放资源(init()用于加载资源)
3. Servlet注解配置
由于每个Servlet都要在xml文件中配置,过于麻烦,所以引入注解配置,方便快捷
注解配置:只需要在类上面写@WebServlet("/demo1.do")
即可
路径定义规则:
- /xxx
- *.do(注意没有 / )
Tomcat真正访问的是“Tomcat部署的web项目”,“Tomcat部署的web项目”对应着“工作空间项目”的web目录下的所有资源。
WEB-INF目录下的资源不能被浏览器直接访问。
4. Servlet的体系结构
Servlet—接口
- GenericServlet—抽象类(实现了Servlet接口)
- HttpServlet—抽象类(继承GenericServlet)
GenericServlet:将Servlet接口中的其他的方法做了默认空实现,只将service()方法作为抽象
HttpServlet:对Http协议的一种封装,简化操作
- 定义类继承HttpServlet
- 覆写doGet/doPost方法
前端通过form表单发送数据到Servlet中,我们可以通过Servlet中的service()里的一些操作获取这些数据。所以service()里的第一件事就是获取数据,但是在获取数据之前要判断form表单的请求方式。这个过程是繁琐的,并且是每个Servlet都要完成的操作,所以Sun公司提供了一个HttpServlet类,他帮助我们完成了这些操作,以后我们不再需要写判断请求方式的过程,只需要重写doGet()、doPost()方法即可。
HttpServlet源码:
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();//获取请求方式
long lastModified;
//判断是那种请求方式,如果是GET就...如果是Post就...
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader("If-Modified-Since");
} catch (IllegalArgumentException var9) {
ifModifiedSince = -1L;
}
if (ifModifiedSince < lastModified / 1000L * 1000L) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);//如果是GET请求,则调用doGet
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);//如果是Post请求,则调用doPost
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{
method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
内容持续更新中…