当当当当~~~~欢迎大家阅读,今天我们学习JavaWeb中的三大组件(servlet)程序、(Filter)过滤器和(Listener)监听器
servlet程序
一:概念
运行在服务器端的小程序
其实Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。
将来我们自定义一个类,实现Servlet接口,复写方法。
二:快速入门
(一):创建JavaEE项目
(二):定义一个类,实现Servlet接口
public class ServletDemo1 implements Servlet{}
(三):实现接口中的抽象方法
@WebServlet("/demo")
public class ServletDemo implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("servlet3.0来了......");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
(四):配置Servlet:在web.xml中配置
<!--配置Servlet -->
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>cn.itcast.web.servlet.ServletDemo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
三:执行原理
1. 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
2. 查找web.xml文件,是否有对应的<url-pattern>标签体内容。
3. 如果有,则在找到对应的<servlet-class>全类名
4. tomcat会将字节码文件加载进内存,并且创建其对象
5. 调用其方法
四:Servlet中的生命周期方法
(一):被创建:执行init方法,只执行一次
1:Servlet什么时候被创建?
(1):默认情况下,第一次被访问时,Servlet被创建
(2):可以配置执行Servlet的创建时机。
<!--配置Servlet-->
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>servlet.ServletDemo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
<!--配置Servlet-->
<servlet>
<servlet-name>demo2</servlet-name>
<servlet-class>servlet.ServletDemo2</servlet-class>
<!--指定Servlet的创建时机
1.第一次被访问时创建
<load-on-startup>的值为负数
2.在服务器启动时创建
<load-on-startup>的值为0或正整数-->
<load-on-startup>5</load-on-startup>
</servlet>
2:Servlet的init方法,只执行一次
说明一个Servlet在内存中只存在一个对象,Servlet是单例的
多个用户同时访问时,可能存在线程安全问题。
解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要修改值
(二):提供服务:执行service方法,执行多次
1:每次访问Servlet时,Service方法都会被调用一次
(三):被销毁:执行destroy方法,只执行一次
1:Servlet被销毁时执行。服务器关闭时,Servlet被销毁
2:只有服务器正常关闭时,才会执行destroy方法。
3:destroy方法在Servlet被销毁之前执行,一般用于释放资源
五:Servlet3.0
(一):好处
支持注解配置。可以不需要web.xml了。
(二):步骤
1. 创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml
2. 定义一个类,实现Servlet接口
3. 复写方法
4. 在类上使用@WebServlet注解,进行配置
@WebServlet("资源路径")
六:Servlet的体系结构
Servlet -- 接口
|
GenericServlet -- 抽象类
|
HttpServlet -- 抽象类
(一):GenericServlet
将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象
将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可
public class ServletDemo2 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("demo2......");
}
}
(二):HttpServlet
对http协议的一种封装,简化操作
1. 定义类继承HttpServlet
2. 复写doGet/doPost方法
@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet......");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost......");
}
}
七:Servlet相关配置
(一):urlpartten:Servlet访问路径
1:一个Servlet可以定义多个访问路径 : @WebServlet({"/d4","/dd4","/ddd4"})
2:路径定义规则
(1):/xxx:路径匹配
(2):/xxx/xxx:多层路径,目录结构
(3):*.do:扩展名匹配
八:ServletContext对象
(一):概念
代表整个web应用,可以和程序的容器(服务器)来通信
(二):获取
@WebServlet("/servletContextDemo1")
public class ServletContextDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
* ServletContext对象获取:
* 1.通过request对象获取
* request.getServletContext();
* 2.通过HttpServlet获取
* this.getServletContext();
*/
//1.通过request对象获取
ServletContext context1 = request.getServletContext();
//2.通过HttpServlet获取
ServletContext context2 = this.getServletContext();
System.out.println(context1);
System.out.println(context2);
System.out.println(context1 == context2);//true
}
(三):功能
1. 获取MIME类型
@WebServlet("/servletContextDemo2")
public class ServletContextDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
获取MIME类型
MIME类型:在互联网通信过程中定义的一种文件数据类型
格式: 大类型/小类型 text/html image/jpeg
获取:String getMimeType(String file)
*/
//1.通过HttpServlet对象获取
ServletContext context = this.getServletContext();
//2.定义文件名称
String filename="a.jpg";//image/jpeg
//3.获取MIME类型
String mimeType = context.getMimeType(filename);
System.out.println(mimeType);
}
2. 域对象:共享数据
1. setAttribute(String name,Object value)
2. getAttribute(String name)
3. removeAttribute(String name)
* ServletContext对象范围:所有用户所有请求的数据
3. 获取文件的真实(服务器)路径
@WebServlet("/servletContextDemo4")
public class ServletContextDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
1.获取MIME类型
2.域对象:共享数据
3.获取文件的真实(服务器)路径
*/
//1.通过HttpServlet对象获取
ServletContext context = this.getServletContext();
//获取文件的服务器路径
String realPath = context.getRealPath("/b.txt");//web目录下的资源访问
File file=new File(realPath);
String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
System.out.println(c);
String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问
System.out.println(a);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
(servlet)程序的讲解到这里就结束啦,接下来我们看(!Filter)过滤器~~~~
Filter:过滤器
一:概念
生活中的过滤器:净水器,空气净化器,土匪
web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。
二:过滤器的作用
一般用于完成通用的操作。如:登录验证、统一编码处理、敏感字符过滤等...
三:快速入门
(一):步骤
1. 定义一个类,实现接口Filter
2. 复写方法
3. 配置拦截路径
1. web.xml
2. 注解
(二):代码
@WebFilter("/*")//访问所有资源之前,都会执行该过滤器
public class FilterDemo1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//放行
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
四:过滤器细节
(一):web.xml配置
<filter>
<filter-name>demo1</filter-name>
<filter-class>filter.FilterDemo1</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(二):过滤器执行流程
1. 执行过滤器
2. 执行放行后的资源
3. 回来执行过滤器放行代码下边的代码
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//对request对象请求消息增强
System.out.println("filterDemo2执行了...");
//放行
chain.doFilter(req, resp);
//对response对象的响应消息增强
System.out.println("filterDemo2回来了...");
}
(三):过滤器生命周期方法
1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
2. doFilter:每一次请求被拦截资源时,会执行。执行多次
3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源
@WebFilter("/*")
public class FilterDemo3 implements Filter {
/*
*@Description:在服务器启动后,会创建Filter对象,然后调用init方法
*@param:config
*@return:ServletException
*/
public void init(FilterConfig config) throws ServletException {
System.out.println("init...");
}
/*
*@Description:每一次请求被拦截资源时,会执行
*@param:req
*@return:
*/
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
System.out.println("doFilter...");
chain.doFilter(req, resp);
}
/*
*@Description:在服务器关闭后,Filter对象被销毁,如果服务器是正常关闭,则会执行destroy方法
*@param:
*@return:
*/
public void destroy() {
System.out.println("destroy...");
}
}
(四):过滤器配置详解
1:拦截路径配置
@WebFilter("/index.jsp") //1.具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
@WebFilter("/user/*") //2.拦截目录: /user/*访问/user下的所有资源时,过滤器都会被执行
@WebFilter("*.jsp") //3. 后缀名拦截: *.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
@WebFilter("/*") //4. 拦截所有资源: /* 访问所有资源时,过滤器都会被执行
2:拦截方式配置:资源被访问的方式
注解配置
设置dispatcherTypes属性
1. REQUEST:默认值。浏览器直接请求资源
2. FORWARD:转发访问资源
3. INCLUDE:包含访问资源
4. ERROR:错误跳转资源
5. ASYNC:异步访问资源
//浏览器直接请求资源时,该过滤器会被执行
@WebFilter(value="/index.jsp",dispatcherTypes = DispatcherType.REQUEST)
//只有转发访问index.jsp时,该过滤器才会被执行
@WebFilter(value="/index.jsp",dispatcherTypes = DispatcherType.FORWARD)
//浏览器直接请求资源,转发访问index.jsp时,该过滤器都会被执行
@WebFilter(value = "/*",dispatcherTypes = {DispatcherType.FORWARD,DispatcherType.REQUEST})
web.xml配置
设置<dispatcher></dispatcher>标签即可
(五):过滤器链(配置多个过滤器)
1:执行顺序:如果有两个过滤器:过滤器1和过滤器2
1. 过滤器1
2. 过滤器2
3. 资源执行
4. 过滤器2
5. 过滤器1
举例:doFilter...
filterDemo6执行了...
filterDemo7执行了...
index.jsp...
filterDem7回来了...
filterDem6回来了...
2:过滤器先后顺序问题
1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
如: AFilter 和 BFilter,AFilter就先执行了。
2. web.xml配置: <filter-mapping>谁定义在上边,谁先执行
代理设计模式:增强对象的功能
一:概念
1. 真实对象:被代理的对象
2. 代理对象:
3. 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的
二:实现方式
(一):静态代理:有一个类文件描述代理模式
(二):动态代理:在内存中形成代理类
1:实现步骤
1. 代理对象和真实对象实现相同的接口
2. 代理对象 = Proxy.newProxyInstance();
3. 使用代理对象调用方法。
4. 增强方法
举例:联想电脑的代理
先创建一个真实对象,再在接口中声明代理对象和真实对象需要实现的方法,让代理对象和真实对象实现相同的接口
public class Lenovo implements SaleComputer {
@Override
public String sale(double money) {
System.out.println("花了"+money+"元买了一台联想电脑...");
return "联想电脑";
}
@Override
public void show() {
System.out.println("展示电脑...");
}
}
public interface SaleComputer {
public String sale(double money);
public void show();
}
2:增强方式
1. 增强参数列表
2. 增强返回值类型
3. 增强方法体执行逻辑
public class ProxyTest {
public static void main(String[] args) {
//1:创建真实对象
Lenovo lenovo=new Lenovo();
//2:动态代理增强Lenovo对象
/*
* 三个参数
* 1:类加载器:真实对象.getClass().getClassLoader()
* 2:接口数组:真实对象.getClass().getInterfaces()
* 3:处理器:new InvocationHandler()
*/
SaleComputer proxy_lenovo= (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
/*
* 代理逻辑编写的方法:代理对象调用的所有方法都会触发该方法执行
* 参数:
* 1:proxy:代理对象
* 2:method:代理对象调用的方法,被封装为的对象
* 3:args:代理对象调用方法时,传递的实际参数*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/* System.out.println("该方法执行了...");
System.out.println(method.getName());
System.out.println(args[0]);*/
//方式一:增强参数
//判断是否时sale方法
if(method.getName().equals("sale")){
//1.增强参数
double money= (double) args[0];
money=money*0.85;
System.out.println("专车接你...");
//使用真实对象调用该方法
String obj = (String) method.invoke(lenovo, money);
System.out.println("免费送货...");
//2.增强返回值
return obj+"_鼠标垫";
}else{
Object obj = method.invoke(lenovo, args);
return obj;
}
}
});
//3:调用方法
/* String computer = lenovo.sale(8000);
System.out.println(computer);*/
proxy_lenovo.show();
}
}
(Filter)过滤器的讲解到这里就结束啦,接下来我们看(Listener)监听器~~~~
Listener:监听器
一: 概念
(一):事件监听机制
事件 :一件事情
事件源 :事件发生的地方
监听器 :一个对象
注册监听:将事件、事件源、监听器绑定在一起。 当事件源上发生某个事件后,执行监听器代码
(二):ServletContextListener:监听ServletContext对象的创建和销毁
1:方法
void contextDestroyed(ServletContextEvent sce) :ServletContext对象被销毁之前会调用该方法
void contextInitialized(ServletContextEvent sce) :ServletContext对象创建后会调用该方法
2:步骤
1. 定义一个类,实现ServletContextListener接口
2. 复写方法
3. 配置
3:web.xml配置
<!--配置监听器-->
<listener>
<listener-class>listener.ContextLoaderListener</listener-class>
</listener>
<!--指定初始化参数-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
4:监听器的代码实现
public class ContextLoaderListener implements ServletContextListener {
/*
* 监听ServletContext对象创建的,ServletContext对象服务器启动后自动创建
* 在服务器启动后自动调用*/
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
//加载资源文件
//1.获取ServletContext对象
ServletContext servletContext = servletContextEvent.getServletContext();
//2.加载资源文件
String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
//3.获取真实路径
String realPath = servletContext.getRealPath(contextConfigLocation);
//4.加载进内存
try{
FileInputStream fis=new FileInputStream(realPath);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("ServletContext对象被创建了...");
}
/*
* 在服务器关闭后,ServletContext对象被销毁,当服务器正常关闭后该方法被调用*/
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象被销毁了...");
}
}
以上就是Servlet & Filter & Listener的内容啦,希望我的文章对你有所帮助,如果有错误的地方还望大家批评指正,谢谢大家阅读!