- 工程结构
- build.gradle
plugins {
id 'java'
}
group 'com.github.xfl12345'
version '1.0-SNAPSHOT'
// source code URL=https://www.cnblogs.com/guohaoblog/p/13282891.html
repositories {
mavenLocal()
// 身为开发者,必备番茄工具,所以我并不必须配置成国内源
// maven {
url = 'http://nexus.vfinance.cn:9081/content/groups/public/'
// url = 'http://maven.aliyun.com/nexus/content/groups/public/'
// }
mavenCentral()
}
dependencies {
def springVersion = '5.3.6'
def log4jVersion = '2.14.1'
def slf4jVersion = '1.7.30'
def org_apache_poi_version = '5.0.0'
def javaMailVersion = '1.6.2'
testImplementation group: 'junit', name: 'junit', version: '4.12'
// JSON support
// https://mvnrepository.com/artifact/com.alibaba/fastjson
implementation group: 'com.alibaba', name: 'fastjson', version: '1.2.76'
// https://mvnrepository.com/artifact/com.google.code.gson/gson
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.3'
// Ant support
// https://mvnrepository.com/artifact/org.apache.ant/ant
implementation group: 'org.apache.ant', name: 'ant', version: '1.10.9'
// util collections
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.11'
// XML support
// https://mvnrepository.com/artifact/org.jsoup/jsoup
implementation group: 'org.jsoup', name: 'jsoup', version: '1.13.1'
// https://mvnrepository.com/artifact/org.dom4j/dom4j
implementation group: 'org.dom4j', name: 'dom4j', version: '2.1.3'
// HTML support
// https://mvnrepository.com/artifact/com.j2html/j2html
implementation group: 'com.j2html', name: 'j2html', version: '1.4.0'
// UUID generator support
// https://mvnrepository.com/artifact/com.fasterxml.uuid/java-uuid-generator
implementation group: 'com.fasterxml.uuid', name: 'java-uuid-generator', version: '4.0.1'
// https://mvnrepository.com/artifact/mysql/mysql-connector-java
implementation group: 'mysql', name: 'mysql-connector-java', version: '5.1.49'
// MyBatis
// https://mvnrepository.com/artifact/org.mybatis/mybatis
implementation group: 'org.mybatis', name: 'mybatis', version: '3.5.7'
// https://mvnrepository.com/artifact/org.mybatis/mybatis-spring
implementation group: 'org.mybatis', name: 'mybatis-spring', version: '2.0.6'
// https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core
implementation group: 'org.mybatis.generator', name: 'mybatis-generator-core', version: '1.4.0'
// https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-maven-plugin
// implementation group: 'org.mybatis.generator', name: 'mybatis-generator-maven-plugin', version: '1.4.0'
// Spring and SpringMVC
// https://mvnrepository.com/artifact/org.springframework/spring-core
// implementation group: 'org.springframework', name: 'spring-core', version: springVersion
// https://mvnrepository.com/artifact/org.springframework/spring-context
// implementation group: 'org.springframework', name: 'spring-context', version: springVersion
// https://mvnrepository.com/artifact/org.springframework/spring-webmvc
implementation group: 'org.springframework', name: 'spring-webmvc', version: springVersion
// https://mvnrepository.com/artifact/org.springframework/spring-jdbc
implementation group: 'org.springframework', name: 'spring-jdbc', version: springVersion
// poi
// https://mvnrepository.com/artifact/org.apache.poi/poi
implementation group: 'org.apache.poi', name: 'poi', version: org_apache_poi_version
// https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-full
implementation group: 'org.apache.poi', name: 'poi-ooxml-full', version: org_apache_poi_version
// https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml
implementation group: 'org.apache.poi', name: 'poi-ooxml', version: org_apache_poi_version
// https://mvnrepository.com/artifact/org.apache.xmlbeans/xmlbeans
implementation group: 'org.apache.xmlbeans', name: 'xmlbeans', version: org_apache_poi_version
// Java Email support
// https://mvnrepository.com/artifact/com.sun.mail/javax.mail
implementation group: 'com.sun.mail', name: 'javax.mail', version: javaMailVersion
// https://mvnrepository.com/artifact/javax.mail/javax.mail-api
implementation group: 'javax.mail', name: 'javax.mail-api', version: javaMailVersion
// Java Log framework - slf4j log4j2
// https://mvnrepository.com/artifact/org.slf4j/slf4j-nop
implementation group: 'org.slf4j', name: 'slf4j-nop', version: slf4jVersion
// https://mvnrepository.com/artifact/org.slf4j/slf4j-api
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
// https://mvnrepository.com/artifact/org.slf4j/slf4j-ext
implementation group: 'org.slf4j', name: 'slf4j-ext', version: slf4jVersion
// https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl
implementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: log4jVersion
// https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core
implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: log4jVersion
// https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-web
implementation group: 'org.apache.logging.log4j', name: 'log4j-web', version: log4jVersion
// https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api
implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: log4jVersion
// solution from URL=https://blog.csdn.net/weixin_42697074/article/details/88084565
// https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-jcl
implementation group: 'org.apache.logging.log4j', name: 'log4j-jcl', version: log4jVersion
// JSP support
implementation fileTree(dir:'lib',includes:['*jar'])
// https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api
// implementation group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
}
- web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<display-name>jsp_netdisk</display-name>
<!-- log4j2-begin-->
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>classpath:log4j2.xml</param-value>
</context-param>
<!--动态修改log4j2.xml:容器会每60秒扫描log4j的配置文件-->
<!-- <context-param>-->
<!-- <param-name>log4jRefreshInterval</param-name>-->
<!-- <param-value>60000</param-value>-->
<!-- </context-param>-->
<!--监听器和过滤器-->
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<!-- log4j2-end -->
<!-- Spring begin -->
<!-- 初始化Spring 容器作为root容器-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application_context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring end -->
<!-- SpringMVC begin -->
<!-- 配置springmvc DispatcherServlet SpringMVC核心分发器-->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring_servlet.xml</param-value>
</init-param>
<!-- 启动级别 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- SpringMVC end -->
<!-- 编码过滤器 UTF-8-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 设置session失效,时间单位:分钟 minute -->
<session-config>
<!-- 暂时设置为 1 分钟,用以快速测试 -->
<session-timeout>1</session-timeout>
</session-config>
</web-app>
- log4j2.xml (log4j2 的XML配置文件,必须叫这名,不能花里胡哨)
<?xml version="1.0" encoding="UTF-8"?>
<!-- source code URL= https://blog.csdn.net/zeal9s/article/details/86078097 -->
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!-- monitorInterval:指定log4j自动重新配置的监测间隔时间 -->
<configuration status="INFO" monitorInterval="1">
<!-- 变量配置 应该是日志文件保存路径-->
<Properties>
<!-- (*必须,各应用需要修改) 部署应用的名称,命名规则 :全部小写字母、中短横线、数字,与微服务命名,disconf中命名一致 -->
<property name="APPNAME">jsp_netdisk</property>
<!-- (各应用需要修改)日志文件本地存放目录路径 建议各个环境跟生产环境统一起来,方便维护 -->
<!--sys:catalina.home tomcat的根目录-->
<Property name="logBaseFolder">${sys:catalina.home}/logs/jsp_netdisk/</Property>
<!-- *必须并强制遵守 日志文件的编码 -->
<property name="log_charset">UTF-8</property>
<!--输出日志格式-->
<property name="log_pattern">
%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n
</property>
</Properties>
<!--先定义所有的appender-->
<appenders>
<!--这个输出控制台的配置-->
<console name="Console" target="SYSTEM_OUT" ignoreExceptions="false">
<!--输出日志的格式 %l :表示某个类-->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%t] %-5p %c{1}:%L - %msg%n"/>
</console>
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${logBaseFolder}/${APPNAME}-info.log"
filePattern="${logBaseFolder}/%d{yyyy-MM}/${APPNAME}-info-%d{dd_HH_mm_ss}.%i.log.gz">
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<!-- 日志输出格式 -->
<PatternLayout charset="${log_charset}" pattern="${log_pattern}" />
<!-- 以下是日志压缩包目录的建议格式名称 建议1天归档依次,压缩文件上线建议为200,这里预估每个磁盘存储空间200G左右,每个压缩包最大值200MB -->
<Policies>
<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
</RollingFile>
<RollingFile name="RollingFileError" fileName="${logBaseFolder}/${APPNAME}-error.log"
filePattern="${logBaseFolder}/%d{yyyy-MM}/${APPNAME}-error-%d{dd_HH_mm_ss}.%i.log.gz">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout charset="${log_charset}" pattern="${log_pattern}" />
<Policies>
<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
</RollingFile>
</appenders>
<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
<loggers>
<!-- source code URL=https://blog.csdn.net/zwj1030711290/article/details/114133986 -->
<!--监控系统信息-->
<!--若是additivity设为false,则 子Logger 只会在自己的appender里输出,而不会在 父Logger 的appender里输出。-->
<!-- 过滤掉spring和mybatis的一些信息,输出到配置的一个或多个AppenderRef中-->
<logger name="org.springframework" level="INFO" additivity="false">
<appender-ref ref="Console" />
</logger>
<logger name="org.mybatis" level="INFO" additivity="false">
<appender-ref ref="Console" />
</logger>
<!-- source code URL=https://blog.csdn.net/qq_41741884/article/details/103012745 -->
<!--配置输出sql语句-->
<!-- <logger name="org.apache.ibatis" level="DEBUG"/>-->
<!-- <logger name="java.sql.Connection" level="DEBUG"/>-->
<!-- <logger name="java.sql.Statement" level="DEBUG"/>-->
<!-- <logger name="java.sql.PreparedStatement" level="DEBUG"/>-->
<!-- name属性可以是包名或者是具体的全限定类名 -->
<!-- 这里只针对MyBatis mapper xml文件里映射的dao接口做DEBUG级别日志记录,输出sql语句。如果不是DEBUG级别,将无法打印sql语句-->
<logger name="com.github.xfl12345.jsp_netdisk.model.dao" level="DEBUG"/>
<logger name="com.github.xfl12345.jsp_netdisk" level="INFO"/>
<root level="ALL">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFileInfo"/>
<appender-ref ref="RollingFileError"/>
</root>
</loggers>
</configuration>
- empty_mybatis_conf.xml (MyBatis的XML配置文件)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 用于输出日志 log4j:LOG4J SLF4J -->
<settings>
<!-- <setting name="logImpl" value="LOG4J2"/>-->
<setting name="logImpl" value="SLF4J"/>
</settings>
</configuration>
- application_context.xml (Spring 框架的XML配置文件)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解驱动 -->
<context:annotation-config/>
<!-- 优先加载Listener,不放过任何event。自动扫描listener包下的所有类 -->
<context:component-scan base-package="com.github.xfl12345.jsp_netdisk.model.listener"/>
<!-- 无限套娃 之 加载所有配置文件的相对路径 -->
<context:property-placeholder ignore-unresolvable="false" location="classpath:all_properties_path.properties"/>
<!-- 无限套娃 之 加载Spring工具类 -->
<bean id="staticSpringApp" class="com.github.xfl12345.jsp_netdisk.StaticSpringApp" lazy-init="false"/>
<!-- 各种Listener -->
<!-- 监听 Spring Context 实例化事件,这是个工具类 -->
<bean id="mySpringApplicationStartListener"
class="com.github.xfl12345.jsp_netdisk.model.listener.MySpringApplicationStartListener" lazy-init="true"/>
<!--解决JDBC驱动卸载问题-->
<bean id="contextFinalizer" class="com.github.xfl12345.jsp_netdisk.model.utils.jdbc.ContextFinalizer"
lazy-init="true"/>
<!--监听session触发事件,实现超时自动注销登录 -->
<bean id="mySessionEventListener" class="com.github.xfl12345.jsp_netdisk.model.listener.MySessionEventListener"
lazy-init="true"/>
<!-- 各种工具类 -->
<!-- 读取properties文件 的 工具类 -->
<bean id="propertiesUtils" class="com.github.xfl12345.jsp_netdisk.model.utils.PropertiesUtils" lazy-init="false"/>
<!-- Java反射机制 的 工具类 -->
<bean id="myReflectUtils" class="com.github.xfl12345.jsp_netdisk.model.utils.MyReflectUtils" lazy-init="false"/>
<!-- UUID生成器 -->
<bean id="uuidGenerator" class="com.fasterxml.uuid.Generators"/>
<!-- 需调用函数才能预加载、完成初始化任务的,都写在里面 -->
<bean id="preloadSingleton" class="com.github.xfl12345.jsp_netdisk.model.PreLoad" lazy-init="false"/>
<!-- 通过继承PooledDataSource类,对父类进行增强,实现了全自动初始化数据库 -->
<bean id="dataSource" class="com.github.xfl12345.jsp_netdisk.model.utils.jdbc.MyDataSource" lazy-init="false">
<constructor-arg index="0" value="${db_init_sql_file_relative_path}"/>
<constructor-arg index="1" value="${db_restart_init_sql_file_relative_path}"/>
<constructor-arg index="2" value="${db_url_base_parameter_file_relative_path}"/>
<constructor-arg index="3" value="${db_url_additional_parameter_file_relative_path}"/>
</bean>
<!--MyBatis SQLSessionFactory -->
<!-- spring和MyBatis完美整合 -->
<!-- source code URL=https://blog.csdn.net/qq_33840251/article/details/89814071 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" lazy-init="false">
<!-- 指定数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 具体指定 mybatis-config.xml 文件,可不配 -->
<property name="configLocation" value="classpath:mybatis/empty_mybatis_conf.xml"/>
<!-- 自动扫描mapping.xml文件,**表示迭代查找 ,,也可在mybatis-config.xml中单独指定xml文件 -->
<!-- 配置单个xml文件 -->
<!--<property name="mapperLocations" value="classpath:com/yaosiyuan/dao/xml/MsMerchantMapper.xml"/> -->
<!-- 配置多个xml文件 -->
<property name="mapperLocations">
<list>
<value>classpath:mybatis/mappings/**.xml</value>
</list>
</property>
</bean>
<!-- Mybatis MapperScannerConfigurer 自动扫描 将Mapper接口生成代理注入到Spring -->
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.github.xfl12345.jsp_netdisk.model.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<!--事务配置-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 发邮件 的 服务类, 这个服务类不免费,需要JavaEE的包 -->
<bean id="emailService" class="com.github.xfl12345.jsp_netdisk.model.service.EmailService" lazy-init="true">
<constructor-arg index="0" value="${email_properties_file_relative_path}"/>
</bean>
<!-- 加载邮件模板 -->
<bean id="verificationEmailTemplate"
class="com.github.xfl12345.jsp_netdisk.model.pojo.html.VerificationEmailTemplate" lazy-init="true">
<constructor-arg index="0" value="staticVerificationEmail.html"/>
</bean>
<!-- 自动扫描service包下的所有类 -->
<context:component-scan base-package="com.github.xfl12345.jsp_netdisk.model.service"/>
<!-- <context:component-scan base-package="com.github.xfl12345.jsp_netdisk" />-->
<!-- <bean id="/login" name="login" class="LoginStatusController" />-->
</beans>
- spring_servlet.xml (SpringMVC 的XML配置文件)
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 自动扫描controller包下的所有类-->
<context:component-scan base-package="com.github.xfl12345.jsp_netdisk.controller" />
<!--视图解析器-->
<beans:bean id="resourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/"/>
<beans:property name="suffix" value=".jsp"/>
<!-- <beans:property name="order" value="0"/>-->
</beans:bean>
<mvc:default-servlet-handler/>
<!-- 静态文件-->
<mvc:resources mapping="/static/**" location="/static/"/>
<mvc:resources mapping="/html/**" location="/html/"/>
<!-- <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />-->
<!-- <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />-->
<!--注解驱动,以使得访问路径与方法的匹配可以通过注解配置-->
<!-- json 配置-->
<mvc:annotation-driven >
<mvc:message-converters>
<beans:bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
<beans:property name="supportedMediaTypes">
<beans:list>
<beans:value>text/html;charset=UTF-8</beans:value>
<beans:value>application/json;charset=UTF-8</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="mappingJackson2HttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<beans:property name="supportedMediaTypes">
<beans:list>
<beans:value>text/html;charset=UTF-8</beans:value>
<beans:value>application/json;charset=UTF-8</beans:value>
</beans:list>
</beans:property>
</beans:bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- <bean id="/login" name="login" class="com.github.xfl12345.jsp_netdisk.controller.LoginController" />-->
<!--上传文件配置-->
<!-- <beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">-->
<!-- <beans:property name="maxUploadSize" value="1024000000"/>-->
<!-- </beans:bean>-->
<!--其他 拦截器配置等-->
</beans:beans>
- MySessionEventListener.java (这是一个Session监听类,里面包含了slf4j的最简单的使用)
package com.github.xfl12345.jsp_netdisk.model.listener;
import com.github.xfl12345.jsp_netdisk.StaticSpringApp;
import com.github.xfl12345.jsp_netdisk.appconst.field.SessionAttributes;
import com.github.xfl12345.jsp_netdisk.model.service.TbAccountService;
import com.github.xfl12345.jsp_netdisk.model.utils.MyStrIsOK;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener
public class MySessionEventListener implements HttpSessionListener {
private final Logger logger = LoggerFactory.getLogger(MySessionEventListener.class);
// 当用户与服务器之间开始session时触发该方法
public void sessionCreated(HttpSessionEvent se)
{
// logger.info("diy listener:sessionCreated");
//TO DO SOMETHING
}
// 当用户与服务器之间session断开时触发该方法
public void sessionDestroyed(HttpSessionEvent se)
{
HttpSession session = se.getSession();
// ServletContext application = session.getServletContext();
String accountIdStr = (String) session.getAttribute(SessionAttributes.ACCOUNT_ID);
if(MyStrIsOK.isNotEmpty(accountIdStr)){
long accountId = Long.parseLong(accountIdStr);
TbAccountService tbAccountService = StaticSpringApp.getBean(TbAccountService.class);
tbAccountService.logoutByAccountId(accountId);
logger.info("accountId="+accountId+",session expire.Auto log out successful.");
}
}
}
- 运行结果
07-May-2021 01:14:55.918 信息 [RMI TCP Connection(32)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/E:/Data/project/tmp/jsp_netdisk/out/artifacts/jsp_netdisk_main_Web_exploded/WEB-INF/lib/log4j-slf4j-impl-2.14.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/E:/Data/project/tmp/jsp_netdisk/out/artifacts/jsp_netdisk_main_Web_exploded/WEB-INF/lib/slf4j-nop-1.7.30.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
[01:14:58:653] [RMI TCP Connection(32)-127.0.0.1] INFO ContextLoader:271 - Root WebApplicationContext: initialization started
[01:15:00:494] [RMI TCP Connection(32)-127.0.0.1] DEBUG LogFactory:105 - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
[01:15:00:797] [RMI TCP Connection(32)-127.0.0.1] INFO MyDataSource:99 - Temporary JDBC URL=jdbc:mysql://localhost:3306/information_schema?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&characterSetResults=utf8
[01:15:01:320] [RMI TCP Connection(32)-127.0.0.1] DEBUG PooledDataSource:434 - Created connection 792247129.
[01:15:01:321] [RMI TCP Connection(32)-127.0.0.1] INFO MyDataSource:104 - Database server connected.Checking database.
[01:15:01:327] [RMI TCP Connection(32)-127.0.0.1] INFO MyDataSource:108 - select * from information_schema.SCHEMATA where SCHEMA_NAME = 'jsp_netdisk'
[01:15:01:332] [RMI TCP Connection(32)-127.0.0.1] INFO MyDataSource:111 - Database is exist!Initiation will process.
[01:15:01:370] [RMI TCP Connection(32)-127.0.0.1] DEBUG PooledDataSource:391 - Returned connection 792247129 to pool.
[01:15:01:370] [RMI TCP Connection(32)-127.0.0.1] INFO MyDataSource:117 - Database initiated!
[01:15:01:370] [RMI TCP Connection(32)-127.0.0.1] DEBUG PooledDataSource:407 - A bad connection (792247129) attempted to return to the pool, discarding connection.
[01:15:01:370] [RMI TCP Connection(32)-127.0.0.1] INFO MyDataSource:119 - Final JDBC URL=jdbc:mysql://localhost:3306/jsp_netdisk?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&characterSetResults=utf8
[01:15:01:371] [RMI TCP Connection(32)-127.0.0.1] DEBUG PooledDataSource:363 - PooledDataSource forcefully closed/removed all connections.
[01:15:01:371] [RMI TCP Connection(32)-127.0.0.1] DEBUG PooledDataSource:363 - PooledDataSource forcefully closed/removed all connections.
[01:15:01:371] [RMI TCP Connection(32)-127.0.0.1] DEBUG PooledDataSource:363 - PooledDataSource forcefully closed/removed all connections.
[01:15:01:371] [RMI TCP Connection(32)-127.0.0.1] DEBUG PooledDataSource:363 - PooledDataSource forcefully closed/removed all connections.
[01:15:01:372] [RMI TCP Connection(32)-127.0.0.1] DEBUG PooledDataSource:363 - PooledDataSource forcefully closed/removed all connections.
[01:15:01:372] [RMI TCP Connection(32)-127.0.0.1] INFO MyDataSource:64 - Mybatis datasource ready!
PreLoad loaded.
[01:15:02:456] [RMI TCP Connection(32)-127.0.0.1] DEBUG LogFactory:105 - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
我的父容器为:null
初始化时我被调用了。
[01:15:03:561] [RMI TCP Connection(32)-127.0.0.1] INFO ContextLoader:307 - Root WebApplicationContext initialized in 4870 ms
[01:15:03:679] [RMI TCP Connection(32)-127.0.0.1] INFO DispatcherServlet:525 - Initializing Servlet 'springMVC'
我的父容器为:Root WebApplicationContext, started on Fri May 07 01:14:58 CST 2021
初始化时我被调用了。
[01:15:06:668] [RMI TCP Connection(32)-127.0.0.1] INFO DispatcherServlet:547 - Completed initialization in 2987 ms
[2021-05-07 01:15:07,184] Artifact jsp_netdisk.main:Web exploded: Artifact is deployed successfully
[2021-05-07 01:15:07,184] Artifact jsp_netdisk.main:Web exploded: Deploy took 25,282 milliseconds
[01:15:44:234] [http-nio-8080-exec-43] DEBUG PooledDataSource:434 - Created connection 1270645277.
[01:15:44:243] [http-nio-8080-exec-43] DEBUG queryValidationInformationByUsername:137 - ==> Preparing: select account_id, username, password_hash, password_salt, account_status from jsp_netdisk.tb_account where username = ?
[01:15:44:286] [http-nio-8080-exec-43] DEBUG queryValidationInformationByUsername:137 - ==> Parameters: root(String)
[01:15:44:307] [http-nio-8080-exec-43] DEBUG queryValidationInformationByUsername:137 - <== Total: 1
[01:15:44:312] [http-nio-8080-exec-43] DEBUG PooledDataSource:391 - Returned connection 1270645277 to pool.
[01:15:44:338] [http-nio-8080-exec-43] DEBUG PooledDataSource:426 - Checked out connection 1270645277 from pool.
[01:15:44:338] [http-nio-8080-exec-43] DEBUG insert:137 - ==> Preparing: insert into jsp_netdisk.account_session(account_id, session_id) values (?, ?)
[01:15:44:338] [http-nio-8080-exec-43] DEBUG insert:137 - ==> Parameters: 1(Long), 23E9A9BB2A680D14DFBF5AB86C456941(String)
[01:15:44:351] [http-nio-8080-exec-43] DEBUG insert:137 - <== Updates: 1
[01:15:44:352] [http-nio-8080-exec-43] DEBUG PooledDataSource:391 - Returned connection 1270645277 to pool.
[01:16:59:800] [Catalina-utility-1] DEBUG PooledDataSource:426 - Checked out connection 1270645277 from pool.
[01:16:59:800] [Catalina-utility-1] DEBUG deleteByAccountId:137 - ==> Preparing: delete from jsp_netdisk.account_session where account_id = ?
[01:16:59:801] [Catalina-utility-1] DEBUG deleteByAccountId:137 - ==> Parameters: 1(Long)
[01:16:59:806] [Catalina-utility-1] DEBUG deleteByAccountId:137 - <== Updates: 1
[01:16:59:806] [Catalina-utility-1] DEBUG PooledDataSource:391 - Returned connection 1270645277 to pool.
[01:16:59:806] [Catalina-utility-1] INFO MySessionEventListener:38 - accountId=1,session expire.Auto log out successful.
看,最后一行日志:
[01:16:59:806] [Catalina-utility-1] INFO MySessionEventListener:38 - accountId=1,session expire.Auto log out successful.
足见slf4j + log4j2 的组合日志框架是正常运行的。
- 写在最后
想要maven版的依赖代码的,可以直接访问gradle相关依赖上面的URL来获取。
比如这个:
// https://mvnrepository.com/artifact/org.mybatis/mybatis
implementation group: 'org.mybatis', name: 'mybatis', version: '3.5.5'
访问 https://mvnrepository.com/artifact/org.mybatis/mybatis 就可以找到maven依赖的代码:
很多原理、源码出处,都在代码里有标注。(诸如“source code URL”这样的字眼)
我知道会有人问原理,但我也不知道。。主要是没时间,我要赶毕设 ,逃……