JavaWeb学习-监听器
创始人
2024-04-13 08:36:50

什么是监听器?

类似于前端的事件绑定,java中的监听器用于监听web应用中某些对象、信息的创建、销毁、增加,修改,删除等动作的发生,然后作出相应的响应处理。当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。常用于统计在线人数和在线用户,系统加载时进行信息初始化,统计网站的访问量等等。

监听器怎么分类?

按监听的对象划分

  • a.ServletContext对象监听器
  • b.HttpSession对象监听器
  • c.ServletRequest对象监听器

按监听的事件划分

  • a.对象自身的创建和销毁的监听器
  • b.对象中属性的创建和消除的监听器
  • c.session中的某个对象的状态变化的监听器

一共有哪些监听器?分别处理的是什么事情?

java中一共给我们提供了八个监听器接口,分别用于监听三个域对象,每个监听器都有专门监听的事件

Request 

  1. ServletRequestListener           (处理request对象创建和销毁)
  2. ServleRequestAttributeListener   (处理域对象中的数据添加 替换 删除)

Session

  1. HttpSessionListener              (处理session对象创建和销毁)
  2. HttpSessionAttributeListener      (处理session域对象中的数据添加 修改 删除)
  3. HttpSessionBindingListener       (处理session对象监听器绑定和解绑定接口)
  4. HttpSessionActivationListener     (处理session对象钝化和活化状态接口)

Application 

  1. ServletContextListener            (处理application对象创建和销毁)
  2. ServletContextAttributeListener   (处理application域对象中的数据添加 修改 删除)

监听器如何使用?

两步走使用

  • 1定义监听器,根据需求实现对应接口
  • 2在web.xml中配置监听器,让监听器工作

接下来我们就挨个认识一下每个监听器及内部方法的作用

一 Requet域监听器

Requet域共有两个监听器接口,分别是

ServletRequestListener 

ServleRequestAttributeListener

接下来我们就认识一些每个接口和接口中每个方法的用处

定义监听器类

package com.msb.listener;
import javax.servlet.*;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
public class MyRequestListener implements ServletRequestListener, ServletRequestAttributeListener {@Overridepublic void requestDestroyed(ServletRequestEvent sre) {// 监听HttpServletRequest对象的销毁  项目中任何一个Request对象的销毁都会触发该方法的执行ServletRequest servletRequest = sre.getServletRequest();System.out.println("request"+servletRequest.hashCode()+"对象销毁了");}@Overridepublic void requestInitialized(ServletRequestEvent sre) {// 监听HttpServletRequest对象的创建并初始化 项目中任何一个Request对象的创建并初始化都会触发该方法的执行ServletRequest servletRequest = sre.getServletRequest();System.out.println("request"+servletRequest.hashCode()+"对象初始化");}@Overridepublic void attributeAdded(ServletRequestAttributeEvent srae) {// 任何一个Request对象中调用 setAttribute方法增加了数据都会触发该方法ServletRequest servletRequest = srae.getServletRequest();String name = srae.getName();Object value = srae.getValue();System.out.println("request"+servletRequest.hashCode()+"对象增加了数据:"+name+"="+value);}@Overridepublic void attributeRemoved(ServletRequestAttributeEvent srae) {// 任何一个Request对象中调用 removeAttribute方法移除了数据都会触发该方法ServletRequest servletRequest = srae.getServletRequest();String name = srae.getName();Object value = srae.getValue();System.out.println("request"+servletRequest.hashCode()+"对象删除了数据:"+name+"="+value);}@Overridepublic void attributeReplaced(ServletRequestAttributeEvent srae) {// 任何一个Request对象中调用 setAttribute方法修改了数据都会触发该方法ServletRequest servletRequest = srae.getServletRequest();String name = srae.getName();Object value = srae.getValue();Object newValue=servletRequest.getAttribute(name);System.out.println("request"+servletRequest.hashCode()+"对象增修改了数据:"+name+"="+value+"设置为:"+newValue);}
}

 配置监听器  使用web.xml 或者通过@WebListener注解都可以


com.msb.listener.MyRequestListener

准备Servlet

@WebServlet(urlPatterns = "/myServlet3.do")
public class MyServlet3 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setAttribute("name", "zhangsan");req.setAttribute("name", "lisi");req.removeAttribute("name");}
}

二  Session域监听器

Session域共有四个监听器接口,分别是

HttpSessionListener
HttpSessionAttributeListener
HttpSessionBindingListener
HttpSessionActivationListener

