Spring+SpringMVC+Mybatis+velocity 搭建

一、前言

花了两三天的不断尝试,终于搭建通了Spring+SpringMVC+Mybatis框架,本文是用来对整个学习过程做一个回顾,当然存在着不少问题有待改进,例如配置文件的具体联系等。 欢迎指正。
文中用到的开发工具列举如下:
JDK 1.7.0_79
Intellij IDEA Ultimate 15
Mysql 5.1.29
Maven 3

二、项目结构

这里写图片描述

  1. 首先创建一个maven项目,然后配置pom.xml,添加框架依赖。
    其中,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.demo</groupId>
  <artifactId>demo</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>

  <name>${project.artifactId}</name>

  <properties>
    <jdk.version>1.7</jdk.version>
    <spring.version>4.0.8.RELEASE</spring.version>
    <mybatis.version>3.2.8</mybatis.version>
    <mybatis.spring.version>1.2.2</mybatis.spring.version>
    <mysql.driver.version>5.1.29</mysql.driver.version>
    <jackson.version>2.5.4</jackson.version>
    <!-- jdbc driver setting -->
  </properties>

  <dependencies>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <!-- Spring framework -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
      <!-- replace with jcl-over-slf4j -->
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</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-jdbc</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-aop</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- mybatis -->
    <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>

    <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.2</version>
    </dependency>

    <!-- jdbc driver -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.driver.version}</version>
      <scope>runtime</scope>
    </dependency>

    <!-- velocity -->
    <dependency>
      <groupId>org.apache.velocity</groupId>
      <artifactId>velocity</artifactId>
      <version>1.7</version>
    </dependency>

    <dependency>
      <groupId>org.apache.velocity</groupId>
      <artifactId>velocity-tools</artifactId>
      <version>2.0</version>
    </dependency>

    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.15</version>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.6</version>
    </dependency>

  </dependencies>

  <build>
    <finalName>demo</finalName>
    <plugins>
      <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.2</version>
        <configuration>
          <overwrite>true</overwrite>
          <verbose>true</verbose>
        </configuration>

      </plugin>

      <!--Maven编译插件 配置-->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>${jdk.version}</source>
          <target>${jdk.version}</target>
          <compilerArguments>
            <extdirs>src\main\webapp\WEB-INF\lib</extdirs>
          </compilerArguments>
          <showWarnings>true</showWarnings>
        </configuration>
      </plugin>

    </plugins>
  </build>

</project>
  1. 配置web.xml
    web.xml是一个项目的核心,主要作用是配置DispatcherServlet。
    最后,web.xml的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- Spring MVC配置 -->
    <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/spring-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

    <!-- 配置spring -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:spring/applicationContext.xml</param-value>
    </context-param>
    <!-- 配置Spring上下文监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 获取request对象 getSession()-->
    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>

    <!-- 配置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>

    <!-- 载入Log4j配置文件位置 -->
    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>classpath:config/log4j.properties</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>
