Spring 5 + Spring MVC 5 + MyBatis 3 的 Maven 项目集成

xiaoxiao2022-06-03  67

相关链接:

MyEclipse CI 2018.9.0 配置 Apache Maven 3.5.4

在MyEclipse CI 2018.9.0 中使用 Maven 3.5.4 创建Maven项目

在MyEclipse中使用SVN提交(自动忽略 .settings .project .classpath等)、检出(无.settings .project .classpath文件等)Maven代码


配置Maven请查看:MyEclipse CI 2018.9.0 配置 Apache Maven 3.5.4  新建Maven项目请查看:在MyEclipse CI 2018.9.0 中使用 Maven 3.5.4 创建Maven项目  新建项目配置:

Dynamic Web Module

4.0

Java

1.8

JavaScript

1.0

JSTL Libraries

1.2.4

MyEclipse Server Library

Apache Tomcat v9.0

项目结构预览:  配置pom.xml: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>net.csdn</groupId> <artifactId></artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name></name> <!-- 阿里云maven代码库 --> <repositories> <repository> <id>aliyun</id> <name>aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </repository> </repositories> <!-- 阿里云maven代码库 --> <properties> <!-- Spring框架jar包版本 --> <!-- 2018年7月26日 5.0.8.RELEASE 截止2018-09-06为最新版 --> <spring.version>5.0.8.RELEASE</spring.version> <!-- 启用@AspectJ支持 --> <!-- 2018年4月20日 1.9.1 截止2018-09-06为最新版 --> <aspectjweaver.version>1.9.1</aspectjweaver.version> <!-- mchange c3p0 --> <!-- 2015年12月9日 0.9.5.2 截止2018-09-06为最新版 --> <c3p0.version>0.9.5.2</c3p0.version> <!-- 2018年2月2日 0.2.15 截止2018-09-06为最新版 --> <mchange-commons.version>0.2.15</mchange-commons.version> <!-- mchange c3p0 --> <!-- MyBatis --> <!-- 2018年3月11日 3.4.6 截止2018-09-06为最新版 --> <mybatis.version>3.4.6</mybatis.version> <!-- MyBatis整合Spring中间件jar包 --> <!-- 2018年3月14日 1.3.2 截止2018-09-06为最新版 --> <mybatis-spring.version>1.3.2</mybatis-spring.version> <!-- mysql 数据库驱动 --> <!-- 2018年6月28日 8.0.12 截止2018-09-06为最新版 --> <mysql-connector.version>8.0.12</mysql-connector.version> <!-- log4j2 --> <!-- 2018年7月30日 2.11.1 截止2018-09-06为最新版 --> <log4j2.version>2.11.1</log4j2.version> <!-- slf4j --> <!-- 2017年3月16日 1.7.25 截止2018-09-06为最新版 --> <slf4j.version>1.7.25</slf4j.version> <!-- commons-lang3 --> <!-- 2018年8月16日 3.8 截止2018-09-06为最新版 --> <!-- 工具类 --> <commons-lang3.version>3.8</commons-lang3.version> <!-- commons-text --> <!-- 工具类 --> <!-- 2018年6月9日 截止2018-09-06为最新版 --> <commons-text.version>1.4</commons-text.version> <!-- springfox --> <!-- 2018年6月23日 2.9.2 截止2018-09-06为最新版 --> <springfox-swagger2.version>2.9.2</springfox-swagger2.version> <!-- javax/servlet/jsp/jstl/core/Config --> <!-- 2006年5月12日 1.2 --> <jstl.version>1.2</jstl.version> <!-- jetty-webapp --> <!-- 2018年8月30日 9.4.12.v20180830 截止2018-09-06为最新版 --> <jetty-webapp.version>9.4.12.v20180830</jetty-webapp.version> <!-- gson --> <!-- 2018年5月22日 2.8.5 截止2018-09-06为最新版 --> <gson.version>2.8.5</gson.version> <!-- json --> <!-- 还需要commons-lang,已被引入 --> <commons-beanutils.version>1.9.3</commons-beanutils.version> <commons-collections.version>3.2.2</commons-collections.version> <commons-logging.version>1.2</commons-logging.version> <ezmorph.version>1.0.6</ezmorph.version> <json.version>2.4</json.version> <!-- github验证码 --> <patchca.version>0.0.1</patchca.version> </properties> <dependencies> <!-- ++++++++++++++++++++++++++++++ spring、spring mvc ++++++++++++++++++++ --> <!-- spring 视图解析器 5.0.8.RELEASE --> <!-- 相关依赖(自动引入5.0.8.RELEASE): spring-aop-、spring-beans-、spring-context-、spring-core-、spring-expression-、spring-jcl-、spring-web- --> <!-- 同spring-websocket --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- spring JDBC事务管理器 5.0.8.RELEASE --> <!-- 相关依赖(自动引入5.0.8.RELEASE):spring-beans、spring-core、spring-jcl、spring-tx --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <!-- 相关依赖(自动引入5.0.8.RELEASE):spring-aop、spring-beans、spring-context、spring-core、spring-expression、spring-jcl、spring-web、 --> <!-- 同spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>${spring.version}</version> </dependency> <!-- 相关依赖(自动引入5.0.8.RELEASE):spring-beans-、spring-core-、spring-jcl- --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>${spring.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ aspectjweaver ++++++++++++++++++++ --> <!-- aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${aspectjweaver.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ c3p0 ++++++++++++++++++++ --> <!-- c3p0 --> <!-- mchange c3p0 0.9.5.2 --> <!-- 相关依赖(自动引入0.2.11):mchange-commons-java- --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>${c3p0.version}</version> </dependency> <!-- mchange commons --> <dependency> <groupId>com.mchange</groupId> <artifactId>mchange-commons-java</artifactId> <version>${mchange-commons.version}</version> </dependency> <!-- c3p0 --> <!-- ++++++++++++++++++++++++++++++ mybatis ++++++++++++++++++++ --> <!-- MyBatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ mybatis-spring ++++++++++++++++++++ --> <!-- MyBatis整合Spring中间件jar包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${mybatis-spring.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ mysql ++++++++++++++++++++ --> <!-- mysql 数据库驱动 8.0.12 --> <!-- 相关依赖(自动引入2.6.0):protobuf-java- --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-connector.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ log4j2 ++++++++++++++++++++ --> <!-- log4j2 2.11.1 --> <!-- 相关依赖(自动引入2.11.1):log4j-core、log4j-api --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-web</artifactId> <version>${log4j2.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ slf4j ++++++++++++++++++++ --> <!-- slf4j --> <!-- 相关依赖(自动引入1.2.17):log4j- --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ commons-lang3 ++++++++++++++++++++ --> <!-- commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commons-lang3.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ commons-text ++++++++++++++++++++ --> <!-- commons-text --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-text</artifactId> <version>${commons-text.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ springfox ++++++++++++++++++++ --> <!-- springfox --> <!-- 2018年6月23日 --> <!-- aopalliance-1.0.jar --> <!-- byte-buddy-1.8.12.jar --> <!-- classmate-1.4.0.jar --> <!-- guava-20.0.jar --> <!-- jackson-annotations-2.9.5.jar --> <!-- mapstruct-1.2.0.Final.jar --> <!-- slf4j-api-1.7.25.jar --> <!-- 版本4.0.9.RELEASE:spring-aop-、spring-beans-、spring-context-、spring-core-、spring-expression- --> <!-- 版本2.9.2:springfox-core-、springfox-schema-、springfox-spi-、springfox-spring-web-、springfox-swagger2- 、springfox-swagger-common- --> <!-- 版本1.2.0.RELEASE:spring-plugin-core-、spring-plugin-metadata- --> <!-- 版本1.5.20:swagger-annotations-、 swagger-models- --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${springfox-swagger2.version}</version> </dependency> <!-- aopalliance-1.0.jar --> <!-- byte-buddy-1.8.12.jar --> <!-- guava-20.0.jar --> <!-- slf4j-api-1.7.25.jar --> <!-- 版本4.0.9.RELEASE:spring-aop-、spring-beans-、spring-context-、spring-core-、spring-expression- --> <!-- 版本2.9.2:springfox-core-、springfox-spi-、springfox-spring-web- --> <!-- 版本1.2.0.RELEASE:spring-plugin-core-、spring-plugin-metadata- --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${springfox-swagger2.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ jstl ++++++++++++++++++++ --> <!-- javax/servlet/jsp/jstl/core/Config --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ jetty-webapp ++++++++++++++++++++ --> <!-- --> <!-- javax.servlet-api-3.1.0.jar --> <!-- 版本9.4.12.v20180830:jetty-http-、jetty-io-、jetty-security-、jetty-server-、jetty-servlet-、jetty-util-、jetty-xml- --> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-webapp</artifactId> <version>${jetty-webapp.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ gson ++++++++++++++++++++ --> <!-- gson --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>${gson.version}</version> </dependency> <!-- ++++++++++++++++++++++++++++++ json ++++++++++++++++++++ --> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>${commons-beanutils.version}</version> </dependency> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>${commons-collections.version}</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>${commons-logging.version}</version> </dependency> <dependency> <groupId>net.sf.ezmorph</groupId> <artifactId>ezmorph</artifactId> <version>${ezmorph.version}</version> </dependency> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>${json.version}</version> <classifier>jdk15</classifier> </dependency> <!-- ++++++++++++++++++++++++++++++ github验证码 ++++++++++++++++++++ --> <dependency> <groupId>com.github.bingoohuang</groupId> <artifactId>patchca</artifactId> <version>${patchca.version}</version> </dependency> <!-- <dependency> <groupId>net.pusuo</groupId> <artifactId>patchca</artifactId> <version>0.5.0</version> </dependency> --> <!-- ++++++++++++++++++++++++++++++ ++++++++++++++++++++ --> </dependencies> <build> <plugins> <!-- 配置Tomcat插件 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <port>80</port> <path>/</path> <url>http://192.168.1.100:80/manager/text</url> <username>tomcat</username> <password>tomcat</password> </configuration> </plugin> <!-- 配置Tomcat插件 --> <!-- 默认 jdk 1.8 --> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <!-- 默认 jdk 1.8 --> </plugins> </build> </project> 配置web.xml: <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0"> <display-name></display-name> <!-- 方便的Web应用程序的ApplicationContext实例化 --> <!-- 参见:https://docs.spring.io/spring/docs/5.0.8.RELEASE/spring-framework-reference/core.html#context-create --> <!-- 参见:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-servlet --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 方便的Web应用程序的ApplicationContext实例化 --> <!-- DispatcherServlet --> <!-- 定义Spring MVC的前端控制器 --> <!-- 参见:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-servlet --> <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-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- 让Spring MVC的前端控制器拦截所有请求 --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 静态资源不拦截 --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> <url-pattern>*.css</url-pattern> <url-pattern>*.gif</url-pattern> <url-pattern>*.jpg</url-pattern> <url-pattern>*.png</url-pattern> <url-pattern>*.ico</url-pattern> <url-pattern>*.mp3</url-pattern> <url-pattern>*.woff</url-pattern> <url-pattern>*.json</url-pattern> </servlet-mapping> <!-- DispatcherServlet --> <!-- log4j2配置 --> <!-- 参见:http://logging.apache.org/log4j/2.x/manual/webapp.html --> <context-param> <param-name>log4jConfiguration</param-name> <param-value>classpath:log4j2.xml</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> <!-- <dispatcher>ASYNC</dispatcher> --> <!-- Servlet 3.0仅禁用自动初始化; 2.5不支持 --> </filter-mapping> <!-- github验证码 --> <!-- 直接访问http://127.0.0.1//validImg.jpg即可得到验证码,不受SSM控制 --> <servlet> <servlet-name>ValidCode</servlet-name> <servlet-class>net.csdn.servlet.ValidCode</servlet-class> </servlet> <servlet-mapping> <servlet-name>ValidCode</servlet-name> <url-pattern>/validImg.jpg</url-pattern> </servlet-mapping> <!-- 404页面 --> <!-- <error-page> <error-code>404</error-code> <location>/WEB-INF/error/404.html</location> </error-page> --> <!-- 500页面 --> <!-- <error-page> <error-code>500</error-code> <location>/WEB-INF/error/500.html</location> </error-page> --> <!-- <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> --> </web-app> 配置jdbc.properties: # 在mysql-connector-java-8.0.12中已经被启用 com.mysql.jdbc.Driver # 在mysql-connector-java-8.0.12中使用 com.mysql.cj.jdbc.Driver # useSSL\=false 不验证SSL # serverTimezone\=GMT+8 设置时区为东8区 dataSource.driverClass=com.mysql.cj.jdbc.Driver dataSource.jdbcUrl=jdbc\:mysql\://127.0.0.1\:3306/csdn?useSSL\=false&serverTimezone\=GMT+8 dataSource.user=root dataSource.password=root dataSource.maxPoolSize=20 dataSource.maxIdleTime = 1000 dataSource.minPoolSize=5 dataSource.initialPoolSize=5 配置log4j.properties: log4j.rootLogger=info,stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=[\u65F6\u95F4\:%d{yyyy-MM-dd hh\:mm\:ss}] [\u7EA7\u522B\:%p] [\u7C7B\:%c] [\u6D88\u606F\:%m] %n #log4j.logger.com.ibatis=debug #log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug #log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug #log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug #log4j.logger.java.sql.Connection=debug #log4j.logger.java.sql.Statement=debug #log4j.logger.java.sql.PreparedStatement=debug,stdout # Spring Stuff #log4j.logger.org.springframework=INFO #log4j.logger.org.springframework.oxm=INFO #log4j.logger.org.springframework.web=debug log4j.logger.net.csdn.aop.aspect.SystemLogAspect=debug 配置log4j2.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE xml> <Configuration status="OFF" monitorInterval="1800"> <properties> <!-- log打印到本地的路径 --> <property name="LOG_HOME">/log4j2/mybatis/genertor/logs/</property> <property name="ERROR_LOG_FILE_NAME">error</property> </properties> <Appenders> <!-- 控制台打印日志 --> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d %-5p (%F:%L) - %m%n" /> </Console> <!-- 日志信息输出到文件配置 --> <RollingRandomAccessFile name="ErrorLog" fileName="${LOG_HOME}/${ERROR_LOG_FILE_NAME}.log" filePattern="${LOG_HOME}/${ERROR_LOG_FILE_NAME}.log.%d{yyyy-MM-dd}.log.gz"> <PatternLayout pattern="%d %-5p (%F:%L) - %m%n" /> <Policies> <!-- TimeBasedTriggeringPolicy指定的size是1,结合起来就是1天生成一个新文件。 --> <!-- 如果filePattern改成%d{yyyy-MM-dd HH}.gz,此时最小粒度为小时,则每一个小时生成一个文件。 --> <TimeBasedTriggeringPolicy /> <!-- 指定当文件体积大于size指定的值时,触发Rolling --> <SizeBasedTriggeringPolicy size="100 MB" /> </Policies> <!-- 指定最多保存的文件个数 --> <DefaultRolloverStrategy max="20" /> </RollingRandomAccessFile> </Appenders> <Loggers> <root level="info" includeLocation="true"> <appender-ref ref="ErrorLog" /> <appender-ref ref="Console" /> </root> </Loggers> </Configuration> 配置mybatis-config.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> <!-- 使用log4j2打印查询语句 --> <settings> <!-- <setting name="logImpl" value="LOG4J2" /> --> <!-- 打印查询语句 --> <setting name="logImpl" value="STDOUT_LOGGING" /> </settings> <typeAliases> <package name="net.csdn" /> </typeAliases> <plugins> <!-- 拦截器配置 --> <plugin interceptor="net.csdn.util.sql.SqlCostInterceptor" /> </plugins> </configuration> 配置spring-context.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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:mybatis="http://mybatis.org/schema/mybatis-spring" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd"> <!-- mybatis:scan会将 net.csdn.mapper 包里的所有接口当作mapper配置,之后可以自动引入mapper接口 --> <!-- 多包用英文逗号隔开,如:<mybatis:scan base-package="net.csdn.mapper,com.baidu.mapper" /> --> <!-- 参见:http://www.mybatis.org/spring/mappers.html --> <mybatis:scan base-package="net.csdn.mapper" /> <!-- 自动检测类并注册bean定义 --> <!-- 参见:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-scanning-autodetection --> <!-- 多包用英文逗号隔开,如:<mybatis:scan base-package="net.csdn,com.baidu" /> --> <context:component-scan base-package="net.csdn" /> <!-- 使用BeanFactoryPostProcessor定制配置元数据 --> <!-- 参见:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-extension-factory-postprocessors --> <context:property-override location="classpath:jdbc.properties" /> <!-- 配置c3p0数据源 --> <!-- 参见:https://www.mchange.com/projects/c3p0/ --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" /> <!-- 配置SqlSessionFactory,org.mybatis.spring.SqlSessionFactoryBean是Mybatis社区开发用于整合Spring的bean --> <!-- 在基本的 MyBatis 中,session 工厂可以使用 SqlSessionFactoryBuilder 来创建。而在 MyBatis-Spring 中,则使用 SqlSessionFactoryBean 来替代。 --> <!-- 参见:http://www.mybatis.org/spring/zh/factorybean.html --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations"> <array> <!-- 扫描xml文件、可填写多个<value>值:如 <value>classpath:net/csdn/mapping/*.xml</value> <value>classpath:com/baidu/mapping/*.xml</value> --> <!-- value中不可有空格:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): --> <value>classpath:net/csdn/mapping/*.xml</value> </array> </property> <!-- 读取MyBatis配置文件的位置,SQL日志输出 --> <property name="configLocation" value="classpath:mybatis-config.xml" /> </bean> <!-- 声明性事务实现的示例 --> <!--参见: https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#transaction-declarative-first-example --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 启用支持annotation注解方式事务管理 --> <!-- 参见:https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#transaction-declarative-annotations --> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- 扫描切点类组件 --> <context:component-scan base-package="net.csdn.aop.aspect" /> <!-- <context:component-scan base-package="net.csdn.service" /> --> <!-- 未知配置 --> <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="5" /> <property name="maxPoolSize" value="10" /> <!-- <property name="WaitForTasksToCompleteOnShutdown" value="true" /> --> </bean> <!-- bean定义 --> <!-- 参见:https://docs.spring.io/spring/docs/5.0.8.RELEASE/spring-framework-reference/core.html#beans-factory-instantiation --> </beans> 配置spring-mvc.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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd"> <!-- 自动扫描该包,SpringMVC会将包下用了@controller注解的类注册为Spring的controller --> <!-- 参见:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-stereotype-annotations --> <!-- 多个 controller 用英文逗号隔开,如:<context:component-scan base-package="net.csdn.controller,com.baidu.controller" /> --> <context:component-scan base-package="net.csdn.controller" /> <!-- 启用MVC注解 --> <!-- 参见:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-config-enable --> <mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <!-- json乱码处理 --> <value>application/json; charset=UTF-8</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!-- 默认Servlet --> <!-- 使用默认的Servlet来响应静态文件 --> <!-- 参见:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-default-servlet-handler --> <mvc:default-servlet-handler /> <!-- 查看解析器 --> <!-- 视图解析器 --> <!-- 参见:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-view-jsp-resolver --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/content/" /> <!-- <property name="suffix" value=".jsp" /> --> </bean> <!-- 使用XML配置启用@AspectJ支持 --> <!-- 参见:https://docs.spring.io/spring/docs/5.0.8.RELEASE/spring-framework-reference/core.html#aop --> <aop:aspectj-autoproxy /> <!-- 参见:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#websocket-server-handshake --> <!-- <websocket:handlers> <websocket:mapping path="/myHandler" handler="myHandler" /> <websocket:handshake-interceptors> <bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor" /> </websocket:handshake-interceptors> </websocket:handlers> <bean id="myHandler" class="net.csdn.websocket.MyHandler" /> --> <!-- 参见:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#websocket-server-runtime-configuration --> <!-- 通过该类即可在普通工具类里获取spring管理的bean --> <bean class="net.csdn.spring.SpringTool" /> <!-- 配置拦截器 --> <mvc:interceptors> <!-- admin 拦截器 --> <mvc:interceptor> <!-- 拦截所有url --> <mvc:mapping path="/**" /> <!-- 不拦截url --> <mvc:exclude-mapping path="/index.html" /> <bean class="net.csdn.handlerInterceptor.HandlerInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> </beans> 至此已配置完成。  SQL: /* Navicat Premium Data Transfer Source Server : 127.0.0.1 Source Server Type : MySQL Source Server Version : 50720 Source Host : 127.0.0.1:3306 Source Schema : csdn Target Server Type : MySQL Target Server Version : 50720 File Encoding : 65001 Date: 30/10/2018 15:34:47 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for test_log -- ---------------------------- DROP TABLE IF EXISTS `test_log`; CREATE TABLE `test_log` ( `logId` int(11) NOT NULL AUTO_INCREMENT COMMENT '日志主键', `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '日志类型', `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '日志标题', `remoteAddr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '请求地址', `requestUri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'URI', `method` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '请求方式', `params` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '提交参数', `exception` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '异常', `operateDate` datetime(0) DEFAULT NULL COMMENT '开始时间', `timeout` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '结束时间', `userId` int(11) DEFAULT NULL COMMENT '用户ID', PRIMARY KEY (`logId`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of test_log -- ---------------------------- INSERT INTO `test_log` VALUES (1, 'info', '访问测试首页', '127.0.0.1', '//test/aop/index.do', 'GET', '', NULL, '2018-10-30 15:16:39', '0:0:0.20', NULL); INSERT INTO `test_log` VALUES (2, 'info', '访问测试登录', '127.0.0.1', '//test/aop/login.do', 'GET', 'username=xuxiaowei&password=', NULL, '2018-10-30 15:16:51', '0:0:0.71', 1); INSERT INTO `test_log` VALUES (3, 'info', '访问测试首页', '127.0.0.1', '//test/aop/index.do', 'GET', '', NULL, '2018-10-30 15:17:25', '0:0:0.0', 1); INSERT INTO `test_log` VALUES (4, 'info', '访问测试首页', '127.0.0.1', '//test/aop/index.do', 'GET', '', NULL, '2018-10-30 15:21:26', '0:0:0.27', NULL); INSERT INTO `test_log` VALUES (5, 'info', '访问测试登录', '127.0.0.1', '//test/aop/login.do', 'GET', 'username=xuxiaowei&password=', NULL, '2018-10-30 15:21:28', '0:0:0.69', 1); INSERT INTO `test_log` VALUES (6, 'error', '异常测试', '127.0.0.1', '//test/aop/err.do', 'GET', '', 'java.lang.ArithmeticException: / by zero', '2018-10-30 15:21:47', '0:0:0.0', 1); -- ---------------------------- -- Table structure for test_user -- ---------------------------- DROP TABLE IF EXISTS `test_user`; CREATE TABLE `test_user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '工号', `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '账号', `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名', `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '密码', `sex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '性别', `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '邮箱', `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '手机', `locked` tinyint(4) DEFAULT NULL COMMENT '是否被锁定', `organizationId` int(11) DEFAULT NULL COMMENT '部门ID仅用户接受参数', `loginIp` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '最后登入IP', `loginDate` datetime(0) DEFAULT NULL COMMENT '最后登入日期', `photo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '头像', `oldLoginIp` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '上次登入IP', `oldLoginDate` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '上次登入日期', `createBy` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建者ID', `updateBy` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新者ID', `createDate` datetime(0) DEFAULT NULL COMMENT '创建日期', `updateDate` datetime(0) DEFAULT NULL COMMENT '更新日期', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of test_user -- ---------------------------- INSERT INTO `test_user` VALUES (1, 'xuxiaowei', NULL, '123456', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); SET FOREIGN_KEY_CHECKS = 1; 测试日志:  相关类:以下类均为测试使用,可在上面的配置中删除。 net.csdn.aop.annotation.TestSystemControllerLog: 系统日志切片相关,自定义注解,拦截Controller,用于记操作日志: package net.csdn.aop.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 自定义注解 拦截Controller * * @author xuxiaowei * */ @Target({ ElementType.PARAMETER, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface TestSystemControllerLog { /** * 获取描述description * * @SystemControllerLog(description = "登入系统") * * @return */ String description() default ""; } net.csdn.aop.aspect.TestSystemLogAspect: 系统日志切点类: package net.csdn.aop.aspect; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.NamedThreadLocal; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; //import com.layui.test.entity.TestLog; //import com.layui.test.entity.TestUser; //import com.layui.test.service.TestLogService; //import com.layui.test.util.UuidUtils; import net.csdn.aop.annotation.TestSystemControllerLog; import net.csdn.entity.TestLog; import net.csdn.entity.TestUser; import net.csdn.service.TestLogService; import net.csdn.util.date.DateUtils; import net.csdn.util.string.StringUtils; /** * 系统日志切点类 * * @author xuxiaowei * */ @Aspect @Component public class TestSystemLogAspect { /** * */ private static final Logger logger = LoggerFactory.getLogger(TestSystemLogAspect.class); /** * 本地线程开始时间 */ private static final ThreadLocal<Date> beginTimeThreadLocal = new NamedThreadLocal<Date>("ThreadLocal beginTime"); /** * 本地线程日志 */ private static final ThreadLocal<TestLog> logThreadLocal = new NamedThreadLocal<TestLog>("ThreadLocal log"); /** * 当前用户 */ private static final ThreadLocal<TestUser> currentUser = new NamedThreadLocal<>("ThreadLocal user"); /** * 全局变量,同一个请求 */ @Autowired(required = false) private HttpServletRequest request; /** * 线程池任务执行程序 */ @Autowired private ThreadPoolTaskExecutor threadPoolTaskExecutor; /** * 日志储存service */ @Autowired private TestLogService logService; // /** // * Service层切点 // */ // @Pointcut("@annotation(cn.wimcn.test.annotation.SystemServiceLog)") // public void serviceAspect() { // System.out.println("+++++++++++++Service层切点+++++++++++++"); // } /** * Controller层切点 注解拦截 */ @Pointcut("@annotation(net.csdn.aop.annotation.TestSystemControllerLog)") public void testControllerAspect() { System.out.println("+++++++++++++Controller层切点 注解拦截+++++++++++++"); } /** * 方法规则拦截 */ @Pointcut("execution(* net.csdn.controller.*.*(..))") public void controllerPointerCut() { logger.debug("+++++++++++++方法规则拦截+++++++++++++"); } /** * 前置通知 用于拦截Controller层记录用户的操作的开始时间 * * @param joinPoint 切点 * @throws InterruptedException */ @Before("testControllerAspect()") public void doBefore(JoinPoint joinPoint) throws InterruptedException { Date beginTime = new Date(); // 设置本地线程开始时间 beginTimeThreadLocal.set(beginTime); // debug模式下 显式打印开始时间用于调试 // 在log4j中开启本类的debug if (logger.isDebugEnabled()) { logger.debug("开始计时: {} URI: {}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(beginTime), request.getRequestURI()); } // 读取session中的用户 HttpSession session = request.getSession(); TestUser user = (TestUser) session.getAttribute("ims_user"); currentUser.set(user); } /** * 后置通知 用于拦截Controller层记录用户的操作 * * @param joinPoint 切点 */ @After("testControllerAspect()") public void doAfter(JoinPoint joinPoint) { TestUser user = currentUser.get(); // 登入login操作 前置通知时用户未校验 所以session中不存在用户信息 if (user == null) { HttpSession session = request.getSession(); user = (TestUser) session.getAttribute("ims_user"); if (user == null) { user = new TestUser(); } } Object[] args = joinPoint.getArgs(); System.out.println("joinPoint-args:" + args.toString()); String title = ""; String type = "info"; // 日志类型(info:入库,error:错误) String remoteAddr = request.getRemoteAddr();// 请求的IP String requestUri = request.getRequestURI();// 请求的Uri String method = request.getMethod(); // 请求的方法类型(post/get) Map<String, String[]> params = request.getParameterMap(); // 请求提交的参数 try { title = getControllerMethodDescription2(joinPoint); } catch (Exception e) { e.printStackTrace(); } // debu模式下打印JVM信息。 long beginTime = beginTimeThreadLocal.get().getTime();// 得到线程绑定的局部变量(开始时间) long endTime = System.currentTimeMillis(); // 2、结束时间 if (logger.isDebugEnabled()) { logger.debug("计时结束:{} URI: {} 耗时: {} 最大内存: {}m 已分配内存: {}m 已分配内存中的剩余空间: {}m 最大可用内存: {}m", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(endTime), request.getRequestURI(), DateUtils.formatDateTime(endTime - beginTime), Runtime.getRuntime().maxMemory() / 1024 / 1024, Runtime.getRuntime().totalMemory() / 1024 / 1024, Runtime.getRuntime().freeMemory() / 1024 / 1024, (Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory() + Runtime.getRuntime().freeMemory()) / 1024 / 1024); } TestLog testLog = new TestLog(); // testLog.setLogid(UuidUtils.creatUUID()); testLog.setTitle(title); testLog.setType(type); testLog.setRemoteAddr(remoteAddr); testLog.setRequestUri(requestUri); testLog.setMethod(method); testLog.setParams(StringUtils.getMapToParams(params)); // testLog.setUserid(user.getId()); testLog.setUserId(user.getId()); Date operateDate = beginTimeThreadLocal.get(); testLog.setOperateDate(operateDate); testLog.setTimeout(DateUtils.formatDateTime(endTime - beginTime)); // 1.直接执行保存操作 // this.logService.createSystemLog(log); // 2.优化:异步保存日志 // new SaveLogThread(log, logService).start(); // 3.再优化:通过线程池来执行日志保存 threadPoolTaskExecutor.execute(new SaveLogThread(testLog, logService)); logThreadLocal.set(testLog); } /** * 异常通知 * * @param joinPoint * @param e */ @AfterThrowing(pointcut = "testControllerAspect()", throwing = "e") public void doAfterThrowing(JoinPoint joinPoint, Throwable e) { TestLog testLog = logThreadLocal.get(); if (testLog != null) { testLog.setType("error"); testLog.setException(e.toString()); new UpdateLogThread(testLog, logService).start(); } } /** * 获取注解中对方法的描述信息 用于Controller层注解 * * @param joinPoint 切点 * @return 方法描述 */ public static String getControllerMethodDescription2(JoinPoint joinPoint) { /** * Returns the signature at the join point. 返回连接点处的签名。 * getStaticPart().getSignature() returns the same object 返回相同的对象 */ MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); TestSystemControllerLog controllerLog = method.getAnnotation(TestSystemControllerLog.class); String discription = controllerLog.description(); return discription; } /** * 保存日志线程 * * @author xuxiaowei * */ private static class SaveLogThread implements Runnable { private TestLog testLog; private TestLogService testLogService; public SaveLogThread(TestLog testLog, TestLogService testLogService) { this.testLog = testLog; this.testLogService = testLogService; } @Override public void run() { testLogService.insert(testLog); } } /** * 日志更新线程 * * @author xuxiaowei * */ private static class UpdateLogThread extends Thread { private TestLog testLog; private TestLogService logService; public UpdateLogThread(TestLog testLog, TestLogService logService) { super(UpdateLogThread.class.getSimpleName()); this.testLog = testLog; this.logService = logService; } @Override public void run() { this.logService.updateByPrimaryKeySelective(testLog); } } } net.csdn.controller.TestAopController: 测试Controller: package net.csdn.controller; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import net.csdn.aop.annotation.TestSystemControllerLog; import net.csdn.entity.TestUser; import net.csdn.entity.TestUserExample; import net.csdn.entity.TestUserExample.Criteria; import net.csdn.service.TestUserService; /** * 测试AOP * * @author xuxiaowei * */ @Api(value = "/test", tags = "系统登入接口") @Controller @RequestMapping("/test/aop") public class TestAopController { private static final Logger logger = LoggerFactory.getLogger(TestAopController.class); @Autowired private TestUserService testUserService; /** * 测试主页 * * @param request * @param response * @return */ @TestSystemControllerLog(description = "访问测试首页") @RequestMapping("/index.do") public String test(HttpServletRequest request, HttpServletResponse response) { System.out.println("/index.do"); logger.info("{} 访问测试首页", "xxx"); return "test/aop/index.jsp"; } /** * 测试登录方法 * * @param request * @param response * @param test * @param model * @return */ @ApiOperation(value = "登入系统", notes = "登入系统", httpMethod = "POST") @TestSystemControllerLog(description = "访问测试登录") @RequestMapping("/login.do") public String login(HttpServletRequest request, HttpServletResponse response, TestUser testUser, Model model) { System.out.println("/login.do"); String username2 = testUser.getUsername(); String password2 = testUser.getPassword(); System.out.println(username2); System.out.println(password2); TestUserExample testUserExample = new TestUserExample(); Criteria createCriteria = testUserExample.createCriteria(); createCriteria.andUsernameEqualTo(username2); createCriteria.andPasswordEqualTo(password2); List<TestUser> testUsers = testUserService.selectByExample(testUserExample); HttpSession session = request.getSession(); if (testUsers.size() > 0) { logger.info("{} 登入系统成功!", username2); String string = testUsers.toString(); System.out.println(string); model.addAttribute("string", string); session.setAttribute("ims_user", testUsers.get(0)); } else { logger.info("{} 登入系统失败!", username2); } return "test/aop/main.jsp"; } @TestSystemControllerLog(description = "异常测试") @RequestMapping("/err.do") public String err(HttpServletRequest request, HttpServletResponse response) { System.out.println("/err.do"); logger.info("{} 访问页面异常测试", "xxx"); int i = 5 / 0; System.out.println(i); return "test/aop/index.jsp"; } } net.csdn.handlerInterceptor.HandlerInterceptor: 拦截器: package net.csdn.handlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; /** * * @author xuxiaowei * */ public class HandlerInterceptor implements HandlerInterceptor { @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // TODO Auto-generated method stub return HandlerInterceptor.super.preHandle(request, response, handler); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub HandlerInterceptor.super.afterCompletion(request, response, handler, ex); } } 实体类相关,自动生成:  工具类:用于生成entity、mapper、mapping、service、serviceImpl:  net.csdn.servlet.ValidCode: 验证码生成器: package net.csdn.servlet; import java.awt.Color; import java.io.IOException; import java.util.Random; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.github.bingoohuang.patchca.color.ColorFactory; import com.github.bingoohuang.patchca.custom.ConfigurableCaptchaService; import com.github.bingoohuang.patchca.filter.predefined.CurvesRippleFilterFactory; import com.github.bingoohuang.patchca.filter.predefined.DiffuseRippleFilterFactory; import com.github.bingoohuang.patchca.filter.predefined.DoubleRippleFilterFactory; import com.github.bingoohuang.patchca.filter.predefined.MarbleRippleFilterFactory; import com.github.bingoohuang.patchca.filter.predefined.WobbleRippleFilterFactory; import com.github.bingoohuang.patchca.font.RandomFontFactory; import com.github.bingoohuang.patchca.utils.encoder.EncoderHelper; import com.github.bingoohuang.patchca.word.RandomWordFactory; /** * github验证码 * * @author xuxiaowei * */ public class ValidCode extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; private static ConfigurableCaptchaService cs = new ConfigurableCaptchaService(); private static Random random = new Random(); static { // cs.setColorFactory(new SingleColorFactory(new Color(25, 60, 170))); cs.setColorFactory(new ColorFactory() { @Override public Color getColor(int x) { int[] c = new int[3]; int i = random.nextInt(c.length); for (int fi = 0; fi < c.length; fi++) { if (fi == i) { c[fi] = random.nextInt(71); } else { c[fi] = random.nextInt(256); } } return new Color(c[0], c[1], c[2]); } }); RandomWordFactory randomWordFactory = new RandomWordFactory(); // 字符范围 randomWordFactory.setCharacters("23456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ"); // 字符数量范围 randomWordFactory.setMaxLength(5); randomWordFactory.setMinLength(3); cs.setWordFactory(randomWordFactory); // 图片像素 cs.setHeight(40); cs.setWidth(130); // 字体大小范围 RandomFontFactory randomFontFactory = new RandomFontFactory(); randomFontFactory.setMaxSize(40); randomFontFactory.setMinSize(30); cs.setFontFactory(randomFontFactory); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { switch (random.nextInt(5)) { case 0: cs.setFilterFactory(new CurvesRippleFilterFactory(cs.getColorFactory())); break; case 1: cs.setFilterFactory(new MarbleRippleFilterFactory()); break; case 2: cs.setFilterFactory(new DoubleRippleFilterFactory()); break; case 3: cs.setFilterFactory(new WobbleRippleFilterFactory()); break; case 4: cs.setFilterFactory(new DiffuseRippleFilterFactory()); break; } HttpSession session = request.getSession(); session = request.getSession(); setResponseHeaders(response); String token = EncoderHelper.getChallangeAndWriteImage(cs, "png", response.getOutputStream()); session.setAttribute("verifyCode", token); } protected void setResponseHeaders(HttpServletResponse response) { response.setContentType("image/png"); response.setHeader("Cache-Control", "no-cache, no-store"); response.setHeader("Pragma", "no-cache"); long time = System.currentTimeMillis(); response.setDateHeader("Last-Modified", time); response.setDateHeader("Date", time); response.setDateHeader("Expires", time); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doPost(req, resp); } } net.csdn.spring.SpringTool: 通过该类即可在普通工具类里获取spring管理的bean: package net.csdn.spring; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; /** * 通过该类即可在普通工具类里获取spring管理的bean * * @author xuxiaowei * */ public final class SpringTool implements ApplicationContextAware { private static ApplicationContext applicationContext = null; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (SpringTool.applicationContext == null) { SpringTool.applicationContext = applicationContext; System.out.println(); System.out.println("========" + "ApplicationContext配置成功," + "在普通类可以通过调用ToolSpring.getAppContext()获取applicationContext对象," + "applicationContext=" + applicationContext + "========"); System.out.println(); } } /** * * @return */ public static ApplicationContext getApplicationContext() { return applicationContext; } /** * 获取been * * @param serviceName * @return */ public static Object getBean(String serviceName) { return getApplicationContext().getBean(serviceName); } } net.csdn.util.sql.SqlCostInterceptor: Sql执行时间记录拦截器: package net.csdn.util.sql; import java.sql.Statement; import java.util.Properties; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.session.ResultHandler; /** * Sql执行时间记录拦截器 * * @author xuxiaowei * */ @Intercepts({ @Signature(type = StatementHandler.class, method = "query", args = { Statement.class, ResultHandler.class }), @Signature(type = StatementHandler.class, method = "update", args = { Statement.class }), @Signature(type = StatementHandler.class, method = "batch", args = { Statement.class }) }) public class SqlCostInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { long startTime = System.currentTimeMillis(); try { return invocation.proceed(); } finally { long endTime = System.currentTimeMillis(); long sqlCost = endTime - startTime; System.out.println("执行SQL耗时 : [" + sqlCost + "ms ] "); } } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { } } net.csdn.util.string.StringUtils: 字符串工具类: package net.csdn.util.string; import java.io.UnsupportedEncodingException; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; //deprecated as of 3.6, use commons-text //从3.6开始弃用,使用commons-text //import org.apache.commons.lang3.StringEscapeUtils; //commons-text-1.4.jar import org.apache.commons.text.StringEscapeUtils; /** * 字符串工具类 * * 继承org.apache.commons.lang3.StringUtils类 * * @author xuxiaowei * */ public class StringUtils extends org.apache.commons.lang3.StringUtils { private static final char SEPARATOR = '_'; private static final String CHARSET_NAME = "UTF-8"; /** * 首字母小写 * * @param string * @return */ public static String lowerFirst(String string) { char[] cs = string.toCharArray(); cs[0] += 32; String valueOf = String.valueOf(cs); return valueOf; } /** * 转换为字节数组 * * @param str * @return */ public static byte[] getBytes(String str) { if (str != null) { try { return str.getBytes(CHARSET_NAME); } catch (UnsupportedEncodingException e) { return null; } } else { return null; } } /** * 转换为字节数组 * * @param str * @return */ public static String toString(byte[] bytes) { try { return new String(bytes, CHARSET_NAME); } catch (UnsupportedEncodingException e) { return EMPTY; } } /** * 是否包含字符串 * * @param str 验证字符串 * @param strs 字符串组 * @return 包含返回true */ public static boolean inString(String str, String... strs) { if (str != null) { for (String s : strs) { if (str.equals(trim(s))) { return true; } } } return false; } /** * 替换掉HTML标签方法 * * @param html * @return */ public static String replaceHtml(String html) { if (isBlank(html)) { return ""; } String regEx = "<.+?>"; Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(html); String s = m.replaceAll(""); return s; } /** * 替换为手机识别的HTML,去掉样式及属性,保留回车。 * * @param html * @return */ public static String replaceMobileHtml(String html) { if (html == null) { return ""; } return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>"); } // /** // * 替换为手机识别的HTML,去掉样式及属性,保留回车。 // * // * @param txt // * @return // */ // public static String toHtml(String txt) { // if (txt == null) { // return ""; // } // return replace(replace(Encodes.escapeHtml(txt), "\n", "<br/>"), "\t", "    "); // } /** * 缩略字符串(不区分中英文字符) * * @param str 目标字符串 * @param length 截取长度 * @return */ public static String abbr(String str, int length) { if (str == null) { return ""; } try { StringBuilder sb = new StringBuilder(); int currentLength = 0; for (char c : replaceHtml(StringEscapeUtils.unescapeHtml4(str)).toCharArray()) { currentLength += String.valueOf(c).getBytes("GBK").length; if (currentLength <= length - 3) { sb.append(c); } else { sb.append("..."); break; } } return sb.toString(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return ""; } /** * 转换为Double类型 * * @param val * @return */ public static Double toDouble(Object val) { if (val == null) { return 0D; } try { return Double.valueOf(trim(val.toString())); } catch (Exception e) { return 0D; } } /** * 转换为Float类型 * * @param val * @return */ public static Float toFloat(Object val) { return toDouble(val).floatValue(); } /** * 转换为Long类型 * * @param val * @return */ public static Long toLong(Object val) { return toDouble(val).longValue(); } /** * 转换为Integer类型 * * @param val * @return */ public static Integer toInteger(Object val) { return toLong(val).intValue(); } // /** // * 获得i18n字符串 // * // * @param code // * @param args // * @return // */ // public static String getMessage(String code, Object[] args) { // LocaleResolver localLocaleResolver = (LocaleResolver) SpringContextHolder.getBean(LocaleResolver.class); // HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) // .getRequest(); // Locale localLocale = localLocaleResolver.resolveLocale(request); // return SpringContextHolder.getApplicationContext().getMessage(code, args, localLocale); // } /** * 获得用户远程地址 * * @param request * @return */ public static String getRemoteAddr(HttpServletRequest request) { String remoteAddr = request.getHeader("X-Real-IP"); if (isNotBlank(remoteAddr)) { remoteAddr = request.getHeader("X-Forwarded-For"); } else if (isNotBlank(remoteAddr)) { remoteAddr = request.getHeader("Proxy-Client-IP"); } else if (isNotBlank(remoteAddr)) { remoteAddr = request.getHeader("WL-Proxy-Client-IP"); } return remoteAddr != null ? remoteAddr : request.getRemoteAddr(); } /** * 驼峰命名法工具 * * toCamelCase("hello_world") == "helloWorld" * toCapitalizeCamelCase("hello_world") == "HelloWorld" * toUnderScoreCase("helloWorld") = "hello_world" * * @param s * @return */ public static String toCamelCase(String s) { if (s == null) { return null; } s = s.toLowerCase(); StringBuilder sb = new StringBuilder(s.length()); boolean upperCase = false; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == SEPARATOR) { upperCase = true; } else if (upperCase) { sb.append(Character.toUpperCase(c)); upperCase = false; } else { sb.append(c); } } return sb.toString(); } /** * 驼峰命名法工具 * * toCamelCase("hello_world") == "helloWorld" * toCapitalizeCamelCase("hello_world") == "HelloWorld" * toUnderScoreCase("helloWorld") = "hello_world" * * @param s * @return */ public static String toCapitalizeCamelCase(String s) { if (s == null) { return null; } s = toCamelCase(s); return s.substring(0, 1).toUpperCase() + s.substring(1); } /** * 驼峰命名法工具 * * toCamelCase("hello_world") == "helloWorld" * toCapitalizeCamelCase("hello_world") == "HelloWorld" * toUnderScoreCase("helloWorld") = "hello_world" * * @param s * @return */ public static String toUnderScoreCase(String s) { if (s == null) { return null; } StringBuilder sb = new StringBuilder(); boolean upperCase = false; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); boolean nextUpperCase = true; if (i < (s.length() - 1)) { nextUpperCase = Character.isUpperCase(s.charAt(i + 1)); } if ((i > 0) && Character.isUpperCase(c)) { if (!upperCase || !nextUpperCase) { sb.append(SEPARATOR); } upperCase = true; } else { upperCase = false; } sb.append(Character.toLowerCase(c)); } return sb.toString(); } /** * 驼峰转下划线 (暂不建议使用toUnderScoreCase) * * @param camelCaseName * @return */ public static String toUnderscoreName(String camelCaseName) { StringBuilder result = new StringBuilder(); if (camelCaseName != null && camelCaseName.length() > 0) { result.append(camelCaseName.substring(0, 1).toLowerCase()); for (int i = 1; i < camelCaseName.length(); i++) { char ch = camelCaseName.charAt(i); if (Character.isUpperCase(ch)) { result.append("_"); result.append(Character.toLowerCase(ch)); } else { result.append(ch); } } } return result.toString(); } /** * 如果不为空,则设置值 * * @param target * @param source */ public static void setValueIfNotBlank(String target, String source) { if (isNotBlank(source)) { target = source; } } /** * 转换为JS获取对象值,生成三目运算返回结果 * * 例如:row.user.id * * 返回:!row?'':!row.user?'':!row.user.id?'':row.user.id * * @param objectString 对象串 */ public static String jsGetVal(String objectString) { StringBuilder result = new StringBuilder(); StringBuilder val = new StringBuilder(); String[] vals = split(objectString, "."); for (int i = 0; i < vals.length; i++) { val.append("." + vals[i]); result.append("!" + (val.substring(1)) + "?'':"); } result.append(val.substring(1)); return result.toString(); } /** * 转换为utf-8字符串 * * @param s * @return */ public static String toUtf8String(String s) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c >= 0 && c <= 255) { sb.append(c); } else { byte[] b; try { b = Character.toString(c).getBytes("utf-8"); } catch (Exception ex) { b = new byte[0]; } for (int j = 0; j < b.length; j++) { int k = b[j]; if (k < 0) k += 256; sb.append("%" + Integer.toHexString(k).toUpperCase()); } } } return sb.toString(); } /** * * Map<String, String[]> 转 String * * @param paramMap * @return */ public static String getMapToParams(Map<String, String[]> paramMap) { if (paramMap == null) { return ""; } StringBuilder params = new StringBuilder(); for (Map.Entry<String, String[]> param : ((Map<String, String[]>) paramMap).entrySet()) { params.append(("".equals(params.toString()) ? "" : "&") + param.getKey() + "="); String paramValue = (param.getValue() != null && param.getValue().length > 0 ? param.getValue()[0] : ""); params.append(StringUtils.abbr(StringUtils.endsWithIgnoreCase(param.getKey(), "password") ? "" : paramValue, 100)); } return params.toString(); } } net.csdn.util.date.DateUtils: 日期工具类: package net.csdn.util.date; import java.text.ParseException; import java.util.Date; import org.apache.commons.lang3.time.DateFormatUtils; /** * 日期工具类 * * 继承org.apache.commons.lang3.time.DateUtils类 * * @author xuxiaowei * */ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { private static String[] parsePatterns = { "yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss", "yyyy.MM.dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd HH:mm", "yyyy.MM.dd HH:mm", "yyyy-MM-dd", "yyyy/MM/dd", "yyyy.MM.dd", "yyyy-MM", "yyyy/MM", "yyyy.MM" }; /** * 得到当前日期字符串 格式(yyyy-MM-dd) * * @return */ public static String getDate() { return getDate("yyyy-MM-dd"); } /** * 得到当前日期字符串 格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E" * * @param pattern * @return */ public static String getDate(String pattern) { return DateFormatUtils.format(new Date(), pattern); } /** * 得到日期字符串 默认格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E" * * @param date * @param pattern * @return */ public static String formatDate(Date date, Object... pattern) { String formatDate = null; if (pattern != null && pattern.length > 0) { formatDate = DateFormatUtils.format(date, pattern[0].toString()); } else { formatDate = DateFormatUtils.format(date, "yyyy-MM-dd"); } return formatDate; } /** * 得到日期时间字符串,转换格式(yyyy-MM-dd HH:mm:ss) * * @param date * @return */ public static String formatDateTime(Date date) { return formatDate(date, "yyyy-MM-dd HH:mm:ss"); } /** * 得到当前时间字符串 格式(HH:mm:ss) * * @return */ public static String getTime() { return formatDate(new Date(), "HH:mm:ss"); } /** * 得到当前日期和时间字符串 格式(yyyy-MM-dd HH:mm:ss) * * @return */ public static String getDateTime() { return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"); } /** * 得到当前年份字符串 格式(yyyy) * * @return */ public static String getYear() { return formatDate(new Date(), "yyyy"); } /** * 得到当前月份字符串 格式(MM) * * @return */ public static String getMonth() { return formatDate(new Date(), "MM"); } /** * 得到当天字符串 格式(dd) * * @return */ public static String getDay() { return formatDate(new Date(), "dd"); } /** * 得到当前星期字符串 格式(E)星期几 * * @return */ public static String getWeek() { return formatDate(new Date(), "E"); } /** * 日期型字符串转化为日期格式 * * "yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss", "yyyy.MM.dd HH:mm:ss", * "yyyy-MM-dd HH:mm", "yyyy/MM/dd HH:mm", "yyyy.MM.dd HH:mm", "yyyy-MM-dd", * "yyyy/MM/dd", "yyyy.MM.dd", "yyyy-MM", "yyyy/MM", "yyyy.MM" * * @param str * @return */ public static Date parseDate(Object str) { if (str == null) { return null; } try { return parseDate(str.toString(), parsePatterns); } catch (ParseException e) { return null; } } /** * 获取过去的天数 * * @param date * @return */ public static long pastDays(Date date) { long t = new Date().getTime() - date.getTime(); return t / (24 * 60 * 60 * 1000); } /** * 获取过去的小时 * * @param date * @return */ public static long pastHour(Date date) { long t = new Date().getTime() - date.getTime(); return t / (60 * 60 * 1000); } /** * 获取过去的分钟 * * @param date * @return */ public static long pastMinutes(Date date) { long t = new Date().getTime() - date.getTime(); return t / (60 * 1000); } /** * 转换为时间(天,时:分:秒.毫秒) * * @param timeMillis * @return */ public static String formatDateTime(long timeMillis) { long day = timeMillis / (24 * 60 * 60 * 1000); long hour = (timeMillis / (60 * 60 * 1000) - day * 24); long min = ((timeMillis / (60 * 1000)) - day * 24 * 60 - hour * 60); long s = (timeMillis / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60); long sss = (timeMillis - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - s * 1000); return (day > 0 ? day + "," : "") + hour + ":" + min + ":" + s + "." + sss; } /** * 获取两个日期之间的天数 * * @param before * @param after * @return */ public static double getDistanceOfTwoDate(Date before, Date after) { long beforeTime = before.getTime(); long afterTime = after.getTime(); return (afterTime - beforeTime) / (1000 * 60 * 60 * 24); } /** * @param args * @throws ParseException */ public static void main(String[] args) throws ParseException { // System.out.println(formatDate(parseDate("2010/3/6"))); // System.out.println(getDate("yyyy年MM月dd日 E")); // long time = new Date().getTime()-parseDate("2012-11-19").getTime(); // System.out.println(time/(24*60*60*1000)); } } 项目源码:Spring 5 + Spring MVC 5 + MyBatis 3 的 Maven 项目集成 源码  本文参考: Spring AOP实现后台管理系统日志管理

相关链接:

MyEclipse CI 2018.9.0 配置 Apache Maven 3.5.4

在MyEclipse CI 2018.9.0 中使用 Maven 3.5.4 创建Maven项目

在MyEclipse中使用SVN提交(自动忽略 .settings .project .classpath等)、检出(无.settings .project .classpath文件等)Maven代码

转载请注明原文地址: https://www.6miu.com/read-4915022.html

最新回复(0)