接下来我们就认识一些每个接口和接口中每个方法的用处

监听器代码

HttpSessionListener
HttpSessionAttributeListener

package com.msb.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebListener
public class MySessionListener implements HttpSessionListener , HttpSessionAttributeListener {@Overridepublic void sessionCreated(HttpSessionEvent se) {System.out.println("任何一个Session对象创建");}@Overridepublic void sessionDestroyed(HttpSessionEvent se) {System.out.println("任何一个Session对象的销毁");}@Overridepublic void attributeAdded(HttpSessionBindingEvent se) {System.out.println("任何一个Session对象中添加了数据");}@Overridepublic void attributeRemoved(HttpSessionBindingEvent se) {System.out.println("任何一个Session对象中移除了数据");}@Overridepublic void attributeReplaced(HttpSessionBindingEvent se) {System.out.println("任何一个Session对象中修改了数据");}
}

HttpSessionBindingListener

package com.msb.listener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
/*
* 可以监听具体的某个session对象的事件的
*
* HttpSessionListener 只要在web.xml中配置或者通过@WebListener注解就可以注册监听所有的Session对象
* HttpSessionBindingListener 必须要通过setAttribute方法和某个session对象绑定之后,监听单独的某个Session对象
* */
public class MySessionBindingListener implements HttpSessionBindingListener {// 绑定方法/*session.setAttribute("mySessionBindingListener",new MySessionBindingListener())*/@Overridepublic void valueBound(HttpSessionBindingEvent event) {System.out.println("监听器和某个session对象绑定了");}// 解除绑定方法/** 当发生如下情况,会触发该方法的运行* 1 session.invalidate(); 让session不可用* 2 session到达最大不活动时间,session对象回收 ;* 3 session.removeAttribute("mySessionBindingListener");手动解除绑定* */@Overridepublic void valueUnbound(HttpSessionBindingEvent event) {}
}

HttpSessionActivationListener

package com.msb.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/public class MySessionActivationListener implements HttpSessionActivationListener {@Overridepublic void sessionWillPassivate(HttpSessionEvent se) {System.out.println("session即将钝化");}@Overridepublic void sessionDidActivate(HttpSessionEvent se) {System.out.println("session活化完毕");}
}

三  Application监听器

Application域共有两个监听器接口,分别是

ServletContextListener
ServletContextAttributeListener

接下来我们就认识一些每个接口和接口中每个方法的用处

监听器代码

package com.msb.listener;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
public class MyApplicationListener implements ServletContextListener , ServletContextAttributeListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("ServletContext创建并初始化了");}@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("ServletContext销毁了");}@Overridepublic void attributeAdded(ServletContextAttributeEvent scae) {System.out.println("ServletContext增加了数据");}@Overridepublic void attributeRemoved(ServletContextAttributeEvent scae) {System.out.println("ServletContext删除了数据");}@Overridepublic void attributeReplaced(ServletContextAttributeEvent scae) {System.out.println("ServletContext修改了数据");}
}

案例:

1.需求:记录每次请求中如下的信息并存储进入日志文件请求的来源

  • 浏览器所在电脑IP
  • 请求的资源 URL 
  • 请求发生的时间 

监听器代码

package com.msb.listener;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebListener
public class RequestLogListener implements ServletRequestListener {private SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");@Overridepublic void requestDestroyed(ServletRequestEvent sre) {}@Overridepublic void requestInitialized(ServletRequestEvent sre) {// 获得请求发出的IP// 获得请求的URL// 获得请求产生的时间HttpServletRequest request = (HttpServletRequest)sre.getServletRequest();String remoteHost = request.getRemoteHost();String requestURL = request.getRequestURL().toString();String reqquestDate = simpleDateFormat.format(new Date());// 准备输出流try {PrintWriter pw =new PrintWriter(new FileOutputStream(new File("d:/msb.txt"),true));pw.println(remoteHost+" "+requestURL+" "+reqquestDate );pw.close();} catch (FileNotFoundException e) {e.printStackTrace();}}
}

2.需求:

1当任何一个账户处于登录状态时,在线统计总数+1,离线时-1

2通过session监听器实现计数,但是在线人数要保存在Application域中

准备监听器