</web-app>
  1. spring配置:
    applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="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/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">


    <!-- 引入jdbc配置文件 -->
    <context:property-placeholder location="classpath:config/jdbc.properties" />

    <!-- c3p0连接池配置 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- 用户名-->
        <property name="user" value="${jdbc.username}"/>
        <!-- 用户密码-->
        <property name="password" value="${jdbc.password}"/>
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <!--连接池中保留的最大连接数。默认值: 15 -->
        <property name="maxPoolSize" value="20"/>
        <!-- 连接池中保留的最小连接数,默认为:3-->
        <property name="minPoolSize" value="2"/>
        <!-- 初始化连接池中的连接数,取值应在minPoolSize与maxPoolSize之间,默认为3-->
        <property name="initialPoolSize" value="2"/>
        <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。默认值: 0 -->
        <property name="maxIdleTime" value="60" />
        <!-- 当连接池连接耗尽时,客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒。默认: 0 -->
        <property name="checkoutTimeout" value="3000"/>
        <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。默认值: 3 -->
        <property name="acquireIncrement" value="2"/>
        <!--定义在从数据库获取新连接失败后重复尝试的次数。默认值: 30 ;小于等于0表示无限次-->
        <property name="acquireRetryAttempts" value="0"/>
        <!--重新尝试的时间间隔,默认为:1000毫秒-->
        <property name="acquireRetryDelay" value="1000" />
        <!--关闭连接时,是否提交未提交的事务,默认为false,即关闭连接,回滚未提交的事务 -->
        <property name="autoCommitOnClose" value="false"/>
        <!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试使用。默认值: null -->
        <property name="automaticTestTable" value="Test"/>
        <!--如果为false,则获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常,但是数据源仍有效保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭。默认: false-->
        <property name="breakAfterAcquireFailure" value="false" />
        <!--每60秒检查所有连接池中的空闲连接。默认值: 0,不检查 -->
        <property name="idleConnectionTestPeriod" value="60" />
        <!--c3p0全局的PreparedStatements缓存的大小。如果maxStatements与maxStatementsPerConnection均为0,则缓存不生效,只要有一个不为0,则语句的缓存就能生效。如果默认值: 0-->
        <property name="maxStatements" value="100" />
        <!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。默认值: 0 -->
        <property name="maxStatementsPerConnection" value="0" />
    </bean>

    <!-- 创建SqlSessionFactory,同时指定数据源 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 实体类包 -->
        <property name="typeAliasesPackage" value="com.demo"/>
        <!-- 配置sql映射文件所在位置  注意:默认与mapper类位置相同   -->
        <property name="mapperLocations" value="classpath*:mappings/**/*.xml" />
        <property name="configLocation" value="classpath:spring/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.demo"/>
        <property name="annotationClass" value="com.demo.global.persistence.annotation.MyBatisDao"/>
    </bean>

    <!-- 配置事务管理器,使用tx标签配置的拦截器声明式事务  -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 配置事务的传播特性  -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--
                REQUIRED:如果存在一个事务,则支持当前事务;如果没有事务,则开启一个新事务。
                NESTED:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则开启一个新事务。
            -->
            <tx:method name="find*" read-only="true" propagation="SUPPORTS" />
            <tx:method name="get*" read-only="true" propagation="SUPPORTS" />
            <tx:method name="query*" read-only="true" propagation="SUPPORTS" />
            <tx:method name="pageQuery*" read-only="true" propagation="SUPPORTS" />
            <tx:method name="*"  read-only="false" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

    <!-- 配置事务的切入点  -->
    <aop:config proxy-target-class="true">
        <aop:advisor pointcut="execution(* com.demo.module..*.service..*.*(..))" advice-ref="txAdvice" />
    </aop:config>

    <!-- 定义扫描根路径为com.demo,不使用默认的扫描方式 -->
    <context:component-scan base-package="com.demo" use-default-filters="false">
        <!-- 扫描符合@Service @Repository的类 -->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Component" />
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
</beans>

jdbc.properties:

jdbc.type=mysql
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/helpu?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456

jdbc.pool.init=1
jdbc.pool.minIdle=3
jdbc.pool.maxActive=20

jdbc.testSql=SELECT 'x' FROM DUAL
  1. 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"/><!-- NUll -->

    </settings>

