◎筱米加步枪◎.Blog

Happy coding

Velocity基础笔记

今天初步学了一下Velocity,顺手写了一些简单例子,主要是测试VTL(Velocity描述语言)的语法.

先来看看如何使用Velocity的:

//需要依赖的包:common.collections.jar,common-lang.jar
public class VeloccityTest {
	
	public static void main(String[] args) {
		//创建引擎
		VelocityEngine velocityEngine = new VelocityEngine();
		
		//设定输入输出编码可支持中文
		Properties prop = new Properties();
		prop.setProperty(Velocity.ENCODING_DEFAULT, "utf-8"); 
		prop.setProperty(Velocity.INPUT_ENCODING, "utf-8"); 
		prop.setProperty(Velocity.OUTPUT_ENCODING, "utf-8"); 
		
		//可以根据属性对象或者属性文件进行定义,原理是一样的.
		velocityEngine.init(prop);
		
		//取得VTL定义的文件获取模板对象
		Template template = velocityEngine.getTemplate("/src/template.vm");
		
		//新创一个Velocity上下文
		VelocityContext velocityContext = new VelocityContext();
		
		//放入VTL中定义的变量值
		velocityContext.put("name", "ChenST");
		velocityContext.put("address", "淘宝商城");
		
		List<String> products = new ArrayList<String>();
		products.add("百事可乐");
		products.add("可口可乐");
		//可放入一个ArrayList集合代表数组
		velocityContext.put("products", products);
		
		Map<String, String> map = new HashMap<String, String>();
		map.put("key", "mapValue");
		//可放入一个Map结构的对象
		velocityContext.put("map", map);
		
		People people = new People();
		people.setName("张三");
		//可放入一个自定义对象
		velocityContext.put("people", people);
		
		StringWriter stringWriter = new StringWriter();
		//根据模板定义的内容进行合并,并将结果输出给流对象
		template.merge(velocityContext, stringWriter);
		
		System.out.println(stringWriter.toString());
	}
}

接下来再来看看具体的VTL是如何定义和描述的,(习惯将一些学习过程写在代码中...)

#####这个是注释#####

#####parse脚本元素包含另一个VTL的本地文件######

测试解析:#parse("/src/other.vm")

#####include包含另外一个文件,只是文本包含,不进行解析######
测试文本包含:#include("/src/other.vm");

#####set脚本元素定义变量#####
#set($defaultDept = "技术部")

#####引用变量值,可以是VTL中指定的,也可以是Java程序中注入上下文的值#####
#####可以$name也可以${name},后者比较规范#####

测试获取变量值:你好, $name,欢迎来到 $address,默认部门:$defaultDept

#####判定元素if-else-end#####
#set($i = 1)
#set($j = 2)
#if( $i == $j)
测试判定元素:i值和j值相等
#else
测试判定元素:i值和j值不相等
#end

#####VTL变量的算数运算######
#set($plus = ${i}+${j})
#set($minus = ${i}-${j})
#set($multi = ${i}*${j})
#set($divis = ${i}/${j})
测试运算:
加法运算:结果:${plus}
减法运算:结果:${minus}
乘法运算:结果:${multi}
除法运算:结果:${divis}

#####foreach-end脚本元素用于循环操作,products是一个ArrayList#####
#####velocityCount变量的名字是Velocity默认的名字,可以通过修改velocity.properties文件来改变它###
#####directive.foreach.counter.name = velocityCount #####
#####directive.foreach.counter.initial.value = 1 #####

测试循环元素:
#foreach($product in $products)
第$velocityCount条记录 - ${product}
#end

#####使用.有两种含义,一种可以是HashMap,HashTable这种结构,另外一种可以是对象的属性值或者方法#####
测试Map的值:${map.key}
测试对象的值:${people.name}
测试对象方法:${people.call()}

