#Tomcat简介
使用Tomcat-8.5.31
Tomcat目录:
bin:脚本目录
启动脚本:startup.bat
停止脚本:shutdown.bat
conf:配置文件目录 (config /configuration)
核心配置文件:server.xml
用户权限配置文件:tomcat-users.xml
所有web项目默认配置文件:web.xml
lib:依赖库,tomcat和web项目中需要使用的jar包
logs:日志文件.
localhost_access_log..txt tomcat记录用户访问信息,..表示时间。
例如:localhost_access_log.2017-04-28.txt
temp:临时文件目录,文件夹内内容可以任意删除。
webapps:默认情况下发布WEB项目所存放的目录。
work:tomcat处理JSP的工作目录。
启动与结束:
双击tomcat解压目录/bin/startup.bat 文件即可启动tomcat。[http://ip:8080即可访问tomcat服务器](http://ip:8080即可访问tomcat服务器)
启动报错原因:
(1) JAVA_HOME 配置 如果没有配置JAVA_HOME环境变量,在双击“startup.bat”文件运行tomcat时,将一闪立即关闭。 解决方式:需要正确配置JAVA_HOME环境变量,指向JDK的bin目录的上一级目录;
(2)端口号冲突
一台拥有ip地址的主机上可以提供多个服务(启动多个软件),每一个服务都有一个唯一的端口号。所以端口号不能 重复。
使用IDEA创建一个WEB项目:
#Servlet入门
\1. 客户端(浏览器)发送的数据会被提交到服务器;
\2. 服务器必须具备:1.接收请求数据;2.处理请求数据(业务逻辑的处理);3.给浏览器生成响应信息的能力;
\3. tomcat服务器遵从了JavaEE规范,Sun公司制定的动态资源规范Servlet实现这个功能;(运行在服务器端,能够接收用户请求,处理请求数据和给浏览器生成响应信息)
\4. 在java的世界里制定规范往往是接口来实现的,所以Servlet是一个接口,里边只是定义了一些方法;
\5. 如果,我们对这个接口进行具体的实现,就能够完成对用户数据的接收,处理和生成响应信息;
1、什么是Servlet
Servlet 运行在服务端的Java小程序,是sun公司提供一套规范,用来处理客户端请求、响应给浏览器的动态web资源。
Servlet是JavaWeb三大组件之一(Servlet、Filter、Listener),是最重要的组件。
Servlet 的作用
\1. 接收请求 :接收客户端发送的请求数据;
\2. 业务逻辑的处理;
\3. 响应结果 :将处理结果响应给客户端(浏览器);
2、Servlet入门开发步骤
\1. 创建一个普通java类实现Servlet接口;
\2. 重写Servelt接口中的所有抽象方法;
\3. 注册这个类;
在web.xml中配置这个类的信息;
配置这个类的映射路径;
\4. 在service方法中处理请求和响应的业务逻辑;
\5. 发布项目,启动项目之后,通过映射路径访问这个类;
3、Servlet入门例子
【例】Servlet入门例
需求分析 :
\1. 编写一个Servlet,接收客户端(浏览器)的请求;
\2. 接收到请求之后给浏览器响应数据”Hello Servlet!”;
技术分析 :
servletResponse.getWriter().print("Hello World!");
实现步骤:
\1. 创建一个普通java类HelloServlet实现Servlet接口,并重写Servlet接口的所有抽象方法;
1 | public class HelloServlet implements Servlet{ |
\2. 在web.xml中配置这个HelloServlet的类路径和映射路径,配置信息如下;
1 | 【注意】 url-pattern 映射路径前面必须添加"/"; |
\3. 在HelloServlet的service方法中书写响应的代码逻辑;
1 |
|
4、Servlet编程优化
我们发现在上述的HelloServlet中,实现Servlet接口后能够接收浏览器发送的请求并能够响应数据给浏览器。但是Servlet是一个接口,我们实现接口后必须重写接口中所有的方法。但是,我们在接口请求和响应数据的时候只需要一个service方法就足够了。所以,我们需要有选择地实现父类的方法。
子类继承父类时,可以根据子类的需求选择性地重写父类的方法。
4.1 方案一:GenericServlet优化方案
1) GenericServlet简介
GenericServlet类是一个抽象类,它实现了多个接口,其中有一个是Servlet,所以它重写了Servlet接口中的所有方法。我们只需要继承GenericServlet类,重写其中的service方法即可。
2)为什么要继承GenericServlet
\1. GenericServlet实现了Servlet接口,我们继承GenericServlet之后相当于间接实现了Servlet接口;
\2. GenericServlet中给我们提供了很多通用方法,这些方法已经帮我们实现了很多功能,继承GenericServlet之后可以直接调用这些方法,所以说,GenericServlet相对于Servlet,进行了功能的扩展和衍生;
\3. GenericServlet是一个抽象类,里边只有一个抽象方法service(),我们继承GenericServlet之后只需要重写service()方法处理具体的业务逻辑即可,减少了直接实现Servlet接口带来的代码冗余;
3) 案例:使用GenericServlet优化Servlet接口编程
需求分析 :使用GenericServlet重写入门案例
技术分析 :
1. 创建一个普通的java类继承GenericServlet;
2. 在web.xml中配置这个GenericServlet的子类;
3. 重写service方法,在service方法中完成向浏览器响应数据的功能;
实现步骤 :
\1. 编写一个普通的java类,ServletDemo1,继承GenericServlet;
1 | package com.qiezi.servlet; |
\2. 在web.xml配置ServletDemo1;
1 | <servlet> |
\3. 重写service方法,并在service方法中书写以下代码,完成向页面响应数据;
1 |
|
\4. 启动tomcat并访问:
4.2 方案二:HttpServlet优化方案
问题:
在实际的生活中,客户端(浏览器)给我们发送的请求往往是HTTP协议下的请求,所以我们只需要处理HTTP的请求和响应即可。也就是说我们需要的知识一个与HTTP协议相关的Servlet。
解决方案:
Sun公司为我们提供了HttpServlet,对GenericServlet再次进行扩展和功能加强。
实际开发中:我们编写Servlet就可以采用 继承HttpServlet来完成servlet的开发,这样的Servlet我们可以获取更多的业务功能。
1)HttpServlet简介:
HttpServlet是GenericServlet的一个子类。这个类是专门帮我们处理与HTTP协议相关的请求与响应的一个Servlet类,它里边的方法如下:
因为,在我们的日常生活中最常用的HTTP请求只有get请求和post请求。所以我们在继承了HttpServlet之后只需要重写里边的doGet()方法和doPost()方法即可满足我们的需求:
2)为什么要继承HttpServlet
\1. HttpServlet继承了GenericServlet,功能比GenericServlet更强大;
\2. GenericServlet中处理不同的请求都使用service()方法,HttpServlet根据不同的请求方式提供了不同的方法进行处理。等于是细化了service()方法;
\3. HttpServlet类中的方法参数为HttpServletRequest对象和HttpServletResponse对象。使用这两个对象的好处在于:
HttpServletRequest继承了ServletRequest,HttpServletResponse继承了ServletResponse。功能更强大;
HttpServletRequest和HttpServletResponse为我们提供了很多处理HTTP协议相关的API,HTTP协议正是我们日常生活中使用得比较多的一种协议;
(3)HttpServlet编程
1 | 【Servlet优化二】HttpServlet编程 |
(4)请求是怎么到达doGet()和doPost()的
在我们继承HttpServlet之后,重写了doGet()和doPost()方法。浏览器发送的get请求会被doGet()接收并处理,浏览器发送的post请求会被doPost()请求接收并处理。服务器端是怎么辨别我的请求是get还是post请求的呢?下面,我们看一下HttpServlet的源码中的service方法:
\1. 实际处理请求的还是HttpServlet的service()方法;
\2. service方法中,接收请求之后获取了请求方式,
1 | protected void service(HttpServletRequest req, HttpServletResponse resp) |
4.3 Servlet编程优化小结
\1. Servlet编程的作用:接收浏览器的请求,处理请求数据,给浏览器响应数据;
\2. Servlet接口:
Sun公司规定如果想要在服务端接收和响应客户端的数据,必须实现Servlet接口;
由于Servlet是一个接口,实现Servlet接口后必须重写其中所有的方法;
\3. GenericServlet:
GenericServlet:是一个抽象类,它实现了Servlet接口,与协议无关;
继承GenericServlet,只需要重写service方法即可接收和响应数据;
\4. HttpServlet:
HttpServlet:是一个抽象类,它继承了GenericServlet,为HTTP请求定制的;
继承HttpServlet,重写doGet和doPost方法,能够更加方便地处理不同请求的数据;
5、Servlet生命周期
生命周期指的是一个对象从创建到销毁的过程。我们的Servlet是由谁创建的,何时创建的,创建之后做了哪些工作,工作完成之后又是何时销毁的呢?下面我们就来看一下Serlvet的生命周期。
谁创建:tomcat创建;
何时创建:第一次访问这个Servlet的时候,只创建一次,创建完成后会调用init()方法;
如何工作:每次请求到这个Servlet时,由service方法处理请求和响应信息;
何时销毁:服务器正常关闭,销毁前会调用destory()方法;
1 | 【测试代码】 |
【小结】
Servlet对象的创建:
创建者:tomcat;创建时机:在Servlet第一次被访问的时候;
特点:
只会创建一次(单例);
对象创建完成之后,会调用init()方法;
Servlet运行:
service()方法接收用户的请求,和处理响应;
特点:
每次对这个Servlet的访问都会由service()方法来处理;
service()方法的两个参数:request和response对象专门用来处理请求和响应;
Servlet销毁:
Servlet对象在服务器正常关闭的时候销毁;
特点:
销毁的时候会调用destory()方法;
【注意】Servlet对象是单例的,会不会产生线程安全问题?
答:线程安全问题的产生是因为要争夺共同的资源,所以只要不在Servlet类中设置成员变量就可以避免。
6、 Servlet映射路径配置规范
url-pattern中的映射路径配置存在以下几种方式:
1. 完全匹配 /user/hello 资源路径为/user/hello时可以访问
2. 目录匹配 /user/* 资源路径中含有/user目录均可访问
3. 后缀名匹配 *.do 资源路径中以.do结尾的均可访问
4. 缺省路径 / 访问的路径找不到,就会去找缺省路径
tomcat获得匹配路径时,优先级顺序:1 >2 > 3 > 4
开发中一般使用完全匹配,即一个Servlet对应一个映射路径。
\1. 配置servlet的实现类信息:
1 | <!--1.配置HelloServlet的类路径--> |
\2. 配置这个实现类的映射路径:
1 | <!--2.配置映射路径,映射到HelloServlet--> |
\3. url-pattern配置规则
1 | <!--1.配置HelloServlet的类路径--> |
【关于缺省路径】web.xml
URL输入http://localhost:8080/ 如何读取文件?
1)到当前WEB应用下的web.xml文件查找是否有匹配的url-pattern。
2)如果没有匹配的url-pattern,则交给tomcat的内置的DefaultServlet处理。
3)DefaultServlet程序到WEB应用的根目录下查找是否存在一个名称为index.html的静态文件。
4)如果找到该文件,则读取该文件内容,返回给浏览器。
5)如果找不到该文件,则返回404错误页面。
7.服务器启动,立刻加载Servlet对象
问题:普通的Servlet对象在我们第一次访问的时候创建, 开发中,如果我们需要在服务器启动的时候,初始化Servlet对象应该如何编写呢?
需求:服务器tomcat启动,立刻加载配置文件,获取配置文件信息,为项目后续代码提供数据支持。
解决:此时的业务场景,我们需要在web.xml文件中给指定的Servlet添加一个标签
实现步骤:在web.xml中在
#Servlet3.0注解开发
在我们上面创建的Servlet中,Servlet的配置信息都是在web.xml中完成的。如果,我们创建的Servlet非常多,就会导致web.xml中的配置非常臃肿,不便于管理。Servlet3.0为我们提供了注解支持,创建Servlet的时候。在这个Servlet类上面添加注解就可以完成Servlet的配置。Servlet3.0除了提供注解支持,还提供了以下新特性:
1、Servlet3.0新特性
- 注解支持
该版本新增了若干注解,用于简化 Servlet、过滤器(Filter)和监听器(Listener)的声明,这使得 web.xml 部署描述文件从该版本开始不再是必选的了。
- 支持web模块(servlet filter Listener)
- 支持Servlet异步处理
- 文件上传API简化
【注意】详细信息请参考Servlet3.0新特性全解
2、为什么要使用注解
\1. web.xml中配置过多servlet不便于管理,容易出错;
\2. 注解开发使得开发更敏捷,效率更高;
\3. 注解开发是一种趋势;
3、使用IDEA创建3.0版本的Servlet
新版的IDEA(2017版本)创建的Servlet默认是3.0版本的,所以我们只需要新建一个Servlet,然后用注解配置即可。具体步骤如下:
第一步:新建一个Servlet;
在包上面点击鼠标右键New-->Servlet
给这个Servlet取个名,然后点击OK
第二步:配置Servlet
创建完成后,Servlet类上面会默认添加一个注解@WebServlet(name="Servlet3Demo") 。这个@WebServlet注解就是用来配置当前这个Servlet的。这个注解中常用的有两个属性:
\1. name属性: 相当于web.xml的
\2. urlPatterns属性: 编写访问servlet的路径 类似于
所以,我们需要手动在@WebServlet 注解中添加urlPatterns属性,来设置映射路径。
1 | package com.qiezi.servlet; |
4、优化
4.1 优化一
我们继承HttpServlet之后,重写doGet()方法处理get请求,重写doPost()方法处理post请求。但是,浏览器发送的请求到底是get请求还是post请求,我们在书写Servlet代码的时候并不知道。所以,需要在doPost()方法中调用doGet()方法,或者是在doGet()方法中调用doPost()方法。这样我们只需要在一个方法中处理请求了。
4.2 优化二
基于IDEA的模板,快速创建Servlet。
【模板配置代码】
1 | #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end |
5、Servlet开发最终版本
1 | "/lastDemo") ( |