Tomcat
Web服务器软件
- Web服务器软件:接收用户的请求,处理请求,做出响应。web容器,部署web项目。
常见的web服务器:
- webLogic:oracle公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
- webSphere:IBM公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
- JBOSS:JBOSS公司的,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
- Tomcat:Apache基金组织,中小型的JavaEE服务器,仅仅支持少量的JavaEE规范servlet/jsp。开源的,免费的。
Java SE:Java Standard Edition,Java 标准版。是Java技术的核心和基础,是Java ME和Java EE编程的基础。
Java EE:Java Platform Enterprise Edition企业级应用程序版本。Java语言在企业级开发中使用的技术规范的总和,一共规定了13项大的规范
Java ME:Java Platform Micro Edition,是一个技术和规范的集合,它为移动设备(包括消费类产品、嵌入式设备、高级移动设备等)提供了基于Java环境的开发与应用平台。
Tomcat
目录结构
- bin:可执行文件
- conf:配置文件
- libs:依赖jar包
- logs:日志文件
- temp:临时文件
- webapps:存放web项目
- work:存放运行时的数据
可能遇到的问题
黑窗一闪而过
- 原因:没有正确配置JAVA_HOME环境变量
启动报错
- 端口被占用:找到占用的端口号,杀死该进程,或修改自身端口号(
查看进程和端口号netstat -ano
) 修改端口号:conf/server.xml
1
2
3<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />一般会将tomcat的默认端口号修改为80。80端口号是http协议的默认端号。在访问时,就不用输入端口号
- 端口被占用:找到占用的端口号,杀死该进程,或修改自身端口号(
关闭
正常关闭
- bin/shutdown.bat
- ctrl+c
强制关闭
- 关闭窗口
部署
简单部署:将项目打成一个war包,再将war包放置到webapps目录下。(war包会自动解压缩)
配置conf/server.xml文件
1
2
3
4在<Host>标签体中配置
<Context docBase="D:\xxx" path="/xxx" />
// docBase:项目存放的路径
// path:虚拟目录热部署:在conf\Catalina\localhost创建任意名称的xml文件。在文件中编写
1
2<Context docBase="D:\xxx" />
* 虚拟目录:xml文件的名称
Servlet
- Server Applet:运行再服务器端的小程序
概念
- Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
- Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则
- 需要自定义一个类,实现Servlet接口,复写方法。
快速入门
创建JavaEE项目
定义一个类,实现Servlet接口
public class 类名 implements Servlet
实现接口中的抽象方法
- init:创建
- ServletConfig:获取Servlet配置对象
- service:提供服务
- getServletInfo:获取Servlet信息
- destroy:销毁
- 配置Servlet
1 |
|
- 执行原理
- 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
- 查找
web.xml
文件,是否有对应的<url-pattern>
标签体内容。 - 如果有,则在找到对应的
<servlet-class>
全类名 - tomcat会将字节码文件加载进内存,并且创建其对象
- 调用其方法
Servlet生命周期
创建
init
方法,只执行一次- 默认情况:第一次被访问时,Servlet被创建
配置执行创建时机:
- 在
<servlet>
标签下配置<load-on-startup>
- 负数:第一次被访问时创建
- 0或正整数:服务器启动时创建
- 在
注意:Servlet的iniy方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的。
- 多个用户同时访问时,可能存在线程安全问题
- 解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要修改值。
提供服务
- 提供服务:执行
service
方法,执行多次 - 每次访问Servlet时,service方法都会被调用一次
销毁
- 销毁:
destroy
方法,只执行一次 - 只有服务器正常关闭时,才会执行destroy方法。
destroy方法
在Servlet被销毁之前执行,一般用于释放资源
Servlet3.0
支持注解配置,无需web.xml
步骤
- 创建JavaEE项目。选择Servlet的版本3.0以上,可以不创建web.xml
- 定义一个类,实现Servlet接口
- 复写方法
在类上使用
@WebServlet
注解,进行配置@WebServlet(urlPatterns = "资源路径")
@WebServlet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
({ElementType.TYPE})
(RetentionPolicy.RUNTIME)b
public WebServlet {
String name() default "";//相当于<Servlet-name>
String[] value() default {};//代表urlPatterns()属性配置
String[] urlPatterns() default {};//相当于<url-pattern>
int loadOnStartup() default -1;//相当于<load-on-startup>
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
IDEA与tomcat的相关配置
IDEA会为每一个tomcat部署的项目单独建立一份配置文件
- 查看控制台的log:Using CATALINA_BASE
工作空间项目
和tomcat部署的web项目
- tomcat真正访问的是“tomcat部署的web项目”(out文件夹),”tomcat部署的web项目”对应着”工作空间项目” 的web目录下的所有资源
- WEB-INF目录下的资源不能被浏览器直接访问。
Servlet体系结构
1
2
3
4
5
Servlet -- 接口
|
GenericServlet -- 抽象类
|
HttpServlet -- 抽象类
GenericServlet
:将Servlet接口中其他的方法做了默认空实现
,只将service()
方法作为抽象- 将来定义Servlet类时,可以继
承GenericServlet
,实现service()
方法即可
- 将来定义Servlet类时,可以继
HttpServlet
:对http协议的一种封装,简化操作- 定义类继承
HttpServlet
- 复写
doGet/doPost
方法
- 定义类继承
Servlet相关配置
urlPattern
:Servlet访问路径- 一个Servlet可以定义多个访问路径 :
@WebServlet({"/d4","/dd4","/ddd4"})
- 路径定义规则:
/xxx
:路径匹配/xxx/xxx
:多层路径,目录结构*.do
:扩展名匹配
- 一个Servlet可以定义多个访问路径 :
Request & Response
request
对象和response
对象的原理- request和response对象是由服务器创建的
- request对象是来获取请求消息,response对象是来设置响应消息
Request
request对象继承体系结构
1 | ServletRequest -- 接口 |
request功能
获取请求消息数据
获取请求行数据
- 获取当前请求方式:
String getMethod()
- 获取当前虚拟目录:
String getContextPath()
- 获取Servlet路径:
String getServletPath()
- 获取
get
方式请求参数:String getQueryString()
获取请求URI:
String getRequestURI()
:URI:统一资源标识符StringBuffer getRequestURL()
:URL:统一资源定位符
获取协议及版本:
String getProtocol()
- 获取客户机的IP地址:
String getRemoteAddr()
- 获取当前请求方式:
获取请求头数据
String getHeader(String name)
:通过请求头的名称获取请求头的值Enumeration<String> getHeaderNames()
:获取所有的请求头名称
获取请求体数据
- 请求体:只有POST请求方式才有,请求体中封装了POST请求的请求参数
BufferedReader getReader()
:获取字符输入流,只能操作字符数据ServletInputStream getInputStream()
:获取字节输入流,可以操作所有类型数据
其他功能
获取请求参数通用方法
String getParameter(String name)
:根据参数名称获取参数值String[] getParameterValues(String name)
:根据参数名称获取参数值的数组Enumeration<String> getParameterNames()
:获取所有请求的参数名称Map<String,String[]> getParameterMap()
:获取所有参数的map集合中文乱码问题:
- get方式:tomcat 8 已经将get方式乱码问题解决了
- post方式:会乱码
- 解决:在获取参数前,设置request的编码
request.setCharacterEncoding("utf-8");
- 解决:在获取参数前,设置request的编码
请求转发
- 一种在服务器内部的资源跳转方式
步骤
- 通过request对象获取请求
转发器对象
,RequestDispatcher getRequestDispatcher(String path)
- 使用RequestDistpatcher对象来进行转发:
forward(ServletRequest request,ServletRespons response)
- 通过request对象获取请求
特点:
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器内部资源中
- 转发是一次请求
共享数据
- 域对象:一个有作用范围的对象,可以在范围内共享数据
request
域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据- 方法:
void setAttribute(String name,Object obj)
:存储数据Object getAttribute(String name)
:通过键 获取 值void removeAttribute(String name)
:通过键 移除 键值对
获取ServletContext
ServletContext getServletContext()
用户登录
步骤
- 创建项目,导入html页面,配置文件,jar包
- 创建数据库
创建包domain,创建类User
- domain 存放 javabean
创建包util,编写工具类JDBCUtils
- JDBC工具类:
- 获取连接池
DataSource
对象 - 获取数据库连接
Connection
对象
- 获取连接池
- JDBC工具类:
创建包dao,创建类UserDao,提高login方法
- dao:datasource access object,数据库连接对象
- dao:处理所有的数据库相关操作
单元测试,数据库是否正常连接
创建web.servlet包,实现LoginServlet类
注意
- html中的
form
表单中的action
属性:虚拟目录+Servlet的资源路径
BeanUtils工具类
- 导包:
commons-beanutils-1.8.0.jar
- 用于封装JavaBean
JavaBean:
- 类必须被public修饰
- 必须提供空参的构造器
- 成员变量必须使用private修饰
- 提供公共setter和getter方法
JavaBean中的属性:setter和getter方法截取后的产物
- 例如:getUsername() –> Username–> username(一般和成员方法名相同)
常用方法:
setProperty(Object bean, String name, Object value)
:设置属性getProperty(Object bean, String name)
:获取属性populate(Object bean, Map<String,? extends Object> properties)
:将map集合的键值对信息,封装到对应的JavaBean对象中
Response
功能:设置响应消息
设置响应行
- 格式:
HTTP/1.1 200 OK
- 设置状态码:
setStatus(int sc)
- 格式:
设置响应头
setHeader(String name,String value)
设置响应体
获取输出流
- 字符输出流:
PrintWriter getWriter()
- 字节输出流:
ServletOutputStream getOutputStream()
- 字符输出流:
使用输出流:将数据输出到客户端浏览器
重定向
资源的跳转
1
2
3
4// 设置状态码为302
response.setStatus(302);
// 设置响应头location
response.setHeader("location","/JavaEE_Response/responseDemo2");方法:
sendRedirect("/虚拟目录/资源路径")
特点:
||地址栏|服务器|请求|
|—|—|—|—|
|转发Forward|地址栏路径不变|只能访问当前服务器下的资源|一次请求
可以使用request对象共享数据|
|重定向Redirect|地址栏发送变化|可以访问其他站点(服务器)资源|两次请求
不可以使用request对象共享数据|
路径写法
相对路径
- 通过相对路径不可以确定唯一资源
- 不以
/
开头,以.
开头 - 规则:找到当前资源和目标资源之间的相对位置关系
./
:当前目录../
:后退一级目录
绝对路径
- 通过绝对路径可以确定唯一资源
- 以
/
开头 规则:判断定义的路径是给谁用
给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
- 建议虚拟目录动态获取:
request.getContextPath()
<a>,<form>,重定向
- 建议虚拟目录动态获取:
给服务器使用:不需要加虚拟目录()
- 转发路径
服务器输出字符数据到浏览器
步骤:
- 获取字符输出流
输出数据
1
2
3
4
5// 获取字符输出流
PrintWriter pw = response.getWriter();
// 输出数据
pw.write("<h1>hello response</h1><br>");
中文乱码
- 浏览器:与操作系统有关,windows GBK
PrintWriter pw = response.getWriter();
:获取的流的默认编码是ISO-8859-1- 设置该流的默认编码
告诉浏览器响应体使用的编码(设置响应头
content-type
)1
2
3
4// 设置响应头
response.setHeader("content-type","text/html;charset=utf-8");
//或者使用简单的形式,设置编码,是在获取流之前设置
response.setContentType("text/html;charset=utf-8");
ServletContext对象
- 概念:代表整个web应用,可以和程序的容器(服务器)进行通信
获取:
- 通过
request
对象获取:request.getServletContext();
- 通过
HttpServlet
获取:this.getServletContext();
- 通过
功能:
获取
MIME
类型- MIME:在互联网通信过程中定义的一种文件数据类型
- 格式:大类型/小类型 text/html image/jpeg
- 获取方法:
String getMimeType(String file)
域对象:共享数据
- ServletContext对象范围:所有用户所有请求的数据
setAttribute(String name,Object value)
getAttribute(String name)
removeAttribute(String name)
3. 获取文件的真实(服务器)路径
- 方法:`String getRealPath(String path)`
文件下载
步骤:
- 获取下载文件名:request.getParameter()
将资源按字节输入流读入内存
- 找到资源在服务器内的路径:ServletContext对象getRealPath方法
- 读入字节输入流:创建FileInputStream对象,传递路径
设置response响应头
- 获取文件类型:ServletContext对象的getMimeType()
- 设置响应头类型:content-type
- 设置响应头打开方式:content-disposition
将输入流数据 写出到 response输出流
- 获取输出流对象:response.getOutputStream()
- 设置缓冲区:byte[] buff = new byte[1024*4];
- 输出数据:write方法
- 关闭缓冲区:close方法
1 | // 获取文件名称 |
- 中文乱码
- 获取客户端使用的浏览器版本信息
- 根据不同的版本信息,设置filename的编码方式不同