#####macro元素标签可用于定义一个可重用的模板,如reTemp为模块名,可跟任意个参数#####
#macro(reTemp $parm1 $parm2)
测试定义可重用模板,参数:${parm1},${parm2}
#end
#####使用定义的可重用的模块#####
#reTemp(${i} ${j})

#####可以使用中括号操作符表示一个范围,默认增量为1#####
测试范围元素:
#foreach ( $foo in [3..1])
$foo
#end

#####$test和$!的区别:前者找不到时原串输出,后缀如果找不到输出空串#####
找不到test变量值输出:$test
找不到test变量值输出:$!test

另外一个被引用的文件

测试引用其他文件:你好, $name,欢迎来到 $address

感觉Velocity还是挺好的..可以自己一定一些模板,比如java代码,XML代码之类的都可以.可以自己试着做一些小工具,生成自己开发模式的一些代码.还可以结合Eclipse写一些小插件之类的。

 

Ant文件间脚本的调用

每个项目都有一个ant打包部署脚本,一个一个ant文件执行麻烦,需要有一个ant脚本统一调到这些ant文件,把这些ant文件给串起来.

贴个Ant文件间的调用脚本:(部分Ant脚本省略..有代表性的贴出些..)

svn.java.dir=.
svn.eframe.dir=${svn.java.dir}/EFrame
svn.workflow.dir=${svn.java.dir}/workflow
### jar dir ###
eframework.dir = ${svn.eframe.dir}/eframework
casclient.dir=${svn.eframe.dir}/casclient
### war dir  ###
CAS.dir = ${svn.eframe.dir}/CAS
e_workflowService.dir = ${svn.workflow.dir}/e_workflowService
<project basedir="." default="packageAll" name="allJar">
	<property environment="env" />
	<property file="build-all.properties" />
	
	<!-- 重建目录 -->
	<target name="rebuild">
		<delete dir="${basedir}/dist/lib" />
		<delete dir="${basedir}/dist/deploy"/>
		<mkdir dir="${basedir}/dist/lib"/>
		<mkdir dir="${basedir}/dist/deploy"/>
	</target>
	
	<!-- 调用其他项目的ant脚本(打jar包)-->
	<target name="packageJar" depends="rebuild">
		<ant antfile="build.xml" dir="${eframework.dir}"/>
		<ant antfile="build.xml" dir="${casclient.dir}"/>
	</target>
	
	<!-- 调用其他项目的ant脚本(打war包)-->
	<target name="packageWar" depends="packageJar">
		<ant antfile="build.xml" dir="${CAS.dir}"/>
		<ant antfile="build.xml" dir="${e_workflowService.dir}"/>
	</target>
	
	<target name="packageAll" depends="packageWar"/>
</project>

完毕..

使用Ant生成JBoss上部署项目的脚本

用Ant脚本打包部署项目,生成Jboss上部署后的文件信息.(跟MyEclipse部署到Jboss的效果一样)

搞了一天多..Ant不是很熟..贴个备忘下..

