当当当当~~~~欢迎大家阅读,今天我们学习JavaWeb中的三大组件(servlet)程序、(Filter)过滤器和(Listener)监听器
运行在服务器端的小程序
其实Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则。
将来我们自定义一个类,实现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() {
}
}
demo1
cn.itcast.web.servlet.ServletDemo1
demo1
/demo1
1. 当服务器接受到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径
2. 查找web.xml文件,是否有对应的标签体内容。
3. 如果有,则在找到对应的全类名
4. tomcat会将字节码文件加载进内存,并且创建其对象
5. 调用其方法
(1):默认情况下,第一次被访问时,Servlet被创建
(2):可以配置执行Servlet的创建时机。
demo1
servlet.ServletDemo1
demo1
/demo1
demo2
servlet.ServletDemo2
5
说明一个Servlet在内存中只存在一个对象,Servlet是单例的
多个用户同时访问时,可能存在线程安全问题。
解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要修改值
1:每次访问Servlet时,Service方法都会被调用一次
1:Servlet被销毁时执行。服务器关闭时,Servlet被销毁
2:只有服务器正常关闭时,才会执行destroy方法。
3:destroy方法在Servlet被销毁之前执行,一般用于释放资源
支持注解配置。可以不需要web.xml了。
1. 创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml
2. 定义一个类,实现Servlet接口
3. 复写方法
4. 在类上使用@WebServlet注解,进行配置
@WebServlet("资源路径")
Servlet -- 接口
|
GenericServlet -- 抽象类
|
HttpServlet -- 抽象类
将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......");
}
}
对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......");
}
}
(1):/xxx:路径匹配
(2):/xxx/xxx:多层路径,目录结构
(3):*.do:扩展名匹配
代表整个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
}
@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);
}
1. setAttribute(String name,Object value)
2. getAttribute(String name)
3. removeAttribute(String name)
* ServletContext对象范围:所有用户所有请求的数据
@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)过滤器~~~~
生活中的过滤器:净水器,空气净化器,土匪
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() {
}
}
demo1
filter.FilterDemo1
demo1
/*
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...");
}
}
@WebFilter("/index.jsp") //1.具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
@WebFilter("/user/*") //2.拦截目录: /user/*访问/user下的所有资源时,过滤器都会被执行
@WebFilter("*.jsp") //3. 后缀名拦截: *.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行
@WebFilter("/*") //4. 拦截所有资源: /* 访问所有资源时,过滤器都会被执行
注解配置
设置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配置
设置
标签即可
1. 过滤器1
2. 过滤器2
3. 资源执行
4. 过滤器2
5. 过滤器1
举例:doFilter...
filterDemo6执行了...
filterDemo7执行了...
index.jsp...
filterDem7回来了...
filterDem6回来了...
1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
如: AFilter 和 BFilter,AFilter就先执行了。
2. web.xml配置:
谁定义在上边,谁先执行
1. 真实对象:被代理的对象
2. 代理对象:
3. 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的
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();
}
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)监听器~~~~
事件 :一件事情
事件源 :事件发生的地方
监听器 :一个对象
注册监听:将事件、事件源、监听器绑定在一起。 当事件源上发生某个事件后,执行监听器代码
void contextDestroyed(ServletContextEvent sce) :ServletContext对象被销毁之前会调用该方法
void contextInitialized(ServletContextEvent sce) :ServletContext对象创建后会调用该方法
1. 定义一个类,实现ServletContextListener接口
2. 复写方法
3. 配置
listener.ContextLoaderListener
contextConfigLocation
/WEB-INF/classes/applicationContext.xml
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的内容啦,希望我的文章对你有所帮助,如果有错误的地方还望大家批评指正,谢谢大家阅读!