一.SSM剩余概念和配置
在之前的三篇文章里,我分别讲了SpringMVC、Spring、Mybatis三个子框架的概念、运行流程以及配置说明,再往前的一篇文章,我也讲过了maven的概念和配置,其中的配置文件,包含了config.properties、mybatis-config.xml、spring-context.xml、spring-mvc.xml,还有maven的pom.xml文件。
整个项目的路径构成和resources里的配置文件,以及pom.xml的位置如上图所示,可见还有几个配置文件是我们没讲过的,这里就先说一说还有那些个关键的配置文件,他们都有什么作用,处在什么路径。
1.Web.xml
身为一个web工程,别管是不是maven管理,也别管用没用ssm框架,web.xml一定是必备的,也是项目第一步加载的一个配置文件,先来看一下它的路径位置:
然后再直接贴一下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_3_1.xsd" id="WebApp_ID"
version="3.1">
<!-- 项目名称 -->
<display-name>xxx-bs-maintaining-app</display-name>
<!-- Context ConfigLocation -->
<!-- 加载Spring容器配置 -->
<!-- 设置spring容器加载所有的配置文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring-context*.xml</param-value>
</context-param>
<!-- 配置ContextLoaderListener监听器,启动web时自动装配ApplicationContext。默认执行实现方法 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<!-- 解决工程编码过滤器 -->
<filter>
<filter-name>encodingFilter</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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Apache Shiro -->
<!-- 配置Shiro安全认证过滤器以及映射 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- SiteMesh -->
<!-- SiteMesh网页布局和修饰框架配置 -->
<filter>
<filter-name>sitemeshFilter</filter-name>
<filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemeshFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- MVC Servlet -->
<!-- 配置SpringMVC核心控制器 -->
<!-- 配置DispatcherServlet前端控制器 -->
<servlet>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置DispatcherServlet的路径 -->
<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>
<!-- 为DispatcherServlet建立映射 -->
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<!-- 也可以写成*.do -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- DruidStatView -->
<!-- Druid Monitor监控java web项目 -->
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
<!--init-param>
<param-name>allow</param-name>
<param-value>127.0.0.1</param-value>
</init-param-->
<!-- 允许清空统计数据 -->
<!--init-param>
<param-name>resetEnable</param-name>
<param-value>true</param-value>
</init-param-->
<init-param>
<!-- 用户名 -->
<param-name>loginUsername</param-name>
<param-value>druid</param-value>
</init-param>
<init-param>
<!-- 密码 -->
<param-name>loginPassword</param-name>
<param-value>druid#dyb</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
<!-- Validate code -->
<servlet>
<servlet-name>ValidateCodeServlet</servlet-name>
<servlet-class>com.xxx.lrt.frame.core.web.servlet.ValidateCodeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ValidateCodeServlet</servlet-name>
<url-pattern>/servlet/validateCodeServlet</url-pattern>
</servlet-mapping>
<!-- [INSERT FRAGMENT HERE] -->
<!-- Session configure, to "config.properties" file "session.sessionTimeout" parameter.
<session-config>
<session-timeout>30</session-timeout>
</session-config>-->
<!-- Error page -->
<!-- <error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/WEB-INF/views/error/500.jsp</location>
</error-page> -->
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/views/error/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/views/error/404.jsp</location>
</error-page>
</web-app>
2.decorators.xml
其中,在sitemesh配置的地方,sitemesh应用Decorator模式,用filter截取request和response,在src的WEB-INF下,与web.xml同级,建立以下decorators.xml:
<?xml version="1.0" encoding="UTF-8"?>
<decorators defaultdir="/WEB-INF/views">
<!-- 默认装饰页面, 在需要装饰的页面增加<meta name="decorator" content="default"/> -->
<decorator name="blank" page="layouts/blank.jsp" />
<decorator name="default" page="layouts/default.jsp" />
</decorators>
3.pom.xml
pom.xml是maven集成项目的核心文件,也是牵扯甚广,下面贴一下,里面标注出配置的作用,主要包含的是maven引入的jar包:
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<!-- 存储包的路径,命名规则第一段为org(非盈利组织)/com(商业组织),第二段为公司名,第三段为项目名 -->
<groupId>com.xxx.bs</groupId>
<!-- 打包类型,这里是war包 -->
<packaging>war</packaging>
<!-- 模块名 -->
<artifactId>xxx-bs-maintaining-app</artifactId>
<version>1.0.0</version>
<name>xxx-bs-maintaining-app</name>
<url>http://maven.apache.org</url>
<!-- 项目属性 -->
<properties>
<!-- main version setting -->
<!-- spring版本号 -->
<spring.version>4.3.7.RELEASE</spring.version>
<validator.version>5.1.1.Final</validator.version>
<!-- mybatis版本号 -->
<mybatis.version>3.4.5</mybatis.version>
<mybatis-spring.version>1.3.1</mybatis-spring.version>
<druid.version>1.1.6</druid.version>
<ehcache.version>2.6.9</ehcache.version>
<ehcache-web.version>2.0.4</ehcache-web.version>
<!-- 安全框架shiro缓存版本号 -->
<shiro.version>1.4.0</shiro.version>
<!-- jedis、redis缓存版本号 -->
<jedis.version>2.9.0</jedis.version>
<spring.data.redis.version>1.8.1.RELEASE</spring.data.redis.version>
<sitemesh.version>2.4.2</sitemesh.version>
<!-- tools version setting -->
<!-- log4j日志文件管理包版本 -->
<slf4j.version>1.7.7</slf4j.version>
<logback.version>1.1.2</logback.version>
<commons-lang3.version>3.3.2</commons-lang3.version>
<commons-io.version>2.4</commons-io.version>
<commons-codec.version>1.9</commons-codec.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<commons-beanutils.version>1.9.1</commons-beanutils.version>
<jackson.version>2.9.3</jackson.version>
<fastjson.version>1.2.44</fastjson.version>
<xstream.version>1.4.7</xstream.version>
<guava.version>18.0</guava.version>
<dozer.version>5.5.1</dozer.version>
<poi.version>3.17</poi.version>
<zip4j.version>1.3.2</zip4j.version>
<quartz.version>2.2.2</quartz.version>
<!--引入themeleaf-->
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<!-- jdbc driver setting -->
<mysql.driver.version>5.1.31</mysql.driver.version>
<!-- environment setting -->
<jdk.version>1.8</jdk.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<downloadSources>true</downloadSources>
<war.plugin.version>2.6</war.plugin.version>
<compiler.plugin.version>3.5.1</compiler.plugin.version>
<clean.plugin.version>2.5</clean.plugin.version>
<antrun.plugin.version>1.8</antrun.plugin.version>
<dependency.plugin.version>2.10</dependency.plugin.version>
<install.plugin.version>2.5.2</install.plugin.version>
</properties>
<!-- 依赖项定义 -->
<dependencies>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>${thymeleaf.version}</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>${thymeleaf.version}</version>
</dependency>
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<!-- SPRING begin -->
<!-- spring核心包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>${spring.data.redis.version}</version>
</dependency>
<!-- bean validate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${validator.version}</version>
</dependency>
<!-- SPRING end -->
<!-- AOP begin -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
<!-- AOP end -->
<!-- PERSISTENCE begin -->
<!-- MyBatis -->
<!-- mybatis核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- mybatis/spring包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<!-- connection pool -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- jdbc driver -->
<!-- 导入Mysql数据库链接jar包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.driver.version}</version>
<scope>compile</scope>
</dependency>
<!-- PERSISTENCE end -->
<!-- WEB begin -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>opensymphony</groupId>
<artifactId>sitemesh</artifactId>
<version>${sitemesh.version}</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!-- WEB end -->
<!-- CACHE begin -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>${ehcache.version}</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-web</artifactId>
<version>${ehcache-web.version}</version>
</dependency>
<!-- CACHE end -->
<!-- SECURITY begin -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-cas</artifactId>
<version>${shiro.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-quartz</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
</dependency>
<!-- SECURITY end -->
<!-- 日志文件管理包 -->
<!-- LOGGING begin -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- LOGGING end -->
<!-- GENERAL UTILS begin -->
<!-- 上传组件包 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>${commons-beanutils.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- google java lib -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<!-- jackson json -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- fastjson json <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId>
<version>${fastjson.version}</version> </dependency> -->
<!-- xstream xml -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>${xstream.version}</version>
</dependency>
<!-- pojo copy -->
<dependency>
<groupId>net.sf.dozer</groupId>
<artifactId>dozer</artifactId>
<version>${dozer.version}</version>
</dependency>
<!-- email -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- poi office -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>${poi.version}</version>
</dependency>
<!-- SSH -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.53</version>
</dependency>
<!-- GENERAL UTILS end -->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.9.4</version>
</dependency>
<!-- TEST begin -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- TEST end -->
<!-- User Agent -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>${zip4j.version}</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>${quartz.version}</version>
</dependency>
<!-- 阿里云oss功能 -->
<!-- <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.2</version> </dependency> -->
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>aliyun-openservices</artifactId>
<version>1.0.12</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jdom/jdom -->
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
<!-- 阿里云oss功能 end -->
<!-- 加载本地仓库的自定义jar -->
<!-- <dependency>
<groupId>com.xxx.mail</groupId>
<artifactId>xxx-mail</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/xxx-mail.jar</systemPath>
</dependency> -->
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<outputDirectory>${project.basedir}/src/main/webapp/WEB-INF/classes/</outputDirectory>
<plugins>
<!-- Compiler 插件, 设定JDK版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler.plugin.version}</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
<showWarnings>true</showWarnings>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<!-- 打包jar文件时,配置manifest文件,加入lib包的jar依赖 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${war.plugin.version}</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<!-- war 打包插件, 设定war包名称不带版本号 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${war.plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warSourceExcludes>
resources/compressor*/**,
</warSourceExcludes>
<webappDirectory>${project.build.directory}/${project.artifactId}</webappDirectory>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
<!-- resource插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
</plugin>
<!-- install插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>${install.plugin.version}</version>
</plugin>
<!-- clean插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>${clean.plugin.version}</version>
</plugin>
<!-- ant插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>${antrun.plugin.version}</version>
</plugin>
<!-- dependency插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${dependency.plugin.version}</version>
</plugin>
</plugins>
</build>
<profiles>
<!-- 打包:mvn package -DskipTests -P 环境ID -->
<profile>
<id>dev</id>
<properties>
<db-url><![CDATA[jdbc:mysql://aa.aa.aaa.aaa:3306/db_drds?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true]]></db-url>
<db-username>aaaaaaa</db-username>
<db-password>aaaaaaa</db-password>
<db-url1><![CDATA[jdbc:mysql://aa.aa.aaa.aaa:3308/db_dc?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true]]></db-url1>
<db-username1>aaaaaaa</db-username1>
<db-password1>aaaaaaa</db-password1>
<db-url2><![CDATA[jdbc:mysql://aa.aa.aaa.aaa:3306/db_psd_bs?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true]]></db-url2>
<db-username2>aaaaaaa</db-username2>
<db-password2>aaaaaaa</db-password2>
<ds-decrypt>config.decrypt=false</ds-decrypt>
<!-- redis -->
<redis.host>aa.aa.aaa.aaa</redis.host>
<!-- log4j -->
<logs.basedir>${catalina.base}</logs.basedir>
<!-- logback level -->
<log.level>INFO</log.level>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>${jdk.version}</jdk>
</activation>
</profile>
<profile>
<id>BS</id>
<properties>
<db-url><![CDATA[jdbc:mysql://aa.aa.aaa.a:3306/db_drds?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true]]></db-url>
<db-username>aaaaaa</db-username>
<db-password>aaaaaa</db-password>
<db-url1><![CDATA[jdbc:mysql://aa.aa.aaa.a:3306/db_dc?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true]]></db-url1>
<db-username1>aaaaaa</db-username1>
<db-password1>aaaaaa</db-password1>
<db-url2><![CDATA[jdbc:mysql://aa.aa.aaa.a:3306/db_psd?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true]]></db-url2>
<db-username2>aaaaaa</db-username2>
<db-password2>aaaaaa</db-password2>
<ds-decrypt>config.decrypt=false</ds-decrypt>
<!-- redis -->
<redis.host>aa.aa.aaa.a</redis.host>
<!-- log4j -->
<logs.basedir>${catalina.base}</logs.basedir>
<!-- logback level -->
<log.level>INFO</log.level>
</properties>
</profile>
</profiles>
</project>
3.spring-mvc.xml
配置spring-mvc.xml是整个springmvc的重要步骤,里面主要是三部分:扫描控制器、视图模式、注解启动
<?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" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
<description>Spring MVC Configuration</description>
<!-- 加载配置属性文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:config.properties" />
<!-- 使用Annotation自动注册Bean,只扫描@Controller -->
<context:component-scan base-package="com.xxx.lrt" use-default-filters="false"><!-- base-package 如果多个,用“,”分隔 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 默认的注解映射的支持,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping -->
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters register-defaults="true">
<!-- 将StringHttpMessageConverter的默认编码设为UTF-8 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8" />
<!--property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property-->
</bean>
<!-- 将Jackson2HttpMessageConverter的默认格式化输出为false -->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list><value>application/json;charset=UTF-8</value></list>
</property>
<property name="prettyPrint" value="false"/>
<property name="objectMapper">
<bean class="com.xxx.lrt.frame.core.mapper.JsonMapper"></bean>
</property>
</bean>
<!-- 使用XML格式输出数据 -->
<bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<constructor-arg>
<bean class="org.springframework.oxm.xstream.XStreamMarshaller">
<property name="streamDriver">
<bean class="com.thoughtworks.xstream.io.xml.StaxDriver"/>
</property>
<property name="annotatedClasses">
<list>
<value>com.xxx.lrt.frame.core.entity.BaseEntity</value>
</list>
</property>
</bean>
</constructor-arg>
<property name="supportedMediaTypes" value="application/xml"></property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- REST中根据URL后缀自动判定Content-Type及相应的View -->
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="mediaTypes" >
<map>
<entry key="xml" value="application/xml"/>
<entry key="json" value="application/json"/>
</map>
</property>
<property name="ignoreAcceptHeader" value="true"/>
<property name="favorPathExtension" value="true"/>
</bean>
<!-- thymeleaf start -->
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="${web.view.prefix}" />
<property name="suffix" value="${web.view.suffix}" />
<property name="templateMode" value="HTML5" />
<property name="cacheable" value="false" />
<property name="characterEncoding" value="UTF-8"/>
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<property name="additionalDialects">
<set>
<!-- thymeleaf 使用shiro标签 -->
<bean class="at.pollux.thymeleaf.shiro.dialect.ShiroDialect"/>
<!-- 自定义标签 -->
<bean class="com.xxx.lrt.thymeleaf.fns.dialect.FnsDialect"/>
<!-- 自定义工具对象 -->
<bean class="com.xxx.lrt.thymeleaf.fns.dialect.UserUtilsDialect"/>
</set>
</property>
</bean>
<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
<property name="characterEncoding" value="UTF-8" />
</bean>
<!-- thymeleaf end -->
<!-- 定义视图文件解析 -->
<!-- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="${web.view.prefix}"/>
<property name="suffix" value="${web.view.suffix}"/>
</bean> -->
<!-- 对静态资源文件的访问, 将无法mapping到Controller的path交给default servlet handler处理 -->
<mvc:default-servlet-handler />
<!-- 静态资源映射 -->
<mvc:resources mapping="/resources/**" location="/resources/" cache-period="31536000"/>
<!-- 定义无Controller的path<->view直接映射 -->
<mvc:view-controller path="/" view-name="redirect:${web.view.index}"/>
<!-- 拦截器配置 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<mvc:exclude-mapping path="/"/>
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/sys/menu/tree"/>
<mvc:exclude-mapping path="/sys/menu/treeData"/>
<bean class="com.xxx.lrt.modules.sys.interceptor.LogInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
<!-- 支持Shiro对Controller的方法级AOP安全控制 begin-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.apache.shiro.authz.UnauthorizedException">error/403</prop>
<prop key="java.lang.Throwable">error/500</prop>
</props>
</property>
</bean>
<!-- 支持Shiro对Controller的方法级AOP安全控制 end -->
<!-- 上传文件拦截,设置最大上传文件大小 10M=10*1024*1024(B)=10485760 bytes -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
</beans>
4.spring-context.xml
配置内容为融合mybatis(数据源、注解扫描、sqlSession工厂注册、事务),缓存配置、懒加载、aop切片配置
<?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" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.3.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"
default-lazy-init="true">
<description>Spring Configuration</description>
<!-- 加载配置属性文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:config.properties" />
<!-- 加载应用属性实例,可通过 @Value("#{APP_PROP['jdbc.driver']}") String jdbcDriver 方式引用 -->
<util:properties id="APP_PROP" location="classpath:config.properties" local-override="true"/>
<!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。 -->
<context:component-scan base-package="com.xxx.lrt"><!-- base-package 如果多个,用“,”分隔 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- MyBatis begin -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.xxx.lrt"/>
<property name="typeAliasesSuperType" value="com.xxx.lrt.frame.core.entity.BaseEntity"/>
<property name="mapperLocations" value="classpath:/mappings/**/**/*.xml"/>
<property name="configLocation" value="classpath:/mybatis-config.xml"></property>
</bean>
<!-- 扫描basePackage下所有以@MyBatisDao注解的接口 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<property name="basePackage" value="com.xxx.lrt"/>
<property name="annotationClass" value="com.xxx.lrt.frame.core.annotation.MyBatisDao"/>
</bean>
<!-- 定义事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 配置 Annotation 驱动,扫描@Transactional注解的类定义事务 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- MyBatis end -->
<!-- 配置 JSR303 Bean Validator 定义 -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<!-- 缓存配置 -->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:${ehcache.configFile}" />
</bean>
<!-- 计划任务配置,用 @Service @Lazy(false)标注类,用@Scheduled(cron = "0 0 2 * * ?")标注方法 -->
<task:executor id="executor" pool-size="10"/>
<task:scheduler id="scheduler" pool-size="10"/>
<task:annotation-driven scheduler="scheduler" executor="executor" proxy-target-class="true"/>
<!-- 动态配置数据源 -->
<bean id="dataSource" class="com.xxx.lrt.frame.core.datasource.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="defaultDataSource" key="defaultDataSource"></entry>
<entry value-ref="dcDataSource" key="dcDataSource"></entry>
<entry value-ref="ztmDataSource" key="ztmDataSource"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="defaultDataSource"></property>
</bean>
<!-- 数据源配置, 使用 druid 数据库连接池 -->
<bean id="defaultDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.pool.init}" />
<property name="minIdle" value="${jdbc.pool.minIdle}" />
<property name="maxActive" value="${jdbc.pool.maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="${jdbc.testSql}" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)-->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
<!-- 配置监控统计拦截的filters,stat,slf4j -->
<property name="filters" value="stat,config" />
<property name="connectionProperties" value="${config.decrypt}" />
</bean>
<!-- 数据源配置, 使用 druid 数据库连接池 DC -->
<bean id="dcDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc1.url}" />
<property name="username" value="${jdbc1.username}" />
<property name="password" value="${jdbc1.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.pool.init}" />
<property name="minIdle" value="${jdbc.pool.minIdle}" />
<property name="maxActive" value="${jdbc.pool.maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="${jdbc.testSql}" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)-->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
<!-- 配置监控统计拦截的filters,stat,slf4j -->
<property name="filters" value="stat,config" />
<property name="connectionProperties" value="${config.decrypt}" />
</bean>
<!-- 数据源配置, 使用 druid 数据库连接池 ZTM-->
<bean id="ztmDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="${jdbc.driver}" />
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc2.url}" />
<property name="username" value="${jdbc2.username}" />
<property name="password" value="${jdbc2.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.pool.init}" />
<property name="minIdle" value="${jdbc.pool.minIdle}" />
<property name="maxActive" value="${jdbc.pool.maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<property name="validationQuery" value="${jdbc.testSql}" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)-->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
<!-- 配置监控统计拦截的filters,stat,slf4j -->
<property name="filters" value="stat,config" />
<property name="connectionProperties" value="${config.decrypt}" />
</bean>
<!-- 多数据源 aop -->
<bean id="dataSourceAspect" class="com.xxx.lrt.frame.core.datasource.DataSourceAspect" />
<aop:config>
<aop:advisor pointcut="execution(* com.xxx.lrt.modules.*.service.*.*(..))" advice-ref="dataSourceAspect" order="1"/>
</aop:config>
</beans>
5.mybatis-config.xml
这个在上一篇专门讲mybatis的文章里已经提到过了,这里整理各配置文件就再放一遍,中间很多别名就省略掉,保留一个格式例样:
<?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>
<!-- 全局参数 -->
<settings>
<!-- 使全局的映射器启用或禁用缓存。 -->
<setting name="cacheEnabled" value="true"/>
<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 -->
<setting name="aggressiveLazyLoading" value="true"/>
<!-- 是否允许单条sql 返回多个数据集 (取决于驱动的兼容性) default:true -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
<setting name="useColumnLabel" value="true"/>
<!-- 允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。 default:false -->
<setting name="useGeneratedKeys" value="false"/>
<!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不映射 PARTIAL:部分 FULL:全部 -->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!-- 这是默认的执行类型 (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句;BATCH: 执行器可以重复执行语句和批量更新) -->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 使用驼峰命名法转换字段。 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 设置本地缓存范围 session:就会有数据的共享 statement:语句范围 (这样就不会有数据的共享 ) defalut:session -->
<setting name="localCacheScope" value="SESSION"/>
<!-- 设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER,插入空值时不需要指定类型 -->
<setting name="jdbcTypeForNull" value="NULL"/>
<!-- 打印SQL -->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<!-- 类型别名 -->
<typeAliases>
<typeAlias alias="Page" type="com.xxx.lrt.frame.core.entity.Page" /><!--分页 -->
</typeAliases>
<!-- 插件配置 -->
<plugins>
<plugin interceptor="com.xxx.lrt.frame.core.dao.interceptor.PaginationInterceptor">
<property name="jdbcType" value="mysql"/>
</plugin>
</plugins>
</configuration>
6.mybatis-refresh.properties
还有个mybatis配置文件,文件增量动态刷新,注意路径,结合上文路径图片:
# enabled
enabled=true
# project start time[\u9879\u76ee\u542f\u52a8\u65f6\u95f4]
delaySeconds=5
# xml scanning interval time[\u626b\u63cf\u95f4\u9694\u65f6\u957f]
sleepSeconds=2
# xml file's path[xml\u6587\u4ef6\u7684\u8def\u5f84]
mappingPath=mappings
7.config.properties
一个基础配置xml文件,里面包含jdbc、redis的配置信息,发现csdn没有properties格式,看上去有点眼花,凑合看吧(后面看到#注释突然想起来可以改成python格式):
#============================#
#===== Database sttings =====#
#============================#
#mysql database setting
jdbc.type=mysql
jdbc.driver=com.mysql.jdbc.Driver
#jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
jdbc.url=${db-url}
jdbc.username=${db-username}
jdbc.password=${db-password}
jdbc1.type=mysql
jdbc1.driver=com.mysql.jdbc.Driver
#jdbc.url=jdbc:mysql://localhost:3306/db_dc?useUnicode=true&characterEncoding=utf-8
jdbc1.url=${db-url1}
jdbc1.username=${db-username1}
jdbc1.password=${db-password1}
jdbc2.type=mysql
jdbc2.driver=com.mysql.jdbc.Driver
#jdbc.url=jdbc:mysql://localhost:3306/db_psd?useUnicode=true&characterEncoding=utf-8
jdbc2.url=${db-url2}
jdbc2.username=${db-username2}
jdbc2.password=${db-password2}
#jdbc3.type=mysql
#jdbc3.driver=com.mysql.jdbc.Driver
##jdbc.url=jdbc:mysql://localhost:3306/db_power?useUnicode=true&characterEncoding=utf-8
#jdbc3.url=${db-url3}
#jdbc3.username=${db-username3}
#jdbc3.password=${db-password3}
#pool settings
jdbc.pool.init=1
jdbc.pool.minIdle=10
jdbc.pool.maxActive=30
#jdbc.testSql=SELECT 'x'
jdbc.testSql=SELECT 'x' FROM DUAL
config.decrypt=${ds-decrypt}
#udp bind port
server.bind.port=8088
server.ip=${server.ip}
client.timeout=30
group.threads=${group.threads}
worker.threads=20
data.persist=true
task.thread.count=10
#============================#
#===== System settings ======#
#============================#
#\u4ea7\u54c1\u4fe1\u606f\u8bbe\u7f6e
productName=\u7ef4\u62a4\u4fdd\u517b\u7cfb\u7edf
copyrightYear=2018
version=V1.0.0
#\u5f53\u524d\u53d1\u5e03\u7684\u7cfb\u7edf\u4ee3\u7801,\u52a0\u8f7d\u83dc\u5355,\u6743\u9650
system.code=MSAPP
#\u7f51\u7ad9URL\u540e\u7f00
urlSuffix=.html
#\u662f\u5426\u4e0d\u5141\u8bb8\u5237\u65b0\u4e3b\u9875\uff0c\u4e0d\u5141\u8bb8\u60c5\u51b5\u4e0b\uff0c\u5237\u65b0\u4e3b\u9875\u4f1a\u5bfc\u81f4\u91cd\u65b0\u767b\u5f55
notAllowRefreshIndex=false
#\u662f\u5426\u5141\u8bb8\u591a\u8d26\u53f7\u540c\u65f6\u767b\u5f55
user.multiAccountLogin=true
#\u5206\u9875\u914d\u7f6e
page.pageSize=10
#rememberMe checkbox
login.rememberMe=true
#============================#
#==== Framework settings ====#
#============================#
#\u4f1a\u8bdd\u8d85\u65f6\uff0c \u5355\u4f4d\uff1a\u6beb\u79d2\uff0c 20m=1200000ms, 30m=1800000ms, 60m=3600000ms
session.sessionTimeout=1800000
#\u4f1a\u8bdd\u6e05\u7406\u95f4\u9694\u65f6\u95f4\uff0c \u5355\u4f4d\uff1a\u6beb\u79d2\uff0c2m=120000ms\u3002
session.sessionTimeoutClean=120000
#\u7f13\u5b58\u8bbe\u7f6e
ehcache.configFile=cache/ehcache-local.xml
#ehcache.configFile=cache/ehcache-rmi.xml
#\u7d22\u5f15\u9875\u8def\u5f84
web.view.index=index
#\u89c6\u56fe\u6587\u4ef6\u5b58\u653e\u8def\u5f84
web.view.prefix=/WEB-INF/views/
web.view.suffix=.html
#\u6700\u5927\u6587\u4ef6\u4e0a\u4f20\u9650\u5236\uff0c\u5355\u4f4d\u5b57\u8282. 10M=10*1024*1024(B)=10485760 bytes\uff0c\u9700\u540c\u6b65\u4fee\u6539\uff1ackfinder.xml
web.maxUploadSize=10485760
web.tmpDir=${file.tmpdir}
#\u9759\u6001\u6587\u4ef6\u540e\u7f00
web.staticFile=.css,.js,.png,.jpg,.gif,.jpeg,.bmp,.ico,.swf,.psd,.htc,.htm,.html,.crx,.xpi,.exe,.ipa,.apk
#upload userfiles basedir, \u8def\u5f84\u4e2d\u4e0d\u5141\u8bb8\u5305\u542b\u201cuserfiles\u201d
#userfiles.basedir=D:/userfiles
#redis settings
redis.keyPrefix=RTDATA_
redis.host=${redis.host}
redis.port=xxxx
redis.timeout=3000
redis.password=xxxxxxxxxx
#\u6700\u5927\u7a7a\u95f2\u6570
redis.maxIdle=300
#\u63a7\u5236\u4e00\u4e2apool\u53ef\u5206\u914d\u591a\u5c11\u4e2ajedis\u5b9e\u4f8b,\u7528\u6765\u66ff\u6362\u4e0a\u9762\u7684redis.maxActive,\u5982\u679c\u662fjedis 2.4\u4ee5\u540e\u7528\u8be5\u5c5e\u6027
redis.maxTotal=1000
#\u8fde\u63a5\u6c60\u7684\u6700\u5927\u6570\u636e\u5e93\u8fde\u63a5\u6570\u3002\u8bbe\u4e3a0\u8868\u793a\u65e0\u9650\u5236,\u5982\u679c\u662fjedis 2.4\u4ee5\u540e\u7528redis.maxTotal
#redis.maxActive=600
#\u6700\u5927\u5efa\u7acb\u8fde\u63a5\u7b49\u5f85\u65f6\u95f4\u3002\u5982\u679c\u8d85\u8fc7\u6b64\u65f6\u95f4\u5c06\u63a5\u5230\u5f02\u5e38\u3002\u8bbe\u4e3a-1\u8868\u793a\u65e0\u9650\u5236\u3002
redis.maxWaitMillis=1000
#\u8fde\u63a5\u7684\u6700\u5c0f\u7a7a\u95f2\u65f6\u95f4 \u9ed8\u8ba41800000\u6beb\u79d2(30\u5206\u949f)
redis.minEvictableIdleTimeMillis=300000
#\u6bcf\u6b21\u91ca\u653e\u8fde\u63a5\u7684\u6700\u5927\u6570\u76ee,\u9ed8\u8ba43
redis.numTestsPerEvictionRun=1024
#\u9010\u51fa\u626b\u63cf\u7684\u65f6\u95f4\u95f4\u9694(\u6beb\u79d2) \u5982\u679c\u4e3a\u8d1f\u6570,\u5219\u4e0d\u8fd0\u884c\u9010\u51fa\u7ebf\u7a0b, \u9ed8\u8ba4-1
redis.timeBetweenEvictionRunsMillis=30000
#\u662f\u5426\u5728\u4ece\u6c60\u4e2d\u53d6\u51fa\u8fde\u63a5\u524d\u8fdb\u884c\u68c0\u9a8c,\u5982\u679c\u68c0\u9a8c\u5931\u8d25,\u5219\u4ece\u6c60\u4e2d\u53bb\u9664\u8fde\u63a5\u5e76\u5c1d\u8bd5\u53d6\u51fa\u53e6\u4e00\u4e2a
redis.testOnBorrow=true
#\u5728\u7a7a\u95f2\u65f6\u68c0\u67e5\u6709\u6548\u6027, \u9ed8\u8ba4false
redis.testWhileIdle=true
8. spring-context-redis.xml
这算是一个子配置文件吧,专门给redis做配置的,包含注册jedis各种类的工厂:
<?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" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"
default-lazy-init="true">
<description>Jedis Configuration</description>
<!-- 加载配置文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:config.properties" />
<!-- redis连接池配置-->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" >
<!--最大空闲数-->
<property name="maxIdle" value="${redis.maxIdle}" />
<!--连接池的最大数据库连接数 -->
<property name="maxTotal" value="${redis.maxTotal}" />
<!--最大建立连接等待时间-->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!--逐出连接的最小空闲时间 默认1800000毫秒(30分钟)-->
<property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}" />
<!--每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3-->
<property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}" />
<!--逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1-->
<property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}" />
<!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
<!--在空闲时检查有效性, 默认false -->
<property name="testWhileIdle" value="${redis.testWhileIdle}" />
</bean >
<!--redis连接工厂 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
<property name="poolConfig" ref="jedisPoolConfig" />
<!--IP地址 -->
<property name="hostName" value="${redis.host}" />
<!--端口号 -->
<property name="port" value="${redis.port}" />
<!--如果Redis设置有密码 -->
<property name="password" value="${redis.password}" />
<!--客户端超时时间单位是毫秒 -->
<property name="timeout" value="${redis.timeout}" />
</bean>
<!--redis操作模版,使用该对象可以操作redis -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
<property name="connectionFactory" ref="jedisConnectionFactory" />
<!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String! -->
<property name="keySerializer" >
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer" >
<!--bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" /-->
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<!--bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/-->
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<!--开启事务 -->
<property name="enableTransactionSupport" value="true"></property>
</bean >
<!--自定义redis工具类,在需要缓存的地方注入此类 -->
<bean id="jedisUtils" class="com.xxx.lrt.frame.core.utils.JedisUtils">
<property name="redisTemplate" ref="redisTemplate" />
</bean>
</beans>
9.spring-context-shiro.xml
也是一个子配置文件,专门给shiro安全框架配置的,shiro是很有意思的安全框架,后面找时间专门开专题研究一下,这里简单说一下shiro的配置和spring集成:
<?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:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<description>Shiro Configuration</description>
<!-- 加载配置属性文件 -->
<context:property-placeholder ignore-unresolvable="true" location="classpath:config.properties, classpath:shiro.properties" />
<!-- 安全认证过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<!-- 设定用户的登录链接,这里为cas登录页面的链接地址可配置回调地址 -->
<property name="loginUrl" value="${shiro.loginUrl}" />
<property name="filters">
<map>
<!-- 添加casFilter到shiroFilter -->
<entry key="casFilter" value-ref="casFilter" />
<entry key="logoutFilter" value-ref="logoutFilter" />
<entry key="kickout" value-ref="kickoutSessionControlFilter"/>
<entry key="custFilter">
<bean class="com.xxx.bs.modules.sys.security.CustomAuthenticationFilter"/>
</entry>
</map>
</property>
<property name="filterChainDefinitions">
<value>
/resources/** = anon
/test.jsp = anon
/userfiles/** = anon
/dataservice/** = anon
/servlet/validateCodeServlet = anon
/ie.html = anon
/kickout = anon
/lrtsso = casFilter
<!-- /lrtsso = anon -->
/logout = logoutFilter
/** = kickout, custFilter, user
<!-- /** = anon -->
</value>
</property>
</bean>
<!-- 登录限制 -->
<bean id="kickoutSessionControlFilter" class="com.xxx.bs.frame.core.security.shiro.filter.KickoutSessionControlFilter">
<property name="kickoutUrl" value="${shiro.kickout.url}"/>
</bean>
<bean id="casFilter" class="org.apache.shiro.cas.CasFilter">
<!-- 配置验证成功的URL -->
<property name="successUrl" value="${shiro.successUrl}" />
<!-- 配置验证错误时的失败URL -->
<property name="failureUrl" value="${shiro.failureUrl}" />
</bean>
<bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
<!-- 配置验证错误时的失败页面 -->
<property name="redirectUrl" value="${shiro.logoutUrl}" />
</bean>
<bean id="casRealm" class="com.xxx.bs.modules.sys.security.SystemAuthorizingRealm">
<property name="cachingEnabled" value="true"/>
<property name="authenticationCachingEnabled" value="true"/>
<property name="authenticationCacheName" value="authenticationCache"/>
<property name="authorizationCachingEnabled" value="true"/>
<property name="authorizationCacheName" value="authorizationCache"/>
<!-- cas服务端地址前缀 -->
<property name="casServerUrlPrefix" value="${shiro.cas.serverUrlPrefix}" />
<!-- 应用服务地址,用来接收cas服务端票据 -->
<property name="casService" value="${shiro.cas.service}" />
<property name="cacheManager" ref="shiroCacheManager"/>
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="casRealm" />
<!-- <property name="sessionManager" ref="sessionManager" /> -->
<property name="cacheManager" ref="shiroCacheManager"/>
<property name="subjectFactory" ref="casSubjectFactory"/>
</bean>
<bean id="casSubjectFactory" class="org.apache.shiro.cas.CasSubjectFactory"></bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
<!-- 会话DAO -->
<bean id="sessionDAO" class="com.xxx.bs.frame.core.security.shiro.session.CacheSessionDAO">
<!-- <property name="sessionIdGenerator" ref="idGen" /> -->
<property name="activeSessionsCacheName" value="activeSessionsCache" />
<property name="cacheManager" ref="shiroCacheManager" />
</bean>
<!-- 定义授权缓存管理器 -->
<!-- <bean id="shiroCacheManager" class="com.xxx.bs.frame.core.security.shiro.cache.JedisCacheManager" /> -->
<bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManager" ref="cacheManager"/>
</bean>
<!-- 自定义会话管理配置 -->
<bean id="sessionManager" class="com.xxx.bs.frame.core.security.shiro.session.SessionManager">
<!-- 会话超时时间,单位:毫秒 -->
<property name="globalSessionTimeout" value="${session.sessionTimeout}"/>
<!-- 定时清理失效会话, 清理用户直接关闭浏览器造成的孤立会话 -->
<property name="sessionValidationInterval" value="${session.sessionTimeoutClean}"/>
<property name="sessionDAO" ref="sessionDAO"/>
</bean>
<!-- AOP式方法级权限检查 -->
<!-- <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> -->
<!-- <property name="proxyTargetClass" value="true" /> -->
<!-- </bean> -->
<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"></property>
<property name="arguments" ref="securityManager"></property>
</bean>
</beans>
这里有个注意的地方,当我们进行后台自己的接口调试时,用JUnit进行模拟https请求,这个时候我们一般直接用url访问要调试的接口,而不是通过网页登录的方式去进入指定页面来调用目标接口(虽然这也是一种方法,但是没有JUNIT直接调用来的方便)。在不登录的情况下,一般是无法通过shiro的安全验证的,所以这时候我们需要将过滤器的lrtsso设置为anon,在shiro中anon代表无需认证即可访问,authc代表需要认证才可访问。同时把/**也调整为anon。
10.shiro.properties
shiro的配置文件,这里如果需要启动shiro是需要一个叫做cas的服务的,那里面写了shiro的具体内容,晚点专门讲一下。
#localhost
#shiro.loginUrl=http://localhost:8080/cas/login?service=http://localhost:7009/xxx-lrt-cas-sris/lrtsso
#shiro.logoutUrl=http://localhost:8080/cas/logout?service=http://localhost:7009/xxx-lrt-cas-sris/lrtsso
#shiro.cas.serverUrlPrefix=http://localhost:8080/cas
#shiro.cas.service=http://localhost:7009/xxx-lrt-cas-sris/lrtsso
shiro.loginUrl=${shiro.login.url}
shiro.logoutUrl=${shiro.logout.url}
shiro.cas.serverUrlPrefix=${shiro.cas.server.url.prefix}
shiro.cas.service=${shiro.cas.service}
shiro.successUrl=/index
shiro.failureUrl=/index
11.logback.xml
日志
<configuration>
<contextName>aaaaaaaaaa</contextName>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %-5level %logger{0} - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logs.basedir}/logs/maintaining-system.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logs.basedir}/logs/maintaining-system.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>15</maxHistory>
</rollingPolicy>
<encoder>
<charset>UTF-8</charset>
<pattern>%d %-5level %logger{0} - %msg%n</pattern>
</encoder>
</appender>
<logger name="com.xxx.bs" level="INFO" />
<logger name="org.springframework" level="INFO"/>
<logger name="org.apache.ibatis.logging.jdbc" level="DEBUG"/>
<logger name="com.xxx.bs.frame.core.security.shiro" level="WARN"/>
<logger name="org.apache.shiro.session.mgt" level="WARN"/>
<logger name="ch.qos.logback" level="INFO"/>
<logger name="org.quartz" level="INFO"/>
<logger name="io.netty" level="INFO"/>
<logger name="com.alibaba.druid" level="INFO"/>
<logger name="com.x.bs.modules.sys.interceptor" level="INFO" />
<logger name="com.x.bs.frame.core.datasource" level="DEBUG" />
<logger name="com.x.bs.frame.core.utils.excel" level="INFO" />
<logger name="com.x.bs.frame.core.utils.JedisUtils" level="INFO" />
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
二.项目整体结构
前面已经附上了所有的配置文件内容,再来回顾以下项目的整体结构情况。
整体上后台代码有三个大目录,分别是src/main/java后台逻辑代码、src/test/java后台测试代码、src/main/resources后台配置文件,前面讲的大部分配置文件都是在resources路径下。
我们先来看逻辑代码modules目录下分级,可以看到有dao、entity、service、util、vo、web等分级,timedTask这里我单独放了个定时任务,不多讲了。其中serice里面还有一层impl:
这个impl是真正的实现层,里面autowired注解装载dao层的bean,并且用implements对service进行接口重写。最重要的就是dao、service、impl、controller,我们来看以下完整的一次web请求。
1.前端请求
使用http请求,前端针对不同的页面功能,请求不同的url,如果有参数,则同时ajax发送参数给后台。DNS解析域名得到IP和端口,我这里倒是没有用域名,直接就是IP+端口,端口是8081。tomcat主动问询得到8081的端口后占用此端口,tomcat大家都知道,一个web容器,作用就是将请求交给对应的servlet。那么在SSM里,tomcat交给哪个servlet呢?
回顾一下前文web.xml的配置,就会看到一个叫做DispatcherServlet的分发器,在《SSM框架梳理(一)SpringMVC工作流程》里,我们已经讲过,DispatcherServlet是SpringMVC毫无疑问的核心,分发器,要协调命令其他组件去处理已经返回响应工作。在tomcat启动的时候,web.xml会被加载,这个时候SpringMVC的IOC容器也就生成了,DispatcherServlet可用。
至于DispatcherServlet拿到请求后如何调用其他组件,调用了什么组件,在《SSM框架梳理(一)SpringMVC工作流程》内也提过,这里不再提,我们直接跳到Controller。
在SrpingMVC里,controller的作用就是调用service层,并且最终返回结果,看下代码实例:
@Controller
@RequestMapping(value = "/UpdateLine")
public class UpdateLineController extends BaseController {
@Autowired
private UpdateLineService updateLineService;
@ResponseBody
@RequestMapping(value = "/selectLineList", method = { RequestMethod.POST, RequestMethod.GET })
public ResultEntity selectLineList(QueryParam queryParam, HttpServletRequest request,
HttpServletResponse response, Model model) {
logger.info("进入 selectLineList 接口");
ResultEntity result = new ResultEntity();
List<LineEntity> listresult = updateLineService.selectLineList(queryParam);
result.setRebackResult(Constants.REBACK_RESULT_SUCCESS);
result.setRebackDesc(Constants.ERROR_STATU_NORMAL);
result.setListInfo(listresult);
return result;
}
}
上面是controller的代码,可以看到,首先第一件事,就是在这个类前加@controller的注解,目的是让spring扫描。两个requestMapping组合起来就是UpdateLine/selectLineList,也就是前端请求的url,也正式根据这两个mapping,spring才能准确地找到这个controller以及controller内对应的方法。然后我用@Autowired注解,装载了UpdateLineService这个bean,然后在具体方法内List<LineEntity> listresult = updateLineService.selectLineList(queryParam);调用了改bean内的方法。
我们看UpdateLineService这个类:
public interface UpdateLineService {
public List<LineEntity> selectLineList(QueryParam queryParam);
}
很简单,主要的实现在impl,这个service只不过是一个壳,一个调用接口,impl内会重写这个接口,我们转到对应的impl去:
@Service
@Transactional(readOnly = false)
public class UpdateLineServiceImpl extends BaseService implements UpdateLineService {
@Autowired
private UpdateLineDao updateLineDao;
@Override
public List<LineEntity> selectLineList(QueryParam queryParam) {
List<LineEntity> result = updateLineDao.selectLineList(queryParam);
return result;
}
}
impl文件跟controller一样,一开始先是@service实现层的注解,可见这才是真正的实现层,service里是没有加的,@Transactional(readOnly = false)这就是一个事务控制的注解,设计到数据库的隔离级别,readonly是隔离等级最低的,我设置为false,是因为默认是true,而我这里除了读之外还需要增删改(其他方法没有贴出来),所以不能让readonly=true,要不然报错。然后同样是@Autowired装载bean,这里装载的就是dao层的类了,因为service调用dao层去执行sql语句。最后List<LineEntity> result = updateLineDao.selectLineList(queryParam);调用dao层方法,我们转入dao层:
@MyBatisDao
public interface UpdateLineDao {
public List<LineEntity> selectLineList(QueryParam queryParam);
}
首先还是一个MyBatisDao的注解,这个MyBatisDao注解是我们自己写的注解,看一下在spring-context.xml里是怎么配置的,前文也有:
<!-- 扫描basePackage下所有以@MyBatisDao注解的接口 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<property name="basePackage" value="com.xxx.lrt"/>
<property name="annotationClass" value="com.xxx.lrt.frame.core.annotation.MyBatisDao"/>
</bean>
再去这个类里看看,annotationClass:
/**
* 标识MyBatis的DAO,方便{@link org.mybatis.spring.mapper.MapperScannerConfigurer}的扫描。
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyBatisDao {
}
好了看完这个注解的实现,我们回到dao层,public List<LineEntity> selectLineList(QueryParam queryParam);依旧是这个方法,有入参有返回值类型,但是跟service和controller不一样,dao层没得东西@Autowired装载了,也没得其他类的调用了,因为他映射到放这sql语句的xml文件去了。这个xml文件路径前头也说过:src\main\resources\mappings\modules\maintain\UpdateLineDao.xml
看下xml里面的内容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxx.bs.modules.maintain.dao.UpdateLineDao">
<select id="selectLineList" parameterType="QueryParam" resultType="LineEntity">
SELECT
a.line_id AS lineId,
b.FULL_NAME AS lineName
FROM
t_sys_user_line a,
t_rail_line b,
t_sys_user c
WHERE
a.line_id = b.line_id
AND a.user_id = c.user_id
<choose>
<when test="userId==1">
AND c.code = 'super'
</when>
<when test="userId==5224">
AND c.code = 'admin'
</when>
<otherwise>
AND c.code = #{userId}
</otherwise>
</choose>
</select>
</mapper>
可以看到,首先<mapper namespace="com.xxx.bs.modules.maintain.dao.UpdateLineDao">这一样,指定了映射对象的绝对路径,然后这个select语句的id就是dao层的方法名,这个一定要对上,要不然就无法映射上。parameterType="QueryParam" resultType="LineEntity">这里是指入参类型和返回值类型,这里我采用了别称,他们的指向在mybatis-config.xml内声明:<typeAlias alias="LineEntity" type="com.xxx.bs.modules.maintain.entity.LineEntity" />,如果不想在mybatis的配置文件里声明别称,那就直接在映射文件里写绝对路径即可,也不是非要写别称。这里执行完之后,用LineEntity这个对象的格式返回来,dao层包装成List<LineEntity>的格式,在controller包装进了resultEntity的标准格式内,方便前端进行处理。
至此一次完整的、简单的web请求就结束了,后台这边返回了目标数据。