1、tomcat的目录结构
2、运用Tomcat服务器部署WEB项目
2.1 标准的JavaWeb应用目录结构
WebAPP(文件夹,项目)
|---静态资源: html,css,js,图片(它们可以以文件存在,也可以以文件夹存在)
|---WEB-INF 固定写法。此目录下的文件不能被外部(浏览器)直接访问
|---lib:jar包存放的目录
|---web.xml:当前项目的配置文件(3.0规范之后可以省略)
|---classes:java类编译后生成class文件存放的路径
2.2 发布项目到tomcat
2.2.1 方式一:直接发布
只要将准备好的web资源直接复制到tomcat/webapps文件夹下,就可以通过浏览器使用http协议访问获取
2.2.2方式二: 虚拟路径的方式发布项目
第一步:在tomcat/conf目录下新建一个Catalina目录(如果已经存在无需创建)
第二步:在Catalina目录下创建localhost目录(如果已经存在无需创建)
第三步:在localhost中创建xml配置文件,名称为:随便写,比如叫做second.xml(注:这个名称是浏览器访问路径)
第四步:添加second.xml文件的内容为: docBase就是你需要作为虚拟路径的项目的路径
<?xml version = "1.0" encoding = "utf-8"?>
<Context docBase="C:\JavaEE_Relation\JavaEE101\it101_staticWeb\day24_html" />
第五步:直接访问(通过写配置文件的路径来访问):
http://localhost:8080/second/a.html (second就是配置文件的名字, 映射成了myApp)
使用IDEA创建web工程配置tomcat
创建javaweb项目,选择Java Enterprise
目录结构
引入的外部依赖包,放在WEB-INF/lib中
不能在WEB-INF里面放置静态资源,否则不能直接访问,应放在web里
发布
3、Servlet概述
2.1 什么是Servlet
Servlet **运行在服务端(tomcat)**的Java小程序(对象),是sun公司提供一套规范. 就是动态资源
2.2Servlet作用
用来接收、处理客户端请求、响应给浏览器的动态资源。
但servlet的实质就是java代码,通过java的API动态的向客户端输出内容
2.3 servlet与普通的java程序的区别
- 必须实现servlet接口
- 必须在servlet容器(服务器 tomcat)中运行
- servlet程序可以接收用户请求参数以及向浏览器输出数据
4、Servlet入门
4.1 配置文件方式实现
- 创建一个类实现Servlet接口
import javax.servlet.*;
import java.io.IOException;
/**
* 编写Servlet的步骤:
* 1. 实现Servlet接口,重写方法
* 2. 配置Servlet的映射路径(目的就是让浏览器能够访问到Servlet)
* 方式一: 配置文件方式
* web.xml配置
* 方式二: 注解方式 WebServlet注解
* 一个Servlet可以配置多个映射路径,但是多个Servlet不能配置相同的映射路径
*
*
* Servlet的三种映射路径的配置:
* 1. 完整路径匹配:一定要以"/"开头,类似"/demo01"那么就说明客户端的路径只有是"/demo01"才能访问到这个Servlet
* 2. 目录匹配:一定要以"/"开头,类似"/*"或者"/demo/*",那么客户端访问这个Servlet只要匹配/*之前的路径就行了
* 3. 扩展名匹配: 一定不要以"/"开头,类似"*.do"或者"*.in",那么客户端访问这个Servlet只需要匹配后缀即可
*
* Servlet的生命周期: Servlet对象从创建到销毁的整个过程
* 1. Servlet对象什么时候创建: 默认情况下,是在第一次有请求访问这个Servlet的时候创建
* 2. Servlet对象什么时候销毁: 服务器关闭,或者该项目从服务器移除的时候销毁
*
* Servlet的生命周期方法: 在Servlet的生命周期的各个不同的阶段所执行的方法
* 1. init: 在Servlet创建的时候执行的方法,我们通常在这个方法中做一些初始化数据读取的操作
* 2. service: 在Servlet每次接收处理请求的时候执行的方法
* 3. destroy: 在Servlet销毁的时候执行的方法,执行一些资源回收,或者资源备份的操作
*
* Servlet可以配置启动项: 在服务器启动的时候就创建
*/
//@WebServlet(value = "/demo01",loadOnStartup = 1)
public class ServletDemo01 implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
//在init方法中,读取当前Servlet的初始化参数
String initParam = servletConfig.getInitParameter("ContextConfigLocation");
System.out.println("ServletDemo01对象被创建出来了..."+initParam);
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//查询数据库,使用响应将数据响应给浏览器
System.out.println("Hello........");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("ServletDemo01对象被销毁了...");
}
}
- web.xml配置(该文件在web/WEB-INF 文件夹下):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!--配置Servlet-->
<!--配置ServletDemo01的映射路径-->
<servlet>
<!--
任意名字,建议是类名首字母改小写
-->
<servlet-name>servletDemo01</servlet-name>
<!--要配置的Servlet的全限定名-->
<servlet-class>com.itheima.servlet.ServletDemo01</servlet-class>
<!--
给这个Servlet配置初始化参数
-->
<init-param>
<param-name>ContextConfigLocation</param-name>
<param-value>application.xml</param-value>
</init-param>
<!--添加启动项-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<!--和servlet标签中的name保持一致-->
<servlet-name>servletDemo01</servlet-name>
<!--客户端能够访问的映射路径,目前一定要以/开头-->
<url-pattern>/demo01</url-pattern>
</servlet-mapping>
</web-app>
4.2注解方式实现
- 创建一个类实现Servlet接口, 添加注解
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/demo02")
public class ServletDemo02 implements Servlet{
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("hello world...");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
浏览器地址栏输入:http://localhost:8080/day27_servlet/demo02
maven依赖:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
看异常,找Caused by
配置文件方式与注解方式比较
注解方式简化的javaweb代码开发,可以省略web.xml配置文件.
但是配置文件方式必须掌握的(在框架或者大项目里面会使用到的)
@WebServlet
Servlet 接口
public interface Servlet {
/**
* Called by the servlet container to indicate to a servlet that the
* servlet is being placed into service.
*/
public void init(ServletConfig config) throws ServletException;
/**
*
* Returns a {@link ServletConfig} object, which contains
* initialization and startup parameters for this servlet.
*/
public ServletConfig getServletConfig();
/**
* Called by the servlet container to allow the servlet to respond to
* a request.
*/
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
/**
* Returns information about the servlet, such
* as author, version, and copyright.
*/
public String getServletInfo();
/**
*
* Called by the servlet container to indicate to a servlet that the
* servlet is being taken out of service. This method is
* only called once all threads within the servlet's
* <code>service</code> method have exited or after a timeout
* period has passed. After the servlet container calls this
* method, it will not call the <code>service</code> method again
* on this servlet.
*/
public void destroy();
}
ServletRequest
ServletResponse
Servlet执行原理
4.3 Servlet路径的配置url-pattern
url-pattern配置方式共有三种:
- 完全路径匹配: 以 / 开始. 注: 访问的路径不能多一个字母也不能少一个
例如: 配置了/demo01 请求的时候必须是: /demo01
- 目录匹配"以 / 开始需要以 * 结束. 注: Servlet里面用的 不多, 但是过滤器里面通常就使用目录匹配。客户端访问这个Servlet只要匹配 * 之前的路径就行了
例如: 配置/* 访问/a, /aa, /aaa; 配置 /aa/* 访问 /aa/b , /aa/cc
- 扩展名匹配**不能以 / 开始, 以 * 开始的 .**客户端访问这个Servlet只需要匹配后缀即可
例如: *.action; 访问: aa.action, bb.action, c.action; 错误写法: /*.do, 不可以写*.jsp,*.html
注意的地方:
-
一个路径只能对应一个servlet, 但是一个servlet可以有多个路径
-
tomcat获得匹配路径时,优先级顺序:完全路径匹配> 目录匹配 > 扩展名匹配
5、Servlet进阶
5.1 Servlet的生命周期
- Servlet对象是由服务器创建(反射)
- request与response对象也是由tomcat服务器创建
- service()方法也是服务器调用的
1 生命周期概述
一个对象从创建到销毁的过程
2 Servlet生命周期方法
servlet从创建到销毁的过程
出生:(初始化)用户第一次访问时执行。
活着:(服务)应用活着。每次访问都会执行。
死亡: 服务器关闭,或者该项目从服务器移除的时候销毁
serrvlet生命周期方法:
init(ServletConfig config)
在Servlet创建的时候执行的方法,我们通常在这个方法中做一些初始化数据读取的操作
service(ServletRequest req, ServletResponse res)
在Servlet每次接收处理请求的时候执行的方法
destroy()
在Servlet销毁的时候执行的方法,执行一些资源回收,或者资源备份的操作
3 Servlet生命周期描述
-
常规【重点】
默认情况下, 来了第一次请求, 会调用init()方法进行初始化【调用一次】
任何一次请求 都会调用service()方法处理这个请求
服务器正常关闭或者项目从服务器移除, 调用destory()方法进行销毁【调用一次】
-
扩展
servlet是单例多线程的, 尽量不要在servlet里面使用值可变的全局(成员)变量,可能会导致线程不安全
单例: 只有一个对象(init()调用一次, 创建一次)
多线程: 服务器会针对每次请求, 开启一个线程调用service()方法处理这个请求
5.2 ServletConfig
Servlet的配置对象, 可以使用用ServletConfig来获得Servlet的初始化参数,在SpringMVC里面会遇到
- 先在配置文件里面配置初始化参数
可以通过akey获得aaa
ServletConfig 常用方法
public ServletContext getServletContext()
//返回当前Servlet所在的ServletContext的引用
5.3 启动项
Servlet默认情况下什么是创建? 默认情况下是第一次请求的时候.
如果我想让Servlet提前创建(服务器启动的时候), 这个时候就可以使用启动项 在SpringMVC里面会遇到
6、Servlet体系结构
-
Servlet接口
前面我们已经学会创建一个类实现sevlet接口的方式开发Servlet程序,实现Servlet接口的时候,我们必须实现接口的所有方法。但是,在servlet中,真正执行程序逻辑的是service,对于servlet的初始化和销毁,由服务器调用执行,开发者本身不需要关心。因此,有没有一种更加简洁的方式来开发servlet程序呢?
我们先来查阅API回顾Servlet接口:
GenericServlet 类
GenericServlet 是一个类,它简化了servlet的开发,已经提供好了一些servlet接口所需的方法,我们开发者只需要重写service方法即可
使用GenericServlet 创建servlet:
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet(name = "GenericDemoServlet",urlPatterns = "/generic")
public class GenericDemoServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("GenericDemoServlet执行.......");
}
}
GenericServlet 常用方法
HttpServlet
继承HttpServlet,我们需要重写doGet、doPost等方法中一个即可,根据Http不同的请求,我们需要实现相应的方法。
使用HttpServlet创建servlet:
@WebServlet("/demo02")
public class ServletDemo02 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("编写很多代码处理这次post请求");
}
直接在IDEA里面new Servlet时,模板
HttpServletRequest
HttpServletResponse
6.5 ServletContext
1) servletContext概述
ServletContext: 是一个全局对象, 上下文对象.
服务器为每一个应用(项目)都创建了一个ServletContext对象。 ServletContext属于整个应用(项目)的,不局限于某个Servlet。并且整个项目有且只会有一个ServletContext对象
2) ServletContext作用
作为全局的域对象在各个Servlet中进行数据的共享(掌握)
获得文件MIME类型(文件下载)(了解)
获得全局初始化参数(了解)
获取web资源路径 ,可以将Web资源转换成字节输入流(掌握)
3) servletContext常用方法
public Object getAttribute(String name)
//向ServletContext对象的map取数据
public void setAttribute(String name, Object object)
//从ServletContext对象的map中添加数据
public void removeAttribute(String name)
//根据name去移除数据
public String getMimeType(String file) //根据文件名获得文件的mime类型
public String getInitParameter(String name) //获得全局初始化参数
public Enumeration getInitParameterNames()
public String getRealPath(String path)
//为给定的虚拟路径返回一个包含真实路径的字符串(部署路径)
public InputStream getResourceAsStream(String path)
//将位于指定路径上的资源作为一个InputStream对象返回。
//path 必须以“/”开头,并被解释为相对于当前上下文根。getRealPath()方法中的path也是一样
作为域对象存取值【重点】
ServletDemo01
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
- 目标: 在ServletDemo02中获取servletDemo01中的一个变量的值
- 1. 获取ServletContext对象:
- getServletContext()
*/
@WebServlet("/demo01")
public class ServletDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = "zjl";
//1. 获取ServletContext对象
ServletContext servletContext = getServletContext();
//2. 往容器ServletContext中存值
servletContext.setAttribute("name",name);
}
}
ServletDemo02
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/demo02")
public class ServletDemo02 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获取那个容器ServletContext
ServletContext servletContext = getServletContext();
//2. 从容器ServletContext中获取数据
String name = (String) servletContext.getAttribute("name");
System.out.println("在ServletDemo02中获取的name是:" + name);
}
}
获得文件mime-type
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//根据文件名获得文件的mini类型
//1.获得ServletContext
//2.调用getMimeType()方法
String file01 = "a.mp3";
String file02 = "b.png";
String mimeType01 = getServletContext().getMimeType(file01);
String mimeType02 = getServletContext().getMimeType(file02);
response.getWriter().print("ServletDemo05..."+mimeType01+":"+mimeType02);
}
MIME Type
什么是 MIME Type?
首先,我们要了解浏览器是如何处理内容的。在浏览器中显示的内容有 HTML、有 XML、有 GIF、还有 Flash ……那么,浏览器是如何区分它们,决定什么内容用什么形式来显示呢?答案是 MIME Type,也就是该资源的媒体类型。
媒体类型通常是通过 HTTP 协议,由 Web 服务器告知浏览器的,更准确地说,是通过 Content-Type 来表示的,例如:
Content-Type: text/HTML
表示内容是 text/HTML 类型,也就是超文本文件。
Email 附件的类型也是通过 MIME Type 指定的
通常只有一些在互联网上获得广泛应用的格式才会获得一个 MIME Type,如果是某个客户端自己定义的格式,一般只能以 application/x- 开头
XHTML 格式文件的 MIME Type 应该是 application/xHTML+XML
常见的MIME类型
超文本标记语言文本 | html,.htm | text/html |
普通文本 | .txt | text/plain |
RTF文本 | .rtf | application/rtf |
GIF图形 | .gif | image/gif |
JPEG图形 | .ipeg,.jpg | image/jpeg |
au声音文件 | .au | audio/basic |
MIDI音乐文件 | mid,.midi | audio/midi,audio/x-midi |
RealAudio音乐文件 | .ra, .ram | audio/x-pn-realaudio |
MPEG文件 | .mpg,.mpeg | video/mpeg |
AVI文件 | .avi | video/x-msvideo |
GZIP文件 | .gz | application/x-gzip |
TAR文件 | .tar | application/x-tar |
mp3文件 | .mp3 | audio/mpeg |
获得全局初始化参数
在web.xml配置
通过ServletContext来获得
获取web资源路径
获取资源文件的真实路径,
直接将资源文件转换成字节输入流
- API
- String getRealPath(String path);根据资源名称得到资源的绝对路径.
- getResourceAsStream(String path) ;返回制定路径文件的流
注意: filepath:直接从项目的根目录开始写
@WebServlet("/demo04")
public class ServletDemo04 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//方法1: 使用FileInputStream,此时使用磁盘路径
//InputStream is = new FileInputStream("C:/JavaEE_Relation/web/mm.jpg");
//方法2: 使用ClassLoader将文件转换成流
//InputStream is =
//ServletDemo04.class.getClassLoader().getResourceAsStream("../../mm.jpg");
//方法3: 使用ServletContext可以获取web里面的资源的真实路径
ServletContext servletContext = getServletContext();
//String realPath = servletContext.getRealPath("mm.jpg");
//原则: 如果是将类路径(编码src下,编译classes下)下载文件转换成流使用
//类加载器的getResourceAsStream()方法
//如果是将web里面的资源转换成流就使用ServletContext的getResourceAsStream()方法
InputStream is = servletContext.getResourceAsStream("mm.jpg");
System.out.println(is);
}
}