</configuration>
  1. 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.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">

    <!-- 启用spring 注解,如果PersistenceAnnotationBeanPostProcessor和equiredAnnotationBeanPostProcessor不使用,可以不需要 -->
    <context:annotation-config />
    <!-- 注解扫描的包 -->
    <context:component-scan base-package="com.demo.module" >
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
    </context:component-scan>

    <!-- 启用spring mvc注解,会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter和下面重复所以去掉  -->
    <mvc:annotation-driven />

    <!-- Velocity版本 -->
    <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="configLocation"><value>classpath:config/velocity.properties</value></property>
        <property name="resourceLoaderPath" value="/pages/" /><!-- 模板存放的路径 -->
        <property name="velocityProperties">
            <props>
                <prop key="input.encoding">UTF-8</prop>
                <prop key="output.encoding">UTF-8</prop>
            </props>
        </property>
    </bean>
    <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
        <property name="cache" value="true" /><!-- 缓存设置 -->
        <property name="prefix" value="/" /><!-- 视图文件的前缀,即存放的路径 -->
        <property name="suffix" value=".html" /><!-- 视图文件的后缀名 -->
        <property name="contentType" value="text/html;charset=utf-8" />
        <property name="layoutUrl" value="velocity/layout-blank.vm" /><!--指定layout文件-->
        <property name="requestContextAttribute" value="ac" /><!--request属性引用名称-->
        <property name="order" value="1" /><!-- 多ViewResovler配置 -->
        <property name="numberToolAttribute" value="numbertool" /><!--数字函数名称-->
        <property name="dateToolAttribute" value="datetool" /><!--日期函数名称-->
        <property name="toolboxConfigLocation" value="/WEB-INF/classes/config/velocity-tools.xml" /><!--toolbox配置文件路径-->
    </bean>
</beans>
  1. log4j.properties
#将ibatis log4j运行级别调到DEBUG可以在控制台打印出运行的sql语句
log4j.rootLogger=INFO,CONSOLE,FILE

log4j.logger.org.springframework=ERROR  
log4j.logger.org.apache.struts2=ERROR  
log4j.logger.com.opensymphony.xwork2=ERROR  
log4j.logger.org.hibernate=ERROR
log4j.logger.net.sf.json=ERROR
#log4j.logger.com.golden.global.exception=ERROR,P

### 把日志信息输出到控制台 ###
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 
log4j.appender.CONSOLE.Target=System.out 
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 
log4j.appender.CONSOLE.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} %p %X{userid} %X{ip} %m %c{1}.%M%n

### 把日志信息输出到文件:jbit.log ###
log4j.appender.FILE=org.apache.log4j.FileAppender 
log4j.appender.FILE.File=/Users/test/Documents/Data/log/demo.log
log4j.appender.FILE.Append=false 
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout 
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 

### 调至debug ###
#log4j.logger.com.ibatis=DEBUG
#log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
#log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
#log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
#log4j.logger.java.sql.Statement=DEBUG
#log4j.logger.java.sql.PreparedStatement=DEBUG

#log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender 
#log4j.appender.MAIL.Threshold=FATAL 
#log4j.appender.MAIL.BufferSize=10 
#log4j.appender.MAIL.From=gep@golden-soft.com
#log4j.appender.MAIL.SMTPHost=www.golden-soft.com
#log4j.appender.MAIL.Subject=Log4J Message 
#log4j.appender.MAIL.To=gep@golden-soft.com
#log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout 
#log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 


#log4j.appender.DATABASE=com.golden.global.common.log.GoldenJDBCAppender
#log4j.appender.DATABASE.URL=jdbc:oracle:thin:@192.168.2.13:1521:orcl
#log4j.appender.DATABASE.driver=oracle.jdbc.driver.OracleDriver
#log4j.appender.DATABASE.user=bdp 
#log4j.appender.DATABASE.password=bdp 
#log4j.appender.DATABASE.sql=INSERT INTO SYSTEM_LOG(log_id,member_code,log_date,operator_code,log_location,log_message,log_ip,log_hostname,log_servername,log_level) VALUES (system_log_seq.nextval,'%X{membercode}',SYSDATE,'%X{userid}','%C{1}.%M%n','%m','%X{ip}','%X{hostname}','%X{servername}','%p') 
#log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout 
#log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 
  1. velocity配置文件
    velocity.properties
userdirective=com.demo.global.velocity.BlockDirective,com.demo.global.velocity.OverrideDirective,com.demo.global.velocity.ExtendsDirective
file.resource.loader.cache = true
velocimacro.permissions.allow.inline=true

velocity-tools.xml

<?xml version="1.0" encoding="UTF-8"?>
<toolbox>
    <tool>
        <key>stringtools</key>
        <class>com.demo.global.velocity.tools.StringTools</class>
    </tool>
</toolbox>

大功告成,妈妈再也不用担心我在搭建框架上受阻了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值