一、什么是Servlet
Servlet是Java Web的三大组件(三大组件是Servlet、Filter和Listener),它属于动态资源。
二、实现Servlet的方式
1.实现javax.servlet.Servlet接口
2.继承javax.servlet.GenericServletlet
3.继承java.servlet.http.HttpServlet
通常情况下,我们会继承HttpServlet来完成Servlet的编写。
三、Servlet生命周期方法
Servlet类是由我们自己实现,但是Servlet对象是由服务器创建,并且由服务器调用Servlet的相应方法。Servlet是单例的,一个Servlet类只有一个对象,但是可以存在多个Servlet类。Servlet是线程 不安全的。
1.public void init(ServletConfig servletConfig):在Servlet对象被创建后调用,有且只能调用一次。
2.public void service(ServletRequest servletRequest, ServletResponse servletResponse):每次处理请求时都会调用。
3.public void destroy():在Servlet对象被销毁之前调用,只能调用一次。
四、ServletConfig接口,实现了GenericServlet接口
1.理解ServletConfig接口
一个ServletConfig接口的实现类对象就对应与web.xml中<servlet>的配置信息。其中常见的API如下所:
String getServletName(),获取<servlet-name>中的内容。
String getInitParameter(String name),通过名称获取指定的初始化参数值。
Enumeration getInitParameterNames(),获取所有的初始化参数名称值。
ServletContext getServletContext(),获取Servlet的上下文,后面会详细讲解ServletContext接口。
@Override
public void init(ServletConfig servletConfig) throws ServletException {
//获取Servlet初始化参数值
System.out.println(servletConfig.getInitParameter("param1"));
System.out.println(servletConfig.getInitParameter("param2"));
//获取Servlet所有的初始化参数名
Enumeration e = servletConfig.getInitParameterNames();
while (e.hasMoreElements()) {
System.out.println(e.nextElement());
}
}
五、ServletContext
一个完整的Java Web项目只有一个ServletContext对象,我们可以在多个Servlet类中获取这个唯一的对象,使用它个多个Servlet传递数据。ServletContext对象在Tomcat服务器启动时创建,Tomcat关闭时销毁。
1、ServletContext概述
服务器会为每一个Java Web应用创建一个ServletContext对象。
(1) ServletContext对象在服务器启动时完成创建。
(2) ServletContext对象在服务器关闭时销毁。
(3) ServletContext对象的作用是:在整个Web应用的动态资源之间共享数据。什么是共享数据?例如:在AServlet中的ServletContext保存了数据,然后可以在BServlet中获取该数据,这就是共享数据
2、获取ServletContext
(1) ServletConfig接口中getServletContext()方法。
(2) GenericServlet抽象类中的getServletContext()方法。
(3) HttpSession中的getServletContext()方法。
(4) ServletContextEvent中的getServletContext()方法,几乎用不到。
(5) 在Servlet类中如何获取ServletContext对象
>在void init(ServletConfig config)中: ServletContext context = config.getServletContext()
>在GenericServlet或者其子类HttpServlet中获取ServletContext对象:this.getServletContext()
public class MyServlet implements Servlet {
public void init(ServletConfig config) {
ServletContext context = config.getServletContext();
}
}
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
ServletContext context = this.getServletContext();
}
}
3、域对象功能
ServletContext是Java Web四大域对象之一。域对象就是用来在多个Servlet中传递数据的。所谓的四大域对象有:PageContext、ServletRequest、HttpSession和ServletContext。
所有的域对象都有存取数据的功能,因为域对象对象内部有一个Map用来存取数据的,下面是ServletContext对象用来操作数据的方法。
(1) void setAttribute(String name, Object value)
用来存储一个对象,也可以称之为存储一个域属性,例如:servletContext.setAttribute(“xxx”, “XXX”),在ServletContext中保存了一个域属性,域属性名称为xxx,域属性的值为XXX。请注意,如果多次调用该方法,并且使用相同的name,那么会覆盖上一次的值,这一特性与Map相同。
(2) Object getAttribute(String name)
用来获取ServletContext中的数据,当前在获取之前需要先去存储才行,例如:String value = (String)servletContext.getAttribute(“xxx”);获取名为xxx的域属性。
(3) void removeAttribute(String name):用来移除ServletContext中的域属性,如果参数name指定的域属性不存在,那么本方法什么都不做。
(4) Enumeration getAttributeNames():获取所有域属性的名称。
/**
* Created with IntelliJ IDEA
*
* @author SHI
* @date 2015/10/7
*/
public class BServlet extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
ServletContext context = config.getServletContext();
context.setAttribute("name","张三");
}
}
public class DServlet extends HttpServlet {
@Override
public void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println(context.getAttribute("name"));
}
}
//访问BServlet时可用获取到用户名张三。
4、 获取应用初始化参数
Servlet也可以获取初始化参数,但它是局部的参数,通过在web.xml中使用<init-param>元素进行设置。一个Servlet只能获取自己的初始化参数,不能获取别的Servlet的初始化参数。但是我们可以配置公共的初始化参数,为所有的Servlet所用。通常在web.xml中配置公共用的初始化参数,使用ServletContext来获取初始化参数。注意的是应用的初始化参数和Servlet的初始化参数是不一样的。
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<context-param>
<param-name>name1</param-name>
<param-value>Tom</param-value>
</context-param>
<context-param>
<param-name>name2</param-name>
<param-value>Kate</param-value>
</context-param>
</web-app>
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext context = this.getServletContext();
String value1 = context.getInitParameter("name1");
String value2 = context.getInitParameter("name2");
System.out.println(value1 + " " + value2);
Enumeration values = context.getInitParameterNames();//获取应用的所有初始化参数名
while(values.hasMoreElements()) {
System.out.println(values.nextElement());
}
}
六、获取资源相关的方法
(一)首先要明白开发工具IDEA开发web项目的工程目录
1、在IDEA中要明白工程project和模型module,一个project中可以有多个module,一个module就是我们实际开发中的应用项目。本例中的project就是java-web,由于该工程中只有一个module,所以该module就默认java-web。
2、一个工程project的开发目录如上图所示:
(1)out:是一个工程project中的所有模型module编译输出目录。
artifacts:IDEA部署web项目和Eclipse中部署web项目不同,IDEA中部署的web项目并没有像Eclipse中哪样,将项目部署到了tomcat的webapp目录下,而是部署到了artifacts目录中,本例中java_web_war_exploded是该module真正可执行的目录。(相当于tomcat的webapp目录下的项目)
production:存放的是类、资源文件。
(2)src:存放的是类文件。
(3)web:这是web项目的根目录,存放的是web资源。
WEB-INF:存放web项目的配置文件。
3、获取真实路径,也就是文件存储的物理路径
public class AServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
ServletContext context = this.getServletContext();
//D:\Workspace\IDEA\JD_201510\java-web\out\artifacts\java_web_war_exploded\
String path = context.getRealPath("/");
//D:\Workspace\IDEA\JD_201510\java-web\out\artifacts\java_web_war_exploded\index.jsp
path = context.getRealPath("/index.jsp");
//D:\Workspace\IDEA\JD_201510\java-web\out\artifacts\java_web_war_exploded\WEB-INF\web.xml
path = context.getRealPath("/WEB-INF/web.xml");
}
}
4、获取资源流
我们不仅仅可以获取资源的路径,还可以通过ServletContext获取资源流,即把资源以输入流的方式获取:
InputStream in = servletContext.getResourceAsStream("/index.jsp");
5、获取指定目录下的所有资源路径
//本方法必须以 / 开头!
Set<String> sets = context.getResourcePaths("/WEB-INF");
System.out.println(sets.toString());
//结果:[/WEB-INF/lib/, /WEB-INF/classes/, /WEB-INF/web.xml]
6、获取类路径下的资源
获取类路劲资源对于一个 Java Web 项目而言,就是 /WEB-INF/classes中的内容 和 /WEB-INF/lib/中的每个 jar 包, 如何获取:
(1) Class类的 getResourceAsStream(String path)
>>路径以“/”开头,相对classes路径;InputStream in = this.getClass().getResourceAsStream("/a.txt");则a.txt的真实物理路径是:D:\Workspace\IDEA\JD_201510\java-web\out\artifacts\java_web_war_exploded\WEB-INF\classes\a.txt
>>路径不以“/”开头,相对当前class文件所有路径,例如在com.jd.AServlet中执行该方法,那么相对/classes/com/jd/路径;InputStream in = this.getClass().getResourceAsStream("a.txt");则a.txt的真实路径是:
D:\Workspace\IDEA\JD_201510\java-web\out\artifacts\java_web_war_exploded\WEB-INF\classes\com\jd\a.txt
(2)ClassLoader类的 getResourceAsStream(String path):它始终是相对于classes的路径。
InputStream in = this.getClass().getClassLoader().getResourceAsStream("a.txt");
(二) maven项目的目录
1、target目录:模型module编译的输出目录。
(1)classes:类编译输出的目录
(2)web-servlet这个目录最重要。这个目录的名称命名规则是在pom.xml中有<build><finalName>web-servlet</finalName></build>指定的,如果没有指定,则默认为:<artifactId>web-servlet</artifactId>和<version>1.0-SNAPSHOT</version>构成,格式是:${artifactId}-${version};它就相当于Tomcat目录中webapp目录下的项目。
2、resources目录:保存所有的资源文件和配置文件的目录。在使用Maven2执行compile之后,这个目录中的所有文件及子目录,会复制到target/classes目录中,为以后的打包提供了方便。
Maven项目的部署后的类路劲:D:\Workspace\IDEA\JD_201510\java-web-servlet\target\web-servlet\WEB-INF\classess