基于Spring + Spring MVC + Mybatis 高性能web构建实例详解

一直想写这篇文章,前段时间痴迷于JavaScript、NodeJs、AngularJS,做了大量的研究,对前后端交互有了更深层次的认识。

今天抽个时间写这篇文章,我有预感,这将是一篇很详细的文章,详细的配置,详细的注释,看起来应该很容易懂。

用最合适的技术去实现,并不断追求最佳实践。这就是架构之道。

希望这篇文章能给你们带来一些帮助,同时希望你们可以为这个项目贡献你的想法。

源码地址:https://github.com/Eliteams/quick4j 点击打开

源码地址:https://github.com/Eliteams/quick4j 点击打开

源码地址:https://github.com/Eliteams/quick4j 点击打开

看我们的项目结构:

是一个典型的Maven 项目 :

src/main/Java:存放java源文件

src/main/resources:存放程序资源、配置文件

src/test/java:存放测试代码文件

src/main/webapp:web根目录

pom.xml : maven项目配置文件,管理依赖,编译,打包

主要的后端架构:spring + Spring MVC + Mybatis + Apache Shiro

前端界面主要使用MetroNic 模板,

先看我们搭建完成,跑起来的效果,这样你才有兴趣看下去:

你可以 在github 上 checkout quick4j项目 查看 ,并跟下面步骤 来搭建:

强烈建议你,checkout  https://github.com/Eliteams/quick4j ,在本地跑起来,再试着自己搭建框架

1、首先创建 maven 项目 ,用 idea 、eclipse 或 mvn 命令行都行