package com.msb.listener;
import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebListener
public class OnLineNumberListener implements HttpSessionListener  {@Overridepublic void sessionCreated(HttpSessionEvent se) {// 向application域中 增加一个数字HttpSession session = se.getSession();ServletContext application = session.getServletContext();Object attribute = application.getAttribute("count");if(null == attribute){// 第一次放数据application.setAttribute("count", 1);}else{int count =(int)attribute;application.setAttribute("count", ++count);}}@Overridepublic void sessionDestroyed(HttpSessionEvent se) {// 向application域中 减少一个数字HttpSession session = se.getSession();ServletContext application = session.getServletContext();int count =(int)application.getAttribute("count");application.setAttribute("count", --count);}
}

 准备销毁监听的servlet

package com.msb.servlet;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebServlet(urlPatterns = "/logout.do")
public class Logout extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HttpSession session = req.getSession();session.invalidate();}
}

index.jsp
 


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title%sSourceCode%lt;/title></head><body>当前在线人数为:${applicationScope.count}</body>
</html>
</code></pre> 
<p><strong>3.项目重启免登录</strong></p> 
<p>Session序列化和反序列化</p> 
<blockquote> <p>1、序列化与反序列</p> <p>把对象转化为字节序列的过程称为序列化(保存到硬盘,持久化)</p> <p>把字节序列转化为对象的过程称为反序列化(存放于内存)</p> <p> 2、序列化的用途</p> <p>把对象的字节序列永久保存到硬盘上,通常放到一个文件中。</p> <p>把网络传输的对象通过字节序列化,方便传输本节作业</p> 
</blockquote> 
<p>3、实现步骤</p> 
<p>     要想实现序列化和反序列化需要手动配置</p> 
<p> A、新建文件如图所示:</p> 
<p><img alt="" height="99" src="https://files.pic99.top/yuhaojiang/202404/17e9399ebe49e6f.png" width="306" /> </p> 
<p> B、 Context.xml中文件如下</p> 
<pre><code class="language-XML"><?xml version="1.0" encoding="UTF-8"?><Context><Manager className="org.apache.catalina.session.PersistentManager"><Store className="org.apache.catalina.session.FileStore" directory="d:/session"/></Manager></Context></code></pre> 
<p>C、注意实体类必须实现serializable 接口</p> 
<p><strong>开发过程</strong></p> 
<p>1 准备实体类</p> 
<pre><code class="language-java">package com.msb.pojo;
import java.io.Serializable;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
public class User  implements Serializable {private String username;private String pwd;
</code></pre> 
<p>2.开发登录信息输入页面</p> 
<pre><code class="language-html"><%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html><head><title>$Title%sSourceCode%lt;/title></head><body><form action="loginController.do" method="post">用户名:<input type="text" name="user"> <br/>密码:<input type="password" name="pwd"><br/><input type="submit" value="提交"></form></body>
</html></code></pre> 
<p>3开发登录信息验证Servlet</p> 
<pre><code class="language-java">package com.msb.controller;
import com.msb.listener.MySessionActivationListener;
import com.msb.pojo.User;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebServlet("/loginController.do")
public class LoginController extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username = req.getParameter("user");String pwd = req.getParameter("pwd");// userUser user =new User(username,pwd);// sessionHttpSession session = req.getSession();session.setAttribute("user", user);}
}
</code></pre> 
<p>4 开发校验当前是否已经登录的Controller</p> 
<pre><code class="language-java">package com.msb.controller;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
@WebServlet(urlPatterns = "/loginCheckController.do")
public class LoginCheckController extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 判断是否登录HttpSession session = req.getSession();Object user = session.getAttribute("user");Object listener = session.getAttribute("listener");// 获得对应的监听器String message ="";if(null != user){message="您已经登录过";}else{message="您还未登录";}resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html;charset=UTF-8");resp.getWriter().println(message);}
}</code></pre> 
<p>5测试, 先登录,然后请求loginCheckController.do 校验是否登录过,然后重启项目,再起请求loginCheckController.do 校验是否登录过,发现重启后,仍然是登录过的</p> 
<p><br /> 6监听钝化和活化</p> 
<p>准备监听器</p> 
<pre><code class="language-java">package com.msb.listener;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionEvent;
import java.io.Serializable;
/*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/
public class MySessionActivationListener implements HttpSessionActivationListener, Serializable {@Overridepublic void sessionWillPassivate(HttpSessionEvent se) {System.out.println(se.getSession().hashCode()+"即将钝化");}@Overridepublic void sessionDidActivate(HttpSessionEvent se) {System.out.println(se.getSession().hashCode()+"已经活化");}
}
</code></pre> 
<p>登录时绑定监听器</p> 
<pre><code class="language-java">@WebServlet("/loginController.do")
public class LoginController extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username = req.getParameter("user");String pwd = req.getParameter("pwd");// userUser user =new User(username,pwd);// sessionHttpSession session = req.getSession();session.setAttribute("user", user);// 绑定监听器session.setAttribute("listener", new MySessionActivationListener());}
}
</code></pre> 
<p>重启项目 重复测试即可</p>                <!--end::Text-->
            </div>
            <!--end::Description-->
            <div class="mt-5">
                <!--关键词搜索-->
               
            </div>
            <div class="mt-5">
                <p class="fc-show-prev-next">
                    <strong>上一篇:</strong><a href="/xuexi/185330.html">读《信息传》总结——决定我们未来发展的方法论</a><br>
                </p>
                <p class="fc-show-prev-next">
                    <strong>下一篇:</strong><a href="/xuexi/185332.html">遥感技术及高分遥感影像在地震中的应用及高分二号获取</a>                </p>
            </div>
            <!--begin::Block-->
            <div class="d-flex flex-stack mb-2 mt-10">
                <!--begin::Title-->
                <h3 class="text-dark fs-5 fw-bold text-gray-800">相关内容</h3>
                <!--end::Title-->
            </div>
            <div class="separator separator-dashed mb-9"></div>
            <!--end::Block-->
            <div class="row g-10">
                 

            </div>


        </div>
        <!--end::Table widget 14-->
    </div>
    <!--end::Col-->

    <!--begin::Col-->
    <div class="col-xl-4 mt-0">
        <!--begin::Chart Widget 35-->
        <div class="card card-flush h-md-100">
            <!--begin::Header-->
            <div class="card-header pt-5 ">
                <!--begin::Title-->
                <h3 class="card-title align-items-start flex-column">
                    <!--begin::Statistics-->
                    <div class="d-flex align-items-center mb-2">
                        <!--begin::Currency-->
                        <span class="fs-5 fw-bold text-gray-800 ">热门资讯</span>
                        <!--end::Currency-->
                    </div>
                    <!--end::Statistics-->
                </h3>
                <!--end::Title-->
            </div>
            <!--end::Header-->
            <!--begin::Body-->
            <div class="card-body pt-3">

                                <!--begin::Item-->
                <div class="d-flex flex-stack mb-7">
                    <!--begin::Symbol-->
                    
                    <!--end::Symbol-->
                    <!--begin::Title-->
                    <div class="m-0">
                        <a href="/redian/1476181.html" class="text-dark fw-bold text-hover-primary fs-6">经济学家建议最低工资增长跟GD...</a>
                        <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">来源:@第一财经日报微博																							#经济学家建议最低工资每年都提...</span>
                    </div>
                    <!--end::Title-->
                </div>
                                <!--begin::Item-->
                <div class="d-flex flex-stack mb-7">
                    <!--begin::Symbol-->
                    
                    <!--end::Symbol-->
                    <!--begin::Title-->
                    <div class="m-0">
                        <a href="/redian/1476180.html" class="text-dark fw-bold text-hover-primary fs-6">广发证券2026年次级债(第一...</a>
                        <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">中访网数据  中诚信国际信用评级有限责任公司于2026年1月12日发布评级报告,评定广发证券股份有限...</span>
                    </div>
                    <!--end::Title-->
                </div>
                                <!--begin::Item-->
                <div class="d-flex flex-stack mb-7">
                    <!--begin::Symbol-->
                    
                    <!--end::Symbol-->
                    <!--begin::Title-->
                    <div class="m-0">
                        <a href="/redian/1476179.html" class="text-dark fw-bold text-hover-primary fs-6">五矿发展(600058.SH)...</a>
                        <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">五矿发展(600058.SH)发布公告,公司拟以原有业务相关的主要资产及负债(除保留资产、负债外)与...</span>
                    </div>
                    <!--end::Title-->
                </div>
                                <!--begin::Item-->
                <div class="d-flex flex-stack mb-7">
                    <!--begin::Symbol-->
                    
                    <!--end::Symbol-->
                    <!--begin::Title-->
                    <div class="m-0">
                        <a href="/redian/1476178.html" class="text-dark fw-bold text-hover-primary fs-6">泓博医药股价异常波动,公司提示...</a>
                        <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">中访网数据  上海泓博智源医药股份有限公司(股票代码:301230,简称:泓博医药)于2026年1月...</span>
                    </div>
                    <!--end::Title-->
                </div>
                                <!--begin::Item-->
                <div class="d-flex flex-stack mb-7">
                    <!--begin::Symbol-->
                    
                    <!--end::Symbol-->
                    <!--begin::Title-->
                    <div class="m-0">
                        <a href="/xuexi/1476177.html" class="text-dark fw-bold text-hover-primary fs-6">歪歪YY和游戏里骂人的话不带脏...</a>
                        <span class="text-gray-600 fw-semibold d-block pt-1 fs-7">你有人的外表,却只有猪的智商。你就是一个猥琐且智力低下的生物。你瞅瞅你的脸都在天上飞了。你真是个笨蛋...</span>
                    </div>
                    <!--end::Title-->
                </div>
                
            </div>
            <!--end::Body-->
        </div>
        <!--end::Chart Widget 35-->
    </div>
    <!--end::Col-->
</div>



</div>
<!--end::Content container-->
</div>
<!--end::Content-->
</div>
<!--end::Content wrapper-->
<!--begin::Footer-->
<div id="kt_app_footer" class="app-footer">
    <!--begin::Footer container-->
    <div class="app-container container-xxl d-flex flex-column flex-md-row flex-center flex-md-stack py-3">
        <!--begin::Copyright-->
        <div class="text-dark order-2 order-md-1">
            <span class="text-muted fw-semibold me-1">2026 ©</span>
            浩江知识网<a href="http://www.hfjzjc.com/">汇飞网</a><a href="http://www.hhfamen.cn/">发门网</a><a href="http://www.bitekongjian.com/">比特空间</a><a href="http://www.xingshan.vip">星闪网</a><a href="http://www.taiyangwa.net/">太阳生活网</a><a href="http://www.nengyuan100.com/">能源</a><a href="http://spbjmm.com.shayuweb.com">上品网</a><a href="http://www.zzdfzj.cn/">东方游戏网</a><a href="http://www.80hlw.com/">八零商务网</a><a href="http://www.kthtea.cn/">太和茶叶网</a><a href="http://yule.yuhaojiang.com/">浩江娱乐网</a>        </div>
        <!--end::Copyright-->
        <!--begin::Menu-->
        <ul class="menu menu-gray-600 menu-hover-primary fw-semibold order-1">
                        <li class="menu-item">
                <a href="/news/" target="_blank" class="menu-link px-2">知识</a>
            </li>
                        <li class="menu-item">
                <a href="/changshi/" target="_blank" class="menu-link px-2">常识</a>
            </li>
                        <li class="menu-item">
                <a href="/xuexi/" target="_blank" class="menu-link px-2">学习</a>
            </li>
                        <li class="menu-item">
                <a href="/redian/" target="_blank" class="menu-link px-2">热点</a>
            </li>
                        <li class="menu-item">
                <a href="/wenxue/" target="_blank" class="menu-link px-2">文学</a>
            </li>
                    </ul>
        <!--end::Menu-->
    </div>
    <!--end::Footer container-->
</div>
<!--end::Footer-->
</div>
<!--end:::Main-->
</div>
<!--end::Wrapper-->
</div>
<!--end::Page-->
</div>
<!--end::App-->
<div id="kt_scrolltop" class="scrolltop" data-kt-scrolltop="true">
    <!--begin::Svg Icon | path: icons/duotune/arrows/arr066.svg-->
    <span class="svg-icon">
        <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
            <rect opacity="0.5" x="13" y="6" width="13" height="2" rx="1" transform="rotate(90 13 6)" fill="currentColor"></rect>
            <path d="M12.5657 8.56569L16.75 12.75C17.1642 13.1642 17.8358 13.1642 18.25 12.75C18.6642 12.3358 18.6642 11.6642 18.25 11.25L12.7071 5.70711C12.3166 5.31658 11.6834 5.31658 11.2929 5.70711L5.75 11.25C5.33579 11.6642 5.33579 12.3358 5.75 12.75C6.16421 13.1642 6.83579 13.1642 7.25 12.75L11.4343 8.56569C11.7467 8.25327 12.2533 8.25327 12.5657 8.56569Z" fill="currentColor"></path>
        </svg>
    </span>
    <!--end::Svg Icon-->
</div>
<!--begin::Javascript-->
<script>var hostUrl = "/static/default/pc/";</script>
<!--begin::Global Javascript Bundle(mandatory for all pages)-->
<script src="/static/default/pc/plugins/global/plugins.bundle.js"></script>
<script src="/static/default/pc/js/scripts.bundle.js"></script>
<!--end::Global Javascript Bundle-->

<!--end::Javascript-->
</body>
<!--end::Body-->
</html>