svn.lib.path=../../lib
svn.dist.path=../../dist
svn.target.lib=${svn.dist.path}/lib
svn.target.deploy=${svn.dist.path}/deploy
target.war.file=${svn.target.deploy}/EFrameWeb.war
busi.jars=e_workflowclient.jar,jbpmengineclient.jar
<project basedir="." default="deploy" name="EFrameWeb">
	<property environment="env" />
	<!-- 引用属性文件的属性定义 -->
	<property file="build.properties" />

	<property name="debuglevel" value="source,lines,vars" />
	<property name="target" value="1.6" />
	<property name="source" value="1.6" />
	<!-- 定义WebRoot路径 -->
	<property name="WebRoot.dir" value="${basedir}/WebRoot"/>
	<!-- 定义编译路径 -->
	<property name="compile.dir" value="${WebRoot.dir}/WEB-INF/classes"/>
	<!-- 定义源代码路径 -->
	<property name="src.dir" value="${basedir}/src"/>
	<!-- 定义项目所用到的其他包 -->
	<property name="lib.dir" value="${WebRoot.dir}/WEB-INF/lib"/>
	
	<!-- 定义生成的war包的classes路径 -->
	<property name="target.war.file.classes" value="${target.war.file}/WEB-INF/classes"/>
	<!-- 定义生成的war包的lib路径-->
	<property name="target.war.file.lib" value="${target.war.file}/WEB-INF/lib"/>
	
	
	<path id="appAPI.classpath">
		<!-- 包含项目中涉及到的业务包和工具包 -->
		<fileset dir="${svn.target.lib}">
			<include name="**/*.jar"/>
		</fileset>
		
		<!-- 包含项目中涉及到第三方开源包 -->
		<fileset dir="${svn.lib.path}">
			<include name="**/*.jar" />
		</fileset>
		
		<!-- 包含存在项目自身lib目录下的包 -->
		<fileset dir="${lib.dir}">
			<include name="**/*.jar" />
		</fileset>
	</path>
	<target name="clean">
		<delete dir="${compile.dir}" />
		<delete dir="${target.war.file}/" />
	</target>
	<target name="init" depends="clean">
		<mkdir dir="${target.war.file}" /> 
		<mkdir dir="${compile.dir}" />
		
		<!-- 属性信息 -->
		<echo message="${ant.project.name}: ${ant.file}" />
		
		<!-- 编译程序 -->
		<javac debug="true" 
			   includeantruntime="false" 
			   debuglevel="${debuglevel}" 
			   encoding="GBK" 
			   destdir="${compile.dir}" 
			   source="${source}" 
			   target="${target}">
			<src path="${src.dir}" />
			<classpath refid="appAPI.classpath" />
		</javac>
		
		<!-- 拷贝WebRoot下的东西 -->
		<copy includeemptydirs="false" todir="${target.war.file}">
			<fileset dir="${WebRoot.dir}">
				<exclude name="**/.svn" />
				<exclude name="**/*.launch" />
			</fileset>

		</copy>
		
		<!-- 拷贝项目classses非编译文件 -->
		<copy includeemptydirs="false" todir="${target.war.file.classes}">
			<fileset dir="${src.dir}">
				<exclude name="**/*.launch" />
				<exclude name="**/*.java" />
				<exclude name="**/.svn" />
			</fileset>
		</copy>

		<!-- 拷贝项目所依赖的业务包 -->
		<copy includeemptydirs="false" todir="${target.war.file.lib}">
			<fileset dir="${svn.target.lib}" includes="${busi.jars}"/>
		</copy>
	</target>

	<target name="deploy" depends="init"></target>
</project>

 

使用Ant编译出现“找不到符号”错误原因与解决方法

这两天做写Ant脚本打包和部署项目.期间遇到一个问题,花了两三个小时解决.真郁闷..笔记下下.
问题描述如下:
使用Ant脚本编译打包程序时出错,出错信息:“找不到符号”,检查编译程序出来的代码无误,也确保需要的jar包已经引入。
后来偶然发现目录中存在一个早期版本打成的一个同名的jar包.而我写的ant脚本加载器又是优先加载旧版本的jar包.因此识别到的类没有新项目中所用的方法.自然就报"找不到符号"的错误了.
解决方法:
1.最根本的办法:就是去除旧版本的包,然后重新编译即可.
2.不除去旧版本包,可以优先加载新版本的jar程序.

ORA-01034 ORACLE not available ORA-27101 Shared memory realm does not exist错误解决方案.

解决好创建实例问题之后,使用PL/SQL连数据库报如下错误:

ORA-27101 Shared memory realm does not exist
ORA-01034 ORACLE not available 

谷歌了很久很久,才找到解决方案,网上大多数方案都不行.很佩服这个牛人.

偶不是Oracle专家,不说原因了..直接说明怎么解决问题的吧.

1.打开命令窗口输入:lsnrctl start

2.出现监听程序启动成功之后,继续输入: sqlplus '/as sysdba'