2、配置 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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.eliteams</groupId>
  <artifactId>quick4j</artifactId>
  <packaging>war</packaging>
  <version>1.0.0</version>
  <name>quick4j App</name>
  <url>https://github.com/starzou/quick4j</url>
  <build>
    <finalName>quick4j</finalName>
    <plugins>
      <!-- Mybatis generator代码生成插件 配置 -->
      <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>${plugin.mybatis.generator}</version>
        <configuration>
          <configurationFile>${mybatis.generator.generatorConfig.xml}</configurationFile>
          <overwrite>true</overwrite>
          <verbose>true</verbose>
        </configuration>
      </plugin>
      <!--Maven编译插件 配置-->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${plugin.maven-compiler}</version>
        <configuration>
          <source>${project.build.jdk}</source>
          <target>${project.build.jdk}</target>
          <encoding>${project.build.sourceEncoding}</encoding>
        </configuration>
      </plugin>
    </plugins>
    <!--配置Maven 对resource文件 过滤 -->
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>true</filtering>
      </resource>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>
  <properties>
    <!-- base setting -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.build.locales>zh_CN</project.build.locales>
    <project.build.jdk>1.7</project.build.jdk>
    <!-- plugin setting -->
    <mybatis.generator.generatorConfig.xml>${basedir}/src/test/resources/generatorConfig.xml</mybatis.generator.generatorConfig.xml>
    <mybatis.generator.generatorConfig.properties>file:///${basedir}/src/test/resources/generatorConfig.properties</mybatis.generator.generatorConfig.properties>
    <!-- plugin versions -->
    <plugin.mybatis.generator>1.3.1</plugin.mybatis.generator>
    <plugin.maven-compiler>3.1</plugin.maven-compiler>
    <!-- lib versions -->
    <junit.version>4.11</junit.version>
    <spring.version>4.0.2.RELEASE</spring.version>
    <mybatis.version>3.2.2</mybatis.version>
    <mybatis.spring.version>1.2.2</mybatis.spring.version>
    <mysql.connector.version>5.1.30</mysql.connector.version>
    <postgresql.version>9.1-901.jdbc4</postgresql.version>
    <slf4j.version>1.6.6</slf4j.version>
    <log4j.version>1.2.12</log4j.version>
    <httpclient.version>4.1.2</httpclient.version>
    <jackson.version>1.9.13</jackson.version>
    <c3p0.version>0.9.1.2</c3p0.version>
    <druid.version>1.0.5</druid.version>
    <tomcat.jdbc.version>7.0.53</tomcat.jdbc.version>
    <jstl.version>1.2</jstl.version>
    <google.collections.version>1.0</google.collections.version>
    <cglib.version>3.1</cglib.version>
    <shiro.version>1.2.3</shiro.version>
    <commons.fileupload.version>1.3.1</commons.fileupload.version>
    <commons.codec.version>1.9</commons.codec.version>
    <commons.net.version>3.3</commons.net.version>
    <aspectj.version>1.6.12</aspectj.version>
    <netty.version>4.0.18.Final</netty.version>
    <hibernate.validator.version>5.1.1.Final</hibernate.validator.version>
  </properties>
  <dependencies>
    <!-- junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
    </dependency>
    <!-- springframe start -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-oxm</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</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-aop</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-test</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- springframe end -->
    <!-- mybatis start-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${mybatis.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>${mybatis.spring.version}</version>
    </dependency>
    <!--mybatis end-->
    <!-- mysql-connector -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.connector.version}</version>
    </dependency>
    <!-- DruidDataSource -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>${druid.version}</version>
    </dependency>
    <!-- jackson -->
    <dependency>
      <groupId>org.codehaus.jackson</groupId>
      <artifactId>jackson-mapper-asl</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <!-- log start -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <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>
    <!-- log end -->
    <!-- servlet api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
    <!-- jstl -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>${jstl.version}</version>
    </dependency>
    <!-- start apache -->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>${commons.fileupload.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>${httpclient.version}</version>
    </dependency>
    <dependency>
      <groupId>commons-codec</groupId>
      <artifactId>commons-codec</artifactId>
      <version>${commons.codec.version}</version>
    </dependency>
    <dependency>
      <groupId>commons-net</groupId>
      <artifactId>commons-net</artifactId>
      <version>${commons.net.version}</version>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.3</version>
    </dependency>
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.2.1</version>
    </dependency>
    <!-- end apache -->
    <!-- google -->
    <dependency>
      <groupId>com.google.collections</groupId>
      <artifactId>google-collections</artifactId>
      <version>${google.collections.version}</version>
    </dependency>
    <!-- cglib -->
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib-nodep</artifactId>
      <version>${cglib.version}</version>
    </dependency>
    <!-- shiro -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</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-core</artifactId>
      <version>${shiro.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-web</artifactId>
      <version>${shiro.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-quartz</artifactId>
      <version>${shiro.version}</version>
    </dependency>
    <!-- aspectjweaver -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>${aspectj.version}</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>${aspectj.version}</version>
    </dependency>
    <!-- hibernate-validator -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>${hibernate.validator.version}</version>
    </dependency>
    <!-- netty -->
    <dependency>
      <groupId>io.netty</groupId>
      <artifactId>netty-all</artifactId>
      <version>${netty.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis.generator</groupId>
      <artifactId>mybatis-generator-core</artifactId>
      <version>1.3.2</version>
      <type>jar</type>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project> 

3、配置web.xml

web.xml是一个项目的核心,看看它的一些配置:

配置 ContextLoaderListener 监听器

配置Spring字符编码过滤器

配置shiro 安全过滤器

配置Spring MVC 核心控制器 DispatcherServlet

配置一些页面

spring 和 apache shiro 是由一个 ContextLoaderListener 监听器 加载的配置文件,并初始化

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <!-- Spring -->
  <!-- 配置Spring配置文件路径 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
      classpath*:applicationContext.xml
      classpath*:applicationContext-shiro.xml
    </param-value>
  </context-param>
  <!-- 配置Spring上下文监听器 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!-- Spring -->
  <!-- 配置Spring字符编码过滤器 -->
  <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>
  <!-- shiro 安全过滤器 -->
  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <async-supported>true</async-supported>
    <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>
  <!-- 配置log4j配置文件路径 -->
  <context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>classpath:log4j.properties</param-value>
  </context-param>
  <!-- 60s 检测日志配置 文件变化 -->
  <context-param>
    <param-name>log4jRefreshInterval</param-name>
    <param-value>60000</param-value>
  </context-param>
  <!-- 配置Log4j监听器 -->
  <listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
  </listener>
  <!-- Spring MVC 核心控制器 DispatcherServlet 配置 -->
  <servlet>
    <servlet-name>dispatcher</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>
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <!-- 拦截所有/rest/* 的请求,交给DispatcherServlet处理,性能最好 -->
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
  <!-- 首页 -->
  <welcome-file-list>
    <welcome-file>rest/index</welcome-file>
  </welcome-file-list>
  <!-- 错误页 -->
  <error-page>
    <error-code>404</error-code>
    <location>/rest/page/404</location>
  </error-page>
  <error-page>
    <error-code>500</error-code>
    <location>/rest/page/500</location>
  </error-page>
  <error-page>
    <exception-type>org.apache.shiro.authz.AuthorizationException</exception-type>
    <location>/rest/page/401</location>
  </error-page>
</web-app> 

4、spring配置:

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context.xsd
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx.xsd
  http://www.springframework.org/schema/jdbc
  http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
  http://www.springframework.org/schema/cache
  http://www.springframework.org/schema/cache/spring-cache.xsd
  http://www.springframework.org/schema/aop
  http://www.springframework.org/schema/aop/spring-aop.xsd
  http://www.springframework.org/schema/util
  http://www.springframework.org/schema/util/spring-util.xsd">
  <!-- 自动扫描quick4j包 ,将带有注解的类 纳入spring容器管理 -->
  <context:component-scan base-package="com.eliteams.quick4j"></context:component-scan>
  <!-- 引入配置文件 -->
  <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
      <list>
        <value>classpath*:application.properties</value>
      </list>
    </property>
  </bean>
  <!-- dataSource 配置 -->
  <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    <!-- 基本属性 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="${ds.initialSize}"/>
    <property name="minIdle" value="${ds.minIdle}"/>
    <property name="maxActive" value="${ds.maxActive}"/>
    <!-- 配置获取连接等待超时的时间 -->
    <property name="maxWait" value="${ds.maxWait}"/>
    <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
    <property name="timeBetweenEvictionRunsMillis" value="${ds.timeBetweenEvictionRunsMillis}"/>
    <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
    <property name="minEvictableIdleTimeMillis" value="${ds.minEvictableIdleTimeMillis}"/>
    <property name="validationQuery" value="SELECT 'x'"/>
    <property name="testWhileIdle" value="true"/>
    <property name="testOnBorrow" value="false"/>
    <property name="testOnReturn" value="false"/>
    <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
    <property name="poolPreparedStatements" value="false"/>
    <property name="maxPoolPreparedStatementPerConnectionSize" value="20"/>
    <!-- 配置监控统计拦截的filters -->
    <property name="filters" value="stat"/>
  </bean>
  <!-- mybatis文件配置,扫描所有mapper文件 -->
  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="dataSource"
     p:configLocation="classpath:mybatis-config.xml"
     p:mapperLocations="classpath:com/eliteams/quick4j/web/dao/*.xml"/>
  <!-- spring与mybatis整合配置,扫描所有dao -->
  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" p:basePackage="com.eliteams.quick4j.web.dao"
     p:sqlSessionFactoryBeanName="sqlSessionFactory"/>
  <!-- 对dataSource 数据源进行事务管理 -->
  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
     p:dataSource-ref="dataSource"/>
  <!-- 事务管理 通知 -->
  <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
      <!-- 对insert,update,delete 开头的方法进行事务管理,只要有异常就回滚 -->
      <tx:method name="insert*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
      <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
      <tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
      <!-- select,count开头的方法,开启只读,提高数据库访问性能 -->
      <tx:method name="select*" read-only="true"/>
      <tx:method name="count*" read-only="true"/>
      <!-- 对其他方法 使用默认的事务管理 -->
      <tx:method name="*"/>
    </tx:attributes>
  </tx:advice>
  <!-- 事务 aop 配置 -->
  <aop:config>
    <aop:pointcut id="serviceMethods" expression="execution(* com.eliteams.quick4j.web.service..*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods"/>
  </aop:config>
  <!-- 配置使Spring采用CGLIB代理 -->
  <aop:aspectj-autoproxy proxy-target-class="true"/>
  <!-- 启用对事务注解的支持 -->
  <tx:annotation-driven transaction-manager="transactionManager"/>
  <!-- Cache配置 -->
  <cache:annotation-driven cache-manager="cacheManager"/>
  <bean id="ehCacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
     p:configLocation="classpath:ehcache.xml"/>
  <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
     p:cacheManager-ref="ehCacheManagerFactory"/>
</beans> 

application.properties

##JDBC Global Setting
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/quick4j?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=admin123
##DataSource Global Setting
#配置初始化大小、最小、最大
ds.initialSize=1
ds.minIdle=1
ds.maxActive=20
#配置获取连接等待超时的时间
ds.maxWait=60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
ds.timeBetweenEvictionRunsMillis=60000
#配置一个连接在池中最小生存的时间,单位是毫秒
ds.minEvictableIdleTimeMillis=300000 

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="txswx-ehcache">
  <diskStore path="java.io.tmpdir"/>
  <!-- DefaultCache setting. -->
  <defaultCache maxEntriesLocalHeap="10000" eternal="true" timeToIdleSeconds="300" timeToLiveSeconds="600"
         overflowToDisk="true" maxEntriesLocalDisk="100000"/>
</ehcache> 

5、Apache Shiro 配置 : 要配置realms bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
  <description>apache shiro配置</description>
  <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <property name="loginUrl" value="/rest/page/login"/>
    <property name="successUrl" value="/rest/index"/>
    <property name="unauthorizedUrl" value="/rest/page/401"/>
    <property name="filterChainDefinitions">
      <value>
        <!-- 静态资源允许访问 -->
        /app/** = anon
        /assets/** = anon
        <!-- 登录页允许访问 -->
        /rest/user/login = anon
        <!-- 其他资源需要认证 -->
        /** = authc
      </value>
    </property>
  </bean>
  <!-- 缓存管理器 使用Ehcache实现 -->
  <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
  </bean>
  <!-- 会话DAO -->
  <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO"/>
  <!-- 会话管理器 -->
  <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
    <property name="sessionDAO" ref="sessionDAO"/>
  </bean>
  <!-- 安全管理器 -->
  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realms">
      <list>
        <ref bean="securityRealm"/>
      </list>
    </property>
    <!-- cacheManager,集合spring缓存工厂 -->
    <!-- <property name="cacheManager" ref="shiroEhcacheManager" /> -->
    <!-- <property name="sessionManager" ref="sessionManager" /> -->
  </bean>
  <!-- Shiro生命周期处理器 -->
  <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
</beans> 

ehcache-shiro.xml

<ehcache updateCheck="false" name="shiroCache">
  <defaultCache
      maxElementsInMemory="10000"
      eternal="false"
      timeToIdleSeconds="120"
      timeToLiveSeconds="120"
      overflowToDisk="false"
      diskPersistent="false"
      diskExpiryThreadIntervalSeconds="120"
      />
</ehcache> 

6、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>
  <properties>
    <property name="dialectClass" value="com.eliteams.quick4j.core.feature.orm.dialect.MySql5Dialect"/>
  </properties>
  <!-- 配置mybatis的缓存,延迟加载等等一系列属性 -->
  <settings>
    <!-- 全局映射器启用缓存 -->
    <setting name="cacheEnabled" value="true"/>
    <!-- 查询时,关闭关联对象即时加载以提高性能 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
    <setting name="multipleResultSetsEnabled" value="true"/>
    <!-- 允许使用列标签代替列名 -->
    <setting name="useColumnLabel" value="true"/>
    <!-- 不允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->
    <setting name="useGeneratedKeys" value="false"/>
    <!-- 给予被嵌套的resultMap以字段-属性的映射支持 FULL,PARTIAL -->
    <setting name="autoMappingBehavior" value="PARTIAL"/>
    <!-- 对于批量更新操作缓存SQL以提高性能 BATCH,SIMPLE -->
    <!-- <setting name="defaultExecutorType" value="BATCH" /> -->
    <!-- 数据库超过25000秒仍未响应则超时 -->
    <!-- <setting name="defaultStatementTimeout" value="25000" /> -->
    <!-- Allows using RowBounds on nested statements -->
    <setting name="safeRowBoundsEnabled" value="false"/>
    <!-- Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn. -->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <!-- MyBatis uses local cache to prevent circular references and speed up repeated nested queries. By default (SESSION) all queries executed during a session are cached. If localCacheScope=STATEMENT
      local session will be used just for statement execution, no data will be shared between two different calls to the same SqlSession. -->
    <setting name="localCacheScope" value="SESSION"/>
    <!-- Specifies the JDBC type for null values when no specific JDBC type was provided for the parameter. Some drivers require specifying the column JDBC type but others work with generic values
      like NULL, VARCHAR or OTHER. -->
    <setting name="jdbcTypeForNull" value="OTHER"/>
    <!-- Specifies which Object's methods trigger a lazy load -->
    <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
    <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
    <setting name="aggressiveLazyLoading" value="false"/>
  </settings>
  <typeAliases>
    <package name="com.eliteams.quick4j.web.model"/>
    <package name="com.eliteams.quick4j.web.enums"/>
  </typeAliases>
  <plugins>
    <plugin interceptor="com.eliteams.quick4j.core.feature.orm.mybatis.PaginationResultSetHandlerInterceptor"/>
    <plugin interceptor="com.eliteams.quick4j.core.feature.orm.mybatis.PaginationStatementHandlerInterceptor"/>
  </plugins>
</configuration> 

7、Spring MVC 配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    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:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
  <!-- 扫描controller(controller层注入) -->
  <context:component-scan base-package="com.eliteams.quick4j.web.controller"/>
  <!-- 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的 -->
  <!-- 指定自己定义的validator -->
  <mvc:annotation-driven validator="validator"/>
  <!-- 以下 validator ConversionService 在使用 mvc:annotation-driven 会 自动注册 -->
  <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
    <!-- 如果不加默认到 使用classpath下的 ValidationMessages.properties -->
    <property name="validationMessageSource" ref="messageSource"/>
  </bean>
  <!-- 国际化的消息资源文件(本系统中主要用于显示/错误消息定制) -->
  <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basenames">
      <list>
        <!-- 在web环境中一定要定位到classpath 否则默认到当前web应用下找 -->
        <value>classpath:messages</value>
        <value>classpath:org/hibernate/validator/ValidationMessages</value>
      </list>
    </property>
    <property name="useCodeAsDefaultMessage" value="false"/>
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="cacheSeconds" value="60"/>
  </bean>
  <mvc:interceptors>
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
  </mvc:interceptors>
  <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    <property name="defaultLocale" value="zh_CN"/>
  </bean>
  <!-- 支持返回json(避免IE在ajax请求时,返回json出现下载 ) -->
  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
      <list>
        <ref bean="mappingJacksonHttpMessageConverter"/>
      </list>
    </property>
  </bean>
  <bean id="mappingJacksonHttpMessageConverter"
     class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
    <property name="supportedMediaTypes">
      <list>
        <value>text/plain;charset=UTF-8</value>
        <value>application/json;charset=UTF-8</value>
      </list>
    </property>
  </bean>
  <!-- 支持返回json -->
  <!-- 对模型视图添加前后缀 -->
  <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
     p:prefix="/WEB-INF/views/" p:suffix=".jsp"/>
  <!-- 配置springMVC处理上传文件的信息 -->
  <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="utf-8"/>
    <property name="maxUploadSize" value="10485760000"/>
    <property name="maxInMemorySize" value="40960"/>
  </bean>
  <!-- 启用shrio授权注解拦截方式 -->
  <aop:config proxy-target-class="true"></aop:config>
  <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager"/>
  </bean>
</beans> 

messages.properties : hibernate-validator 配置文件,国际化资源文件

#user
user.username.null=用户名不能为空
user.password.null=密码不能为空
log4j.properties :
[plain] view plain copy print?在CODE上查看代码片派生到我的代码片
# DEBUG,INFO,WARN,ERROR,FATAL
LOG_LEVEL=INFO
log4j.rootLogger=${LOG_LEVEL},CONSOLE,FILE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Encoding=utf-8
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
#log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss} %C{8}@(%F:%L):%m%n
log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss} %C{1}@(%F:%L):%m%n
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.FILE.File=${catalina.base}/logs/quick4j.log
log4j.appender.FILE.Encoding=utf-8
log4j.appender.FILE.DatePattern='.'yyyy-MM-dd
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
#log4j.appender.FILE.layout=org.apache.log4j.HTMLLayout
log4j.appender.FILE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH\:mm\:ss} %C{8}@(%F\:%L)\:%m%n 

quick4j.sql

/*
SQLyog 企业版 - MySQL GUI v8.14
MySQL - 5.5.27 : Database - quick4j
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`quick4j` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `quick4j`;
/*Table structure for table `permission` */
DROP TABLE IF EXISTS `permission`;
CREATE TABLE `permission` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '权限id',
 `permission_name` varchar(32) DEFAULT NULL COMMENT '权限名',
 `permission_sign` varchar(128) DEFAULT NULL COMMENT '权限标识,程序中判断使用,如"user:create"',
 `description` varchar(256) DEFAULT NULL COMMENT '权限描述,UI界面显示使用',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='权限表';
/*Data for the table `permission` */
insert into `permission`(`id`,`permission_name`,`permission_sign`,`description`) values (1,'用户新增','user:create',NULL);
/*Table structure for table `role` */
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '角色id',
 `role_name` varchar(32) DEFAULT NULL COMMENT '角色名',
 `role_sign` varchar(128) DEFAULT NULL COMMENT '角色标识,程序中判断使用,如"admin"',
 `description` varchar(256) DEFAULT NULL COMMENT '角色描述,UI界面显示使用',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='角色表';
/*Data for the table `role` */
insert into `role`(`id`,`role_name`,`role_sign`,`description`) values (1,'admin','admin','管理员');
/*Table structure for table `role_permission` */
DROP TABLE IF EXISTS `role_permission`;
CREATE TABLE `role_permission` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '表id',
 `role_id` bigint(20) unsigned DEFAULT NULL COMMENT '角色id',
 `permission_id` bigint(20) unsigned DEFAULT NULL COMMENT '权限id',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='角色与权限关联表';
/*Data for the table `role_permission` */
insert into `role_permission`(`id`,`role_id`,`permission_id`) values (1,2,1);
/*Table structure for table `user` */
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id',
 `username` varchar(50) DEFAULT NULL COMMENT '用户名',
 `password` char(64) DEFAULT NULL COMMENT '密码',
 `state` varchar(32) DEFAULT NULL COMMENT '状态',
 `create_time` datetime DEFAULT NULL COMMENT '创建时间',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='用户表';
/*Data for the table `user` */
insert into `user`(`id`,`username`,`password`,`state`,`create_time`) values (1,'starzou','8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92',NULL,'2014-07-17 12:59:08');
/*Table structure for table `user_role` */
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '表id',
 `user_id` bigint(20) unsigned DEFAULT NULL COMMENT '用户id',
 `role_id` bigint(20) unsigned DEFAULT NULL COMMENT '角色id',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='用户与角色关联表';
/*Data for the table `user_role` */
insert into `user_role`(`id`,`user_id`,`role_id`) values (1,1,1);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 

以上所述是小编给大家介绍的基于Spring + Spring MVC + Mybatis 高性能web构建实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • AngularJS整合Springmvc、Spring、Mybatis搭建开发环境

    最近想学习AngularJS的使用,网上搜了一圈后,折腾了半天解决bug后,成功使用AngularJS整合Springmvc.Spring.Mybatis搭建了一个开发环境.(这里Spring使用的版本是4.0.6,Mybatis版本是3.2.5,AngularJS的版本是1.0.3) 第一步:创建一Maven项目,在pom.xml下添加需要的包 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="

  • SpringMVC+MyBatis声明式事务管理

    采用的基本搭建环境:SpringMVC.MyBatis.MySQL.tomcat Spring事务管理分解了传统的全局事务管理和本地事务管理的劣势,使得在任何环境中都可以使用统一的事务管理模型,你可以写一次代码,然后在不同的环境从你的代码里面配置不同的事务管理策略,Spring提供两种事务管理策略:一种是声明式事务管理策略,另一种是编程式事务管理策略,这里主要介绍声明式事务管理策略 由于采用的是SpringMVC. MyBatis,故统一采用了标注来声明Service.Controller 由于

  • SpringMVC整合mybatis实例代码

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis . 一.逆向工程生成基础信息 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis G

  • Java简单实现SpringMVC+MyBatis分页插件

    1.封装分页Page类 package com.framework.common.page.impl; import java.io.Serializable; import com.framework.common.page.IPage; /** * * * */ public abstract class BasePage implements IPage, Serializable { /** * */ private static final long serialVersionUID

  • 解决springmvc+mybatis+mysql中文乱码问题

    近日使用ajax请求springmvc后台查询mysql数据库,页面显示中文出现乱码 最初在mybatis配置如下 <select id="queryContentById" resultType = "java.lang.String" parameterType="String" > select text from News where id=#{o} </select> 其中表News的text字段为blob类型

  • MyBatis与SpringMVC相结合实现文件上传、下载功能

    环境:maven+SpringMVC + Spring + MyBatis + MySql 本文主要说明如何使用input上传文件到服务器指定目录,或保存到数据库中:如何从数据库下载文件,和显示图像文件并实现缩放. 将文件存储在数据库中,一般是存文件的byte数组,对应的数据库数据类型为blob. 首先要创建数据库,此处使用MySql数据库. 注意:文中给出的代码多为节选重要片段,并不齐全. 1. 前期准备 使用maven创建一个springMVC+spring+mybatis+mysql的项目

  • 基于Spring + Spring MVC + Mybatis 高性能web构建实例详解

    一直想写这篇文章,前段时间痴迷于JavaScript.NodeJs.AngularJS,做了大量的研究,对前后端交互有了更深层次的认识. 今天抽个时间写这篇文章,我有预感,这将是一篇很详细的文章,详细的配置,详细的注释,看起来应该很容易懂. 用最合适的技术去实现,并不断追求最佳实践.这就是架构之道. 希望这篇文章能给你们带来一些帮助,同时希望你们可以为这个项目贡献你的想法. 源码地址:https://github.com/Eliteams/quick4j 点击打开 源码地址:https://gi

  • Spring MVC自定义日期类型转换器实例详解

    Spring MVC自定义日期类型转换器实例详解 WEB层采用Spring MVC框架,将查询到的数据传递给APP端或客户端,这没啥,但是坑的是实体类中有日期类型的属性,但是你必须提前格式化好之后返回给它们.说真的,以前真没这样做过,之前都是一口气查询到数据,然后在jsp页面上格式化,最后展示给用户.但是这次不同,这次我纯属操作数据,没有页面.直接从数据库拿数据给它们返数据.它们给我传数据我持久化数据,说到这里一个小问题就默默的来了. 首先把问题还原一下吧(这是一个数据导出功能),下图中用红框圈

  • Spring mvc 分步式session的实例详解

    Spring mvc 分步式session的实例详解 Session代表服务器与浏览器的一次会话过程,它的信息是保存在服务器端的.在Servlet中,session指的是HttpSession类的对象.服务器在创建session后,会把sessionid以cookie的形式回写给客户端.只要客户端的浏览器不关,每一次访问服务器都会带上这个sessionid.这样就可以在每次请求的时候获取到session的信息. 下面以spring MVC以例来说明如果创建分步式session. 1.login

  • Spring AOP切面解决数据库读写分离实例详解

    Spring AOP切面解决数据库读写分离实例详解 为了减轻数据库的压力,一般会使用数据库主从(master/slave)的方式,但是这种方式会给应用程序带来一定的麻烦,比如说,应用程序如何做到把数据写到master库,而读取数据的时候,从slave库读取.如果应用程序判断失误,把数据写入到slave库,会给系统造成致命的打击. 解决读写分离的方案很多,常用的有SQL解析.动态设置数据源.SQL解析主要是通过分析sql语句是insert/select/update/delete中的哪一种,从而对

  • spring boot 图片上传与显示功能实例详解

    首先描述一下问题,spring boot 使用的是内嵌的tomcat, 所以不清楚文件上传到哪里去了, 而且spring boot 把静态的文件全部在启动的时候都会加载到classpath的目录下的,所以上传的文件不知相对于应用目录在哪,也不知怎么写访问路径合适,对于新手的自己真的一头雾水. 后面想起了官方的例子,没想到一开始被自己找到的官方例子,后面太依赖百度谷歌了,结果发现只有官方的例子能帮上忙,而且帮上大忙,直接上密码的代码 package hello; import static org

  • spring对JDBC和orm的支持实例详解

    简介 Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术,如JDBC,Hibernate或者JDO等.它不仅可以让你方便地在这些持久化技术间切换, 而且让你在编码的时候不用考虑处理各种技术中特定的异常. 一致的异常层次 Spring提供了一种方便的方法,把特定于某种技术的异常,如SQLException, 转化为自己的异常,这种异常属于以 DataAccessException 为根的异常层次.这些异常封装了原始异常对象,这样就不会有丢失任何错误信息的

  • Spring 整合 Hibernate 时启用二级缓存实例详解

    Spring 整合 Hibernate 时启用二级缓存实例详解 写在前面: 1. 本例使用 Hibernate3 + Spring3: 2. 本例的查询使用了 HibernateTemplate: 1. 导入 ehcache-x.x.x.jar 包: 2. 在 applicationContext.xml 文件中找到 sessionFactory 相应的配置信息并在设置 hibernateProperties 中添加如下代码: <!-- 配置使用查询缓存 --> <prop key=&q

  • 基于asp.net MVC 应用程序的生命周期(详解)

    首先我们知道http是一种无状态的请求,他的生命周期就是从客户端浏览器发出请求开始,到得到响应结束.那么MVC应用程序从发出请求到获得响应,都做了些什么呢? 本文我们会详细讨论MVC应用程序一个请求的生命周期,从一个控件到另一个控件是怎样被处理的.我们还会详细介绍一下整个请求的生命周期中,用到的相关组件.因为在平常的开发过程中,我们可能知道怎样去使用MVC框架来处理相关的请求,大部分的时候我们只是在controller和action方法之间做相关的处理,对于真正内在的运行机制可能不是很了解.其实

  • Spring boot进行参数校验的方法实例详解

    Spring boot开发web项目有时候我们需要对controller层传过来的参数进行一些基本的校验,比如非空.整数值的范围.字符串的长度.日期.邮箱等等.Spring支持JSR-303 Bean Validation API,可以方便的进行校验. 使用注解进行校验 先定义一个form的封装对象 class RequestForm { @Size(min = 1, max = 5) private String name; public String getName() { return n

  • Spring Boot的listener(监听器)简单使用实例详解

    监听器(Listener)的注册方法和 Servlet 一样,有两种方式:代码注册或者注解注册 1.代码注册方式 通过代码方式注入过滤器 @Bean public ServletListenerRegistrationBean servletListenerRegistrationBean(){ ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean

随机推荐