JavaWeb
Web概述
什么是JavaWeb技术
Web是全球广域网,也称为万维网(www),能够通过浏览器访问的网站
JavaWeb就是用Java技术来解决相关web互联网领域的技术栈
而JavaEE就是解决相关web互联网领域的技术栈, 其实本质上就是大型的网络编程, 是需要很多技术才能解决企业赚钱的问题
而JavaEE中的技术就包括
JDBC
Mybatis
B/S架构
什么是B/S架构?
B/S 架构:Browser/Server,浏览器/服务器 架构模式,它的特点是,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web资源,服务器把Web资源发送给浏览器即可
- 打开浏览器访问百度首页,输入要搜索的内容,点击回车或百度一下,就可以获取和搜索相关的内容
- 搜索的内容并不在我们自己的点上,那么这些内容很明显是从百度服务器返回给我们的
- 百度的小细节,逢年过节百度的logo会更换不同的图片,服务端发生变化,客户端不需做任务事情就能获取最新内容
- B/S架构的好处:易于维护升级:服务器端升级后,客户端无需任何部署就可以使用到新的版本。
HTTP
http是什么
HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则
数据传输的规则指的是请求数据和响应数据需要按照指定的格式进行传输。
http协议
主要定义通信规则
浏览器发送请求给服务器,服务器响应数据给浏览器,这整个过程都需要遵守一定的规则,之前大家学习过TCP、UDP,这些都属于规则,这里我们需要使用的是HTTP协议,这也是一种规则。
http的特点
- 基于TCP/IP协议, 也是面向链接安全协议
- 基于"请求"和"响应"模型
- 基于"请求"和"响应"模型
HTTP请求和响应
请求
请求行
请求方法
请求的资源
协议的版本
请求头
键: 值
浏览器告诉服务器自身的一些信息
- 版本
- 支持语言
- 支持的数据格式
附赠信息, 服务器用的着的话就是获取, 用不着就不管
请求空行
仅仅只是隔开请求头和请求体
请求体
封装POST请求的"参数部分"
响应
响应行
协议版本
状态码
状态码描述
响应头
"服务器"告诉浏览器自身的信息, 可以命令浏览器以指定方式或者编码解析我们响应体
响应空行
仅仅隔开响应头和响应体的
响应体
页面要展示的内容
Web服务器
Web服务器:负责解析 HTTP 协议,解析请求数据,并发送响应数据
浏览器按照HTTP协议发送请求和数据,后台就需要一个Web服务器软件来根据HTTP协议解析请求和数据,然后把处理结果再按照HTTP协议发送给浏览器
常见的Web服务器软件
TOMCAT
免费开源
WEBSPHERE
收费
WEBLOGIC
收费
JBOSS
免费, 文档收费
tomcat
tomcat概念
-
Tomcat是Apache软件基金会一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范。
-
概念中提到了JavaEE规范,那什么又是JavaEE规范呢?
JavaEE: Java Enterprise Edition,Java企业版。指Java企业级开发的技术规范总和。包含13项技术规范:JDBC、JNDI、EJB、RMI、JSP、Servlet、XML、JMS、Java IDL、JTS、JTA、JavaMail、JAF。
-
因为Tomcat支持Servlet/JSP规范,所以Tomcat也被称为Web容器、Servlet容器。Servlet需要依赖Tomcat才能运行
官网
安装和卸载
安装
直接解压就可以了
没有中文没有空格特殊字符
打开apache-tomcat目录就能看到如下目录结构
bin
bin目录下有两类文件,一种是以.bat结尾的,是Windows系统的可执行文件,一种是以.sh结尾的,是Linux系统的可执行文件。
webapps
就是以后项目部署的目录
卸载
卸载比较简单,可以直接删除目录即可
启动和关闭
启动
双击 bin\startup.bat
启动后,通过浏览器访问 http://localhost:8080
能看到Apache Tomcat的内容就说明Tomcat已经启动成功
启动的过程中,控制台有中文乱码,需要修改conf/logging.prooperties
关闭有三种方式
- 直接x掉运行窗口:强制关闭[不建议]
- bin\shutdown.bat:正常关闭
- ctrl+c: 正常关闭
配置
修改端口
Tomcat默认的端口是8080,要想修改Tomcat启动的端口号,需要修改 conf/server.xml
HTTP协议默认端口号为80,如果将Tomcat端口号改为80,则将来访问Tomcat时,将不用输入端口号。
安装时启动常见问题的解决
端口冲突
第一种方法
关闭那个占用你端口的程序就可以了
netstat -ano
查询端口对应的pid, 可以通过任务管理器找到pid对应的程序然后关闭
第二种方法
修改端口
在conf/server.xml中 port=“自己端口”
80端口HTTP协议的默认端口可以省略不写
一闪而过
JAVA_HOME没有配置正确
项目的发布方式
第一种方法
-
将项目拷贝到webapps目录中即可完成发布
http://ip地址:端口/项目名/资源名
-
将项目打包成war包放到webapps下即可
- tomcat检测到war会自动解压你的项目, 速率比较快
- 你直接删除war包, 项目也会随着被移除
- 如何将项目的资源打成war包
- 打开cmd, 按住shift + 右键
- jar -cvf aaa.war ./*
第二种方法
去到conf/server.xml中Host标签中添加如下标签
docBase
项目放置的真实位置
path
给真实位置起的别名, 这个别名用于浏览器访问, 我们成为"虚拟路径"
优点
不需要将项目拷贝到webapps下面, 放在任何地方都行, 但是告诉tomcat一声
缺点
修改核心配置文件, 容易把核心配置文件损坏, 导致tomcat启动失败
修改完后必须重启服务器才能生效, 核心配置tomcat启动只会读取一次
第三种方法
在conf/catalina/localhost/下面创建一个任意名称的xml文件,添加如下内容
docBase
项目放置的真实位置
path
给真实位置起的别名, 这个别名用于浏览器访问, 我们成为"虚拟路径"
其实xml的文件名就是传说中虚拟路径 , path可以不写, 写了也没用
优点
不需要将项目拷贝到webapps下面, 放在任何地方都行, 但是告诉tomcat一声
支持热部署, 就算损坏了, 不会影响tomcat
创建maven的web项目
只说一种简单的方式
-
安装插件
-
创建maven的java项目
-
右键java项目, 选择JavaToWeb
Web项目结构
Web项目的结构分为
开发中的项目和开发完可以部署的Web项目,这两种项目的结构是不一样的
Maven Web项目结构
开发中的项目
开发完成部署的Web项目
- 开发项目通过执行Maven打包命令package,可以获取到部署的Web项目目录
- 编译后的Java字节码文件和resources的资源文件,会被放到WEB-INF下的classes目录下
- pom.xml中依赖坐标对应的jar包,会被放入WEB-INF下的lib目录下
静态资源
静态资源主要包含HTML、CSS、JavaScript、图片等,主要负责页面的展示
动态资源
- 动态资源主要包含Servlet、JSP等,主要用来负责逻辑处理
- 动态资源处理完逻辑后会把得到的结果交给静态资源来进行展示,动态资源和静态资源要结合一起使用
Servlet
什么是Servlet
-
Servlet是JavaWeb最为核心的内容,它是Java提供的一门动态web资源开发技术。
-
使用Servlet就可以实现,根据不同的登录用户在页面上动态显示不同内容。
-
Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet
创建一个Servlet
导包
创建WebMaven项目,导入Servlet依赖坐标
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<!--
provided指的是在编译和测试过程中有效,最后生成的war包时不会加入
因为Tomcat的lib目录中已经有servlet-api这个jar包,如果在生成war包的时候生效就会和Tomcat中的jar包冲突,导致报错
-->
<scope>provided</scope>
</dependency>
创建
定义一个类,实现Servlet接口,并重写接口中所有方法
public class ServletDemo implements Servlet {
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("servlet hello world~");
}
public void init(ServletConfig servletConfig) throws ServletException {
}
public ServletConfig getServletConfig() {
return null;
}
public String getServletInfo() {
return null;
}
public void destroy() {
}
}
配置
在类上使用@WebServlet注解,配置该Servlet的访问路径
@WebServlet(“/demo1”)
访问
启动Tomcat,浏览器中输入URL地址访问该Servlet
http://localhost:8080/web-demo/demo1
访问后,在控制台会打印“servlet hello world~”说明servlet程序已经成功运行。
Servlet执行流程
- 浏览器发出http://localhost:8080/web-demo/demo1请求,从请求中可以解析出三部分内容,分别是localhost:8080、web-demo、demo1
- 根据localhost:8080可以找到要访问的Tomcat Web服务器
- 根据web-demo可以找到部署在Tomcat服务器上的web-demo项目
- 根据demo1可以找到要访问的是项目中的哪个Servlet类,根据@WebServlet后面的值进行匹配
- 找到ServletDemo1这个类后,Tomcat Web服务器就会为ServletDemo1这个类创建一个对象,然后调用对象中的service方法
- ServletDemo1实现了Servlet接口,所以类中必然会重写service方法供Tomcat Web服务器进行调用
- service方法中有ServletRequest和ServletResponse两个参数,ServletRequest封装的是请求数据,ServletResponse封装的是响应数据,后期我们可以通过这两个参数实现前后端的数据交互
Servlet生命周期
生命周期
对象的生命周期指一个对象从被创建到被销毁的整个过程。
Servlet运行在Servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段
加载和实例化
默认情况下,当Servlet第一次被访问时,由容器创建Servlet对象
初始化
在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次
请求处理
每次请求Servlet时,Servlet容器都会调用Servlet的service()方法对请求进行处理
服务终止
当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法完成资源的释放。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收
注意
默认情况,Servlet会在第一次访问被容器创建,但是如果创建Servlet比较耗时的话,那么第一个访问的人等待的时间就比较长,用户的体验就比较差,所以我们可以配置
@WebServlet(urlPatterns = “/demo1”,loadOnStartup = 1)
loadOnstartup的取值有两类情况
- 负整数:第一次访问时创建Servlet对象
- 0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高
Servlet中的方法
Servlet中总共有5个方法
初始化方法
在Servlet被创建时执行,只执行一次
void init(ServletConfig config)
提供服务方法
每次Servlet被访问,都会调用该方法
void service(ServletRequest req, ServletResponse res)
销毁方法
当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet
void destroy()
获取Servlet信息
String getServletInfo()
//该方法用来返回Servlet的相关信息,没有什么太大的用处,一般我们返回一个空字符串即可
public String getServletInfo() {
return "";
}
获取ServletConfig对象
ServletConfig getServletConfig()
ServletConfig对象,在init方法的参数中有,而Tomcat Web服务器在创建Servlet对象的时候会调用init方法,必定会传入一个ServletConfig对象,我们只需要将服务器传过来的ServletConfig进行返回即可
Servlet体系结构
Servlet编写比较麻烦,因为我们更关注的其实只有service方法,一般只使用service方法,所以可以使用更简单的方法
想要使用更简单的方法就需要了解Servlet体系结构
开发B/S架构的web项目,都是针对HTTP协议,所以会自定义Servlet,通过继承HttpServlet
@WebServlet("/demo2")
public class ServletDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//TODO GET 请求方式处理逻辑
System.out.println("get...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//TODO Post 请求方式处理逻辑
System.out.println("post...");
}
}
- 要想发送一个GET请求,请求该Servlet,只需要通过浏览器发送http://localhost:8080/web-demo/demo2,就能看到doGet方法被执行了
- 要想发送一个POST请求,请求该Servlet,单单通过浏览器是无法实现的,这个时候就需要编写一个form表单来发送请求,在webapp下创建一个a.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/web-demo/demo4" method="post">
<input name="username"/><input type="submit"/>
</form>
</body>
</html>
页面发送的是GET请求,则会进入到doGet方法中进行执行,如果是POST请求,则进入到doPost方法。这样代码在编写的时候就相对来说更加简单快捷
HttpServletRequest
本质
封装了请求部分的对象
目的
获取跟浏览器消息有关的数据, 其中最重要就是浏览器带过来的参数
HttpServletRequest的方法
String getContextPath()
获取全局路径,“虚拟路径”
资源跳转一定会用到他
getRequestURL()
统一资源定位符
http://ip地址:端口/项目名/资源名
getRequestURI()
统一资源标识
/项目名/资源名
getQueryString()
以前get方式获取参数的方式
BufferedReader getReader()
通过readLine()这个将请求体中的参数读
InputStream getInputStream()
上传文件才会用到
String getParameter(String key)
获取一个键对应一个值得
String[] getParameterValues(String key)
获取一个键对应多个, 其实针对复选框的情况
Map<String, String[]> getParameterMap()
获取所有的键和值
HttpServletRequest的请求转发
req.getRequestDispather(“路径”).forward(req,resp)
特点
- 地址栏不会变化
- 对于浏览器而言其实只发了一次请求
- 转发可以使用request对象共享数据
- 请求只能访问本工程下得资源不能访问外部资源
- 可以WEB-INF下得东西
域对象共享数据
setAttribute(String s, Object o)
创建域对象共享数据
getAttribute(String s)
获取域对象共享数据
removeAttribute(String s)
删除域对象共享数据
HttpServletRequest中出现的问题
post会出现中文乱码问题
req.setCharaterEncoding(“UTF-8”);
因为Http协议不支持中文, 浏览器传入中文数据, 会经过URLEncode的编码, 将其编程 十六进制的格式, tomcat解码的时候如果你没有设置编码则用ISO-8859-1编码来解码, 肯定出现乱码, 通过上面的那句话就可以设置编码
get会出现乱码问题
tomcat7才会出现
你接收到数据, 需要将其打回字节, 然后再用UTF-8组装
String s = ISO-8859-1; byte[] arr = s.getByte(“iso-8859-1”); new String(arr,“utf-8”);
tomcat8不会出现乱码问题
怎么设置, 如果是本地的不用设置. 如果用的maven的插件需要在tomcat的插件中添加一句
UTF-8
String URLEncode.encode(要编码的字符串, “字符串原来的字符集”);
将字符串变成%的方式
URLDecode.decode(要解码的字符串, “期望的编码”)
将%的字符串变回原来的样子
HttpServletresponse
本质
帮我们封装响应部分
目的
设置服务器给浏览器消息数据
HttpServletResponse中的方法
setStatus(int 状态码)
设置状态码
setHeader(“键”, “值”)
告诉浏览器服务器的一些信息, 可以控制浏览器的解析方式和行为
重定向
设置状态码为302
需要设置一个响应头告诉浏览器跳转的路径: location = “路径”
sendRedirect(“路径”);
/虚拟路径/资源路径
特点
- 地址栏会变化
- 对于浏览器而言其实发了多次请求
- 重定向不可以使用request对象共享数据
- 可以访问本工程的资源以及外部资源
- 重定向不可以访问WEB-INF下得东西
路径
绝对路径
客户端路径
a标签的href, form表单中的action, img中的src都是客户端路径, 经过浏览器地址栏的路径, 重定向也是
完整写法
http://ip地址:端口/虚拟路径/资源路径
简化写法(如果访问本服务下面的东西, 服务器的地址可以省略)
/虚拟路径/资源路径
服务器路径
转发
必须从/资源路径开始写
原因是tomcat帮你家了/虚拟路径的限制
能够动态获取虚拟路径的地方都建议大家使用绝对路径
String req.getContextPath();
前后端分离都建议使用绝对路径
相对路径
html页面中都建议使用相对路径
秘诀
- 确认自己的位置
- 确定目标的位置
- 通过 ./ 或者…/方式进行调整