3.连接成功后输入startup

4.出现成功信息后再使用PL/SQL登录,发现登录成功.

贴个截图:

Oracle服务误删除的解决办法(360搞的)

之前有一次遇到这个问题,ORACLE.exe莫名奇妙的被360给删除了,上次选择了还原系统来解决,这次不知何时又被删除了.害我搞了一个晚上

无奈之下只好百度谷歌到处搜索.搜索到如下命令可建Oracle实例.(可弄成一个bat文件)

oradim -NEW -SID orcl -STARTMODE manual -PFILE F:\oracle\product\10.2.0\admin\ORCL\pfile\initorcl.ora"  
oradim -STARTUP -SID ORCL -STARTTYPE inst

其中红色部分为自己的Oracle实例.

顺便贴个删除Oracle实例的命令:

oradim -DELETE -SID orcl

完成之后重启便可.

若登录数据库时出现如下错误 :

ora-01034:oracle not available

ora-27101:shared mermory realm does not exist

请看文章:http://cst.is-programmer.com/posts/23753

EhCache基础知识学习笔记

项目需要,稍微过了一下有关EhCache缓存框架的知识.

简单介绍下EhCache:EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点.

一些不太经常变化的数据可以放入缓存,需要时候直接从缓存获取,可以提供系统的性能.

具体来看一下ehcache的知识吧.

ehcache需要一个xml配置文件:

内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<!-- 缓存数据文件创建的地方,java.io.tmpdir是默认的临时文件路径 -->
<diskStore path="java.io.tmpdir"/>

	    <!-- Sets the path to the directory where cache .data files are created. 
	    	  设置为缓存的地方。数据文件创建的目录的路径

	         If the path is a Java System Property it is replaced by 
	         its value in the running VM.
	                        如果路径是Java系统属性中被替换其值在运行虚拟机。
	         
	         
	         The following properties are translated:下列属性换算
	         user.home - User's home directory           用户的主目录
	         user.dir - User's current working directory 用户的当前工作目录
	         java.io.tmpdir - Default temp file path     默认临时文件路径
	    <diskStore path="java.io.tmpdir"/> -->
	    
	    <!--Default Cache configuration. These will applied to caches programmatically created through
	        the CacheManager.
		默认的缓存配置。这将适用于通过编程方式创建缓存在CacheManager。
	
	        The following attributes are required: 下面的属性是必需的
	
	        maxElementsInMemory            - Sets the maximum number of objects that will be created in memory 
                                                 设置对象的最大数量,将在内存中创建
	        eternal                        - Sets whether elements are eternal. If eternal,  timeouts are ignored and the
	                                         element is never expired. 
	                                         设置元素是否是永恒的。如果永恒的,超时被忽略,并且元素是永远不会过期(缓存是否永远不销毁)
	        overflowToDisk                 - Sets whether elements can overflow to disk when the in-memory cache
	                                         has reached the maxInMemory limit.
	                                         设置当缓存中的数据达到最大值时,是否把缓存数据写入磁盘
	
	        The following attributes are optional: 以下属性是可选的
	        timeToIdleSeconds              - Sets the time to idle for an element before it expires.
	                                         i.e. The maximum amount of time between accesses before an element expires
	                                         Is only used if the element is not eternal.
	                                         Optional attribute. A value of 0 means that an Element can idle for infinity.
	                                         The default value is 0.
	                                         设置 当缓存闲置指定时间,当闲置时间到达指定时间时,缓存则自动销毁,可选的属性。
                                                 0值表示一个元素可以闲置无穷。默认值是0
	                                         
	        timeToLiveSeconds              - Sets the time to live for an element before it expires.
	                                         i.e. The maximum time between creation time and when an element expires.
	                                         Is only used if the element is not eternal.
	                                         Optional attribute. A value of 0 means that and Element can live for infinity.
	                                         The default value is 0.
                                                 设置当缓存创建之后到达的指定时间,当缓存生存超过指定的时间,缓存则自动销毁
                                                 可选的属性。0值表示和元素可以活无限。默认值是0
	        diskPersistent                 - Whether the disk store persists between restarts of the Virtual Machine.
	                                         The default value is false.
                                                 无论是磁盘存储之间仍然存在的虚拟机重新启动。默认值是false
	        diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value
	                                         is 120 seconds.
                                                 磁盘之间的到期线程运行的秒数。默认值是120秒
	        -->
	        
    <defaultCache
        maxElementsInMemory="100000"
        eternal="false"
        overflowToDisk="true"
        timeToIdleSeconds="60" 
        timeToLiveSeconds="120"
        />

	<cache name="systemConfigCache"
       maxElementsInMemory="100000"
       eternal="false"
       overflowToDisk="true">
    </cache>

</ehcache>

以上的一些翻译是结合google翻译和一些自己的理解.ehcache涉及的配置元素和属性说明都在上头了.

以下是Java代码部分,描述了一些关于Ehcache的简单使用和一些API,具体其他的API就参考具体文档咯..

//必须导入commons-logging.jar
public class EhCache {
	
	//默认缓存配置路径
	public static String DEFAULT_CACHE_CONFIG_PATH = "conf/ehcache.xml";
	
	public static void main(String[] args) {
		//使用指定的配置文件路径创建缓存管理器
		CacheManager cacheManager = new CacheManager(DEFAULT_CACHE_CONFIG_PATH);
		//获取配置的缓存Cache名字
		String [] cacheNames = cacheManager.getCacheNames();
		
		//会在当前classpath中去寻找ehcache.xml配置文件
		CacheManager cacheManager1 = new CacheManager(); 
		//或者 CacheManager.getInstance(); 
		//或者CacheManager.create();

		//由缓存管理器中获得缓存,可以是配置在文件中的缓存也可以是代码中new出来的.
		Cache cache = cacheManager.getCache("systemConfigCache");
		
		//数据放入缓存
		cache.put(new Element("key", "value"));

		//更新缓存数据
		cache.put(new Element("key","value2"));
		
		//获取缓存的值(序列画值)
		Element element = cache.get("key");
		Serializable value = element.getValue();
		
		//获取缓存的值(对象值)
		Object object = element.getObjectValue();
		
		//移除缓存数据
		cache.remove("key");

		//取得缓存中的属性maxElementsInMemory,其他的值类似
		int maxelementsInMemory = cache.getMaxElementsInMemory();
		
		String name = "codeCreateCache";  //缓存名字
		int maxElementsInMemory = 1000;   //缓存可以存储的总记录量
		boolean overflowToDisk = false;   //当缓存中的数据达到最大值时,是否把缓存数据写入磁盘
		boolean eternal = true;           //缓存是否永远不销毁
		long timeToLiveSeconds = 60;      //当缓存闲置指定时间,则自动销毁
		long timeToIdleSeconds = 120;     //当缓存创建之后到达时间自动销毁
		
		//代码中创建缓存
		Cache cache2 = new Cache(name, maxElementsInMemory, overflowToDisk, eternal, timeToLiveSeconds,
				timeToIdleSeconds);
		
		//添加缓存
		cacheManager.addCache(cache2);
		
		//移除缓存
		cacheManager.removeCache("systemConfigCache");
		
		//卸载缓存管理器
		cacheManager.shutdown();
	}
}

使用起来还是挺方便的,如果有其他需要也可以基于上面封装满足自己的缓存框架.

CAS单点登录用户名中文乱码问题解决方案

做项目使用CAS做单点登录时发现用户名输入中文名,后台日志打出居然是个乱码,自然就匹配不到数据库中的数据了..Google了一下,在CAS项目的web.xml写一个编码过滤器,可以使用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>gb2312</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>

注意:以上过滤器应配置在所有过滤器之前.

再测试,中文用户名测试通过.