posts - 110, comments - 101, trackbacks - 0, articles - 7
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

  .表示当前目录 比如cd .或者 cd ./  当前目录
  .. 代表上级目录
  ~ 代表用户的home目录
  / 代表系统根目录
  pwd 命令用于显示当前目录的绝对路径
 
  命令1
  find . -name mysql_version.h -exec grep -i 'mysql_server_version' {} \;
  解析: 找到mysql_version.h文件 并查看mysql_server_version
  . 当前目录
  -name: 后面跟上 要找的文件名
  -exec: find命令对匹配的文件执行该参数所给出的shell命令 相应命令的形式为'command' { } /;,注意{ }和/;之间的空格。
  即可以在-exec 后面 跟上 shell命令 但是要以 { } /;结束 一个都不能少
  grep 查询文件中的内容
  -i 是不区分大小写
 
   find -name mysql_version.h |xargs cat -n | grep -i mysql_server_version
   其中的 -exexc也可以用 |xargs 代替
 
  命令2
  find . -name mysql_version.h -exec cat {} \;
  cat: 一行一行的读出文件内容
 
  命令3 
  find . -name mysql_version.h -exec cat -n {} \;
  cat命令参数
  -n 显示行号
 
  命令4
  find / -type f -size 0 -exec ls -l {} \;
  cat > fileName 创建文件,不能这样编辑已有的文件
  cat file1 file2 > file3 把几个文件合并到一个文件
 

  命令5
   who  查看当前在线的用户
  
  命令6
  cut –d’:’ -f 1    cut命令可以从一个文本文件或者文本流中提取文本列,具体的说就是在文件中负责剪切数据用的。cut是以每一行为一个处理对象的,这种机制和sed是一样的 
 cut -d'分隔字元' -f fields
 -d ∶后面接分隔字符。与 -f 一起使用; 如 -d : 表示用冒号分隔
    -f ∶依据 -d 的分隔字符将一段讯息分割成为数段,用 -f 取出第几段的意思;
 
  命令7
  \w 匹配文字和数字字符 也就是[A-Za-z0-9]
  x\{m,\}  重复字符x ,至少m次 如'a\{5,\}' 匹配至少有5个a的行
  '\w\{4,\}'
 
  命令7
  cut -d: -f 1,3 /etc/passwd |grep '[0-9]\{3,\}' | wc -l
  -f 1,3 /etc/passwd 即是选择passwd文件中的以冒号分隔的第一列和第三列,grep ‘[0-9]\{3,\}’即是使用grep匹配包含大于99的数据项
 
  命令8
  wc -l 统计行数
 
  命令9
  mv 和rename 重命名,区别mv 只对单个文件命名,rename 还可以批量命名
 
  linux 下执行amoeba.sh文件  报错
  -bash: amoeba.sh: command not found
  解决方法: 在执行文件前面加上. ;
  . amoeba.sh .后面要有要空格
 
  命令10
  删除目录以文件
  rm -rf dal-server/
  -r 就是向下递归 一并删除
  -f 就是直接强行删除 不作任何提示
 
  命令11
  查看linux是x86还是x64
  getconf LONG_BIT 这里的LONG_BIT需要大写
  ifconfig 系统信息
 
  命令12
  安装jdk
  下载jdk-6u30-linux-x64.bin 文件
   进入安装目录
   1 先执行 export _POSIX2_VERSION=199209
   2 然后可以安装jdk了
   命令很简单 就是 ./jdk-6u30-linux-x64.bin 之前没有空格 如果/后面有了空格 会出错
   设置 环境 变量
   进入etc目录下找到 profile 打开并编辑
   在最后  加上
   export JAVA_HOME=/usr/tmp/jdk1.6.0_30
   export PATH=$JAVA_HOME/bin:$PATH
   export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
  
   然后退出终端  重新登录 就可以了
   java -version 可以发现环境变量配置成功了
  
  命令13
  使用脚本 执行java工程
    export CLASSPATH=.
 for jarlib in `ls /usr/tmp/hello_yun/dal-server/lib/*.jar`
 do
   CLASSPATH=$CLASSPATH:$jarlib
 done
 export CLASSPATH=$CLASSPATH
 echo current  classpath $CLASSPATH
    这样就把classpath 都加进来了 
DEFAULT_OPTS="-server -Xms128m -Xmx128m -Xss128k"
DEFAULT_OPTS="$DEFAULT_OPTS -XX:+AggressiveOpts -XX:+UseParallelGC -XX:+UseBiasedLocking -XX:NewSize=64m"
# -Ddalserver.home 
DEFAULT_OPTS="$DEFAULT_OPTS -Ddalserver.home=\"$DALSERVER_HOME\""
DEFAULT_OPTS="$DEFAULT_OPTS -Dclassworlds.conf=\"$DALSERVER_HOME/bin/dalserver.classworlds\""
CMD="exec \"$JAVA_HOME/bin/java\" $DEFAULT_OPTS $OPTS -classpath \"$CLASSPATH\"  $MAIN_CLASS $@"
eval $CMD


  命令14
  端口查看  
    今天发现服务器上Tomcat 8080端口起不来,老提示端口已经被占用。
 使用命令:
 netstat –apn |grep 8080
    top  查看系统资源占用
 

posted @ 2012-03-31 11:35 云云 阅读(1863) | 评论 (0)编辑 收藏

The current (8.0-SNAPSHOT) build uses version 1.5 of the maven-svn-revision-number-plugin plugin, when source code has been checked out using a subversion client version 1.7 the build fails with a subversion error because the repository metadata in the working copy is not upward compatible, 
com.google.code.maven-svn-revision-number-plugin:1.5:maven-svn-revision-number-plugin uses SVNkit 1.3.x which is compatible with subversion 1.6=<

When the maven-svn-revision-number-plugin is updated to version 1.7 (currently latest release of this plugin) you can specify a commandline option (-Dsvn-revision-number.failOnError=false) to ignore the subversion error and the build completes normally. Note that com.google.code.maven-svn-revision-number-plugin:1.7:maven-svn-revision-number-plugin still relies on svnkit:1.3.5 so the error is still there, the updated plugin just gives an option to ignore it either from the commandline or as a config option.

出现了这样的错误的时候 是svn版本问题
由于我的电脑上安装了客户端是1.7的版本
但是pom.xml中使用的是1.6
   <plugin>
    <groupId>com.google.code.maven-svn-revision-number-plugin</groupId>
    <artifactId>maven-svn-revision-number-plugin</artifactId>
    <version>1.6</version>
    <executions>
     <execution>
      <goals>
       <goal>revision</goal>
      </goals>
     </execution>
    </executions>
    <configuration>
     <entries>
      <entry>
       <prefix>SVN</prefix>
      </entry>
     </entries>
    </configuration>
   </plugin>
在编绎时  出现了上述异常 ,我想可能是版本问题 于是乎我就把pom.xml中maven-svn-revision-number-plugin的<version>1.6</version>改成了<version>1.7</version>
心想可能问题解决了 没想到编绎时还是报以上错误
于是在网上狂搜 终于发现了 有人也出现了这样的问题
经过实验发现这个方案靠谱 就记录下来了 路过的人看到了也可以方便解决问题

方案:
     当然上面的<version>1.7</version>还是要保留的 因为我的客户端也是1.7
然后呢  在编绎的时候  要加入 -Dsvn-revision-number.failOnError=false
来个完整的 命令:eclipse:eclipse -Dsvn-revision-number.failOnError=false

就这样ok了。



posted @ 2012-03-21 09:44 云云 阅读(22068) | 评论 (3)编辑 收藏

用java写服务程序时经常会涉及到监控某些配置文件,当配置文件发生变化时实时重新加载该文件的内容到内存.
实际上log4j里有现成的类FileWatchdog做了类似的工作.我们只需继承它,然后重写它的一些方法就可以了.
 
   /**使用log4j的监控狗 */
    
public class IPAccessFileWatchdog extends FileWatchdog {
        
public IPAccessFileWatchdog(String filename){
            
super(filename);
        }


        
public void doOnChange() {
            List
<String> list = IPAccessController.this.loadIPRule(new File(this.filename));
            
if (list != null{
                IPAccessController.
this.ipRule = list.toArray(new String[list.size()]);
            }
 else {
                IPAccessController.
this.ipRule = null;
            }

            LogLog.warn(
"ip access config load completed from file:" + filename);
        }

    }

}


FileWatchdog的代码也很简单,其实就是起一个线程,每隔固定的时间扫描一次监控的文件.我把代码也贴出来:'


// Contributors:  Mathias Bogaert

package org.apache.log4j.helpers;

import java.io.File;
import org.apache.log4j.helpers.LogLog;

public abstract class FileWatchdog extends Thread {

  
  
static final public long DEFAULT_DELAY = 60000
  
  
protected String filename;
  
  
  
protected long delay = DEFAULT_DELAY; 
  
  File file;
  
long lastModif = 0
  
boolean warnedAlready = false;
  
boolean interrupted = false;

  
protected
  FileWatchdog(String filename) 
{
   
this.filename = filename;
   file 
= new File(filename);
   setDaemon(
true);
   checkAndConfigure();
  }


  
  
public
  
void setDelay(long delay) {
   
this.delay = delay;
  }


  
abstract 
  
protected 
  
void doOnChange();

  
protected
  
void checkAndConfigure() {
   
boolean fileExists;
   
try {
    fileExists 
= file.exists();
   }
 catch(SecurityException  e) {
    LogLog.warn(
"Was not allowed to read check file existance, file:["+
 filename
+"].");
    interrupted 
= true// there is no point in continuing
    return;
   }


   
if(fileExists) {
    
long l = file.lastModified(); // this can also throw a SecurityException
    if(l > lastModif) {      // however, if we reached this point this
lastModif = l;        // is very unlikely.
doOnChange();
warnedAlready 
= false;
    }

   }
 else {
    
if(!warnedAlready) {
LogLog.debug(
"["+filename+"] does not exist.");
warnedAlready 
= true;
    }

   }

  }


  
public
  
void run() {   
   
while(!interrupted) {
    
try {
  Thread.sleep(delay);
    }
 catch(InterruptedException e) {
// no interruption expected
    }

    checkAndConfigure();
   }

  }

}


posted @ 2012-02-17 14:03 云云 阅读(3530) | 评论 (0)编辑 收藏

<?xml version="1.0" encoding="UTF-8" ?>
<person>
    
<name>yunyun</name>
    
<gender>true</gender>
    
<address>shanghai</address>
    
<contents>cc</contents>
    
<contents>ss</contents>
    
<taxs>
        
<string>1</string>
        
<string>2</string>
        
<string>3</string>
    
</taxs>
</person>

JavaBean
public class Person2 {
    
private String name;
    
private boolean gender;
    
private String homeAddress;
    
private List<String> contentslist;
    
private String[] taxs;

    @Override
    
public String toString() {
        
return ToStringBuilder.reflectionToString(this);
    }


}

测试类 解析xml 反序列化到javaBean object

public class TestXmlToObject2 {

     
public static final XStream xstream=new XStream();
     
     
static{
         xstream.alias(
"person", Person2.class);//类别名
         xstream.aliasField("address", Person2.class"homeAddress"); //属性别名
         xstream.alias("contents",String.class);//private List<String> contentslist;是string类型
         xstream.addImplicitCollection(Person2.class"contentslist");//隐式集合 隐藏contentslist
         Person2 person=(Person2)xstream.fromXML(TestXmlToObject2.class.getClassLoader().getResourceAsStream("person02.xml"));
         System.out.println(person.toString());
     }

    
    
public static void main(String[] args) {

    }


}


二: 注解方式
xml:
 
<?xml version="1.0" encoding="UTF-8" ?>
<person>
    
<name>yunyun</name>
    
<gender>true</gender>
    
<address>shanghai</address>
    
<company>yihaodian</company>
    
<sources>
        
<string>firstSources</string>
        
<string>secondSources</string>
    
</sources>
    
<part>firstPart</part>
    
<part>secondPart</part>
</person>

javaBean
@XStreamAlias("person")
public class Person3 {
    private String name;
    private boolean gender;
    @XStreamAlias("address")
    private String homeAddress;
    private String company;
    @XStreamImplicit(itemFieldName="part")
    private List
<String> content;
    private String[] sources;
    
    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}

测试
public class TestXmlToObject3 {

     
public static final XStream xstream=new XStream();
     
     
static{
         xstream.processAnnotations(Person3.
class);//显示声明使用注解
         xstream.autodetectAnnotations(true);
         Person3 person
=(Person3)xstream.fromXML(TestXmlToObject3.class.getClassLoader().getResourceAsStream("person03.xml"));
         System.out.println(person.toString());
     }

     
    
    
    
    
public static void main(String[] args) {

    }


}

POM.xml
        <dependency>
            
<groupId>com.thoughtworks.xstream</groupId>
            
<artifactId>xstream</artifactId>
            
<version>1.3.1</version>
        
</dependency>
        
<dependency>
            
<groupId>commons-lang</groupId>
            
<artifactId>commons-lang</artifactId>
            
<version>2.4</version>
        
</dependency>



posted @ 2012-01-31 17:59 云云 阅读(16886) | 评论 (3)编辑 收藏

tomcat 需要远程debug的话 需要在startup.bat中加入下面这段话

SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8788

然后在eclipse 中新建远程debug 端口号就是上面的address 8788 

posted @ 2011-12-09 16:37 云云 阅读(178) | 评论 (0)编辑 收藏

del D:\logs\* /s/q

posted @ 2011-12-09 15:04 云云 阅读(214) | 评论 (0)编辑 收藏

1、拦截器是基于java的反射机制的,而过滤器是基于函数回调
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。
下面通过实例来看一下过滤器和拦截器的区别:
使用拦截器进行/admin 目录下jsp页面的过滤
<package name="newsDemo" extends="struts-default"
namespace="/admin">
<interceptors>
<interceptor name="auth" class="com.test.news.util.AccessInterceptor" />
<interceptor-stack name="authStack">
<interceptor-ref name="auth" />
</interceptor-stack>
</interceptors>
<!-- action -->
<action name="newsAdminView!*" class="newsAction"
method="{1}">
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="authStack">
</interceptor-ref>
下面是我实现的Interceptor class:
package com.test.news.util;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.test.news.action.AdminLoginAction;
/**
* @author chaoyin
*/
public class AccessInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = -4291195782860785705L;
@Override
public String intercept(ActionInvocation actionInvocation) throws Exception {
ActionContext actionContext = actionInvocation.getInvocationContext();
Map session = actionContext.getSession();

//except login action
Object action = actionInvocation.getAction();
if (action instanceof AdminLoginAction) {
return actionInvocation.invoke();
}
//check session
if(session.get("user")==null ){
return "logout";
}
return actionInvocation.invoke();//go on
}
}
过滤器:是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符.
使用过滤器进行/admin 目录下jsp页面的过滤,首先在web.xml进行过滤器配置:
<filter>
<filter-name>access filter</filter-name>
<filter-class>
com.test.news.util.AccessFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>access filter</filter-name>
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
下面是过滤的实现类:
package com.test.news.util;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class AccessFilter implements Filter {
/**
* @author chaoyin
*/

public void destroy() {
}
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)arg0;
HttpServletResponse response = (HttpServletResponse)arg1;
HttpSession session = request.getSession();
if(session.getAttribute("user")== null && request.getRequestURI().indexOf("login.jsp")==-1 ){
response.sendRedirect("login.jsp");
return ;
}
filterChain.doFilter(arg0, arg1);
}
public void init(FilterConfig arg0) throws ServletException {
}
}

posted @ 2011-11-21 18:27 云云 阅读(21095) | 评论 (1)编辑 收藏

解决方案一:
原来,是${java.home}在作怪,eclipse 没有使用 JAVA_HOME



默认,eclipse 使用 C:"windows"system32"javaw.exe 作为 JVM,当然找不到tools.jar



解决方法如下:



修改 eclipse.exe 目录下的 eclipse.ini 指定vm,,注意 -vm后面不能有空格。

 


 

-vmD:\Program Files\Java\jdk1.6.0_23\bin\javaw.exe
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms40m
-Xmx512m
-XX:PermSize=64M
-XX:MaxPermSize=512M

解决方案二:


配置pom.xml文件

 

  1. <properties>
  2. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  3. <spring.version>3.0.5.RELEASE</spring.version>
  4. <java.home>jdk路径</java.home>
  5. </properties>
  6. <profiles>
  7. <profile>
  8. <id>default-tools.jar</id>
  9. <activation>
  10. <property>
  11. <name>java.vendor</name>
  12. <value>Sun Microsystems Inc.</value>
  13. </property>
  14. </activation>
  15. <dependencies>
  16. <dependency>
  17. <groupId>com.sun</groupId>
  18. <artifactId>tools</artifactId>
  19. <version>1.5.0</version>
  20. <scope>system</scope>
  21. <systemPath>${java.home}/lib/tools.jar</systemPath>
  22. </dependency>
  23. </dependencies>
  24. </profile>
  25. </profiles>
在pom.xml文件中将这段配置写上,试一下。注意几个位置的内容编写。

posted @ 2011-11-21 11:02 云云 阅读(23567) | 评论 (2)编辑 收藏

Static 静态:这里主要记录的是静态程序块和静态方法

如果有些代码必须在项目启动的时候就执行,就需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化但是不执行,在不创建对象的情况下,可以供其他程序调用,而在调用的时候才执行,这需要使用静态方法,这种代码是被动执行的. 静态方法在类加载的时候 就已经加载 可以用类名直接调用。

静态代码块和静态方法的区别是:


静态代码块是自动执行的;

静态方法是被调用的时候才执行的.

静态方法:如果我们在程序编写的时候需要一个不实例化对象就可以调用的方法,我们就可以使用静态方法,具体实现是在方法前面加上static,如下:

public static void method(){}

在使用静态方法的时候需要注意一下几个方面:

在静态方法里只能直接调用同类中其他的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。这是因为,对于非静态的方法和变量,需要先创建类的实例对象后才可使用,而静态方法在使用前不用创建任何对象。(备注:静态变量是属于整个类的变量而不是属于某个对象的)

静态方法不能以任何方式引用this和super关键字,因为静态方法在使用前不用创建任何实例对象,当静态方法调用时,this所引用的对象根本没有产生。

静态程序块:当一个类需要在被载入时就执行一段程序,这样可以使用静态程序块。

public class DemoClass {

private DemoClass(){}

public static DemoClass _instance;

static{

if(null == _instance ){

_instance = new DemoClass();

}

}

public static DemoClass getInstance(){

return _instance;

}

}

这样的程序在类被加载的时候就执行了static中的代码。

Ps:java中类的装载步骤:

在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下:

所谓装载就是寻找一个类或是一个接口的二进制形式并用该二进制形式来构造代表这个类或是这个接口的class对象的过程。其中类或接口的名称是给定了的。

装载:查找和导入类或接口的二进制数据;

链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;

校验:检查导入类或接口的二进制数据的正确性;

准备:给类的静态变量分配并初始化存储空间;

解析:将符号引用转成直接引用;

初始化:激活类的静态变量的初始化Java代码和静态Java代码块

本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2010-03/24783.htm

posted @ 2011-11-14 16:15 云云 阅读(4810) | 评论 (1)编辑 收藏

一、基本语法

1、"#"用来标识Velocity的脚本语句,包括#set、#if 、#else、#end、#foreach、#end、#iinclude、#parse、#macro等;
如:
#if($info.imgs)
<img src="$info.imgs" border=0>
#else
<img src="noPhoto.jpg">
#end

2、"$"用来标识一个对象(或理解为变量);
如:$i、$msg、$TagUtil.options(...)等。

3、"{}"用来明确标识Velocity变量;
比如在页面中,页面中有一个$someonename,此时,Velocity将把someonename作为变量名,若我们程序是想在someone这 个变量的后面紧接着显示name字符,则上面的标签应该改成${someone}name。

4、"!"用来强制把不存在的变量显示为空白。
如当页面中包含$msg,如果msg对象有值,将显示msg的值,如果不存在msg对象同,则在页面中将显示$msg字符。这是我们不希望的,为了把不存 在的变量或变量值为null的对象显示为空白,则只需要在变量名前加一个“!”号即可。
如:$!msg

二、在EasyJWeb中的最佳实践

理论上你可以在EasyjWeb模板使用所有Velocity的脚本及功能,但我们不推荐你在界面模板中使用过多过复杂的脚本表达方式,在万不得已的情况下,不要在界面模板中加入任何复杂的逻辑,更不要在界面模板中加入变量声明、逻辑运算符等等。

在EasyJWeb中,我们提供了五条基本的模板脚本语句,基本上就能满足所有应用模板的要求。这四条模板语句很简单,可以直接由界面设计人员来添加。在当前很多EasyJWeb的应用实践中,我们看到,所有界面模板中归纳起来只有下面四种简单模板脚本语句即可实现:
1、$!obj 直接返回对象结果。
如:在html标签中显示java对象msg的值。<p>$!msg</p>
在html标签中显示经过HtmlUtil对象处理过后的msg对象的值 <p>$!HtmlUtil.doSomething($!msg)</p>

2、#if($!obj) #else #end 判断语句
如:在EasyJWeb各种开源应用中,我们经常看到的用于弹出提示信息msg的例子。
#if($msg)
<script>
alert('$!msg');
</script>
#end
上面的脚本表示当对象msg对象存在时,输出<script>等后面的内容。

3、#foreach( $info in $list) $info.someList #end 循环读取集合list中的对象,并作相应的处理。
如:EasyJF开源论坛系统中论(0.3)坛首页显示热门主题的html界面模板脚本:
#foreach( $info in $hotList1)
<a href="/bbsdoc.ejf?easyJWebCommand=show&&cid=$!info.cid" target="_blank">$!info.title</a><br>
#end
上面的脚本表示循环遍历hotList1集合中的对象,并输出对象的相关内容。

4、#macro(macroName)#end 脚本函数(宏)调用,不推荐在界面模板中大量使用。
如:在使用EasyJWeb Tools快速生成的添删改查示例中,可以点击列表的标题栏进行升降排序显示,这是我们在EasyJWeb应用中经常看到的一个排序状态显示的模板内容。
函数(宏)定义,一般放在最前面
#macro(orderPic $type)
#if ($orderField.equals($type))
<img src="http://images.cnblogs.com/ico/${orderType}.gif">
#end
#end
具体的调用如:<font color="#FFFFFF">头衔#orderPic("title")</font>

经过测试,宏不支持方法重载

 

5、包含文件#inclue("模板文件名")或#parse("模板文件名")
主要用于处理具有相同内容的页面,比如每个网站的顶部或尾部内容。
使用方法,可以参考EasyJF开源Blog及EasyJF开源论坛中的应用!
如:#parse("/blog/top.html")或#include("/blog/top.html")
parse与include的区别在于,若包含的文件中有Velocity脚本标签,将会进一步解析,而include将原样显示。


三、关于#set的使用

在万不得已的时候,不要在页面视图自己声明Velocity脚本变量,也就是尽量少使用#set。有时候我们需要在页面中显示序号,而程序对象中又没有包 含这个序号属性同,可以自己定义。如在一个循环体系中,如下所示:
#set ($i=0)
#foreach($info in $list)
序号:$i
#set($i=$i+1)
#end

四、Velocity脚本语法摘要

1、声明:#set ($var=XXX)
左边可以是以下的内容
Variable reference
String literal
Property reference
Method reference
Number literal #set ($i=1)
ArrayList #set ($arr=["yt1","t2"])
算术运算符

2、注释:
单行## XXX
多行#* xxx
xxxx
xxxxxxxxxxxx*#

References 引用的类型
3、变量 Variables
以 "$" 开头,第一个字符必须为字母。character followed by a VTL Identifier. (a .. z or A .. Z).
变量可以包含的字符有以下内容:
alphabetic (a .. z, A .. Z)
numeric (0 .. 9)
hyphen ("-")
underscore ("_")

4、Properties
$Identifier.Identifier
$user.name
hashtable user中的的name值.类似:user.get("name")

5、Methods
object user.getName() = $user.getName()

6、Formal Reference Notation
用{}把变量名跟字符串分开


#set ($user="csy"}
${user}name
返回csyname

$username
$!username
$与$!的区别
当找不到username的时候,$username返回字符串"$username",而$!username返回空字符串""

7、双引号 与 引号
#set ($var="helo")
test"$var" 返回testhello
test'$var' 返回test'$var'
可以通过设置 stringliterals.interpolate=false改变默认处理方式

8、条件语句
#if( $foo )
<strong>Velocity!</strong>
#end
#if($foo)
#elseif()
#else
#end
当$foo为null或为Boolean对象的false值执行.

9、逻辑运算符:== && || !

10、循环语句#foreach($var in $arrays ) // 集合包含下面三种Vector, a Hashtable or an Array
#end
#foreach( $product in $allProducts )
<li>$product</li>
#end

#foreach( $key in $allProducts.keySet() )
<li>Key: $key -> Value: $allProducts.get($key)</li>
#end

#foreach( $customer in $customerList )
<tr><td>$velocityCount</td><td>$customer.Name</td></tr>
#end

11、velocityCount变量在配置文件中定义
# Default name of the loop counter
# variable reference.
directive.foreach.counter.name = velocityCount
# Default starting value of the loop
# counter variable reference.
directive.foreach.counter.initial.value = 1

12、包含文件
#include( "one.gif","two.txt","three.htm" )

13、Parse导入脚本
#parse("me.vm" )

14、#stop 停止执行并返回

15、定义宏Velocimacros ,相当于函数 支持包含功能
#macro( d )
<tr><td></td></tr>
#end
调用
#d()

16、带参数的宏
#macro( tablerows $color $somelist )
#foreach( $something in $somelist )
<tr><td bgcolor=$color>$something</td></tr>
#end
#end

17、Range Operator
#foreach( $foo in [1..5] )

附:《浅析MVC框架中View层的优雅设计及实例》

作者:EasyJF开源团队 大峡

在基于B/S的应用程序开发中,从基本的技术分工上来说就是两大块,一是软件显示界面,另一个是程序逻辑。在N年前的脚本语言时代,无论是asp、 php还是jsp,我们基本是都是把这两者柔和在一起的。尽管我们想方设法做好很多函数或者包含文件来努力达到软件的复用,但仍然无法满足多变的用户需 求,这主要是因为以前的纯脚本编码方式无法很好支持及应用面向对象(OO)领域中的强大功能。

在常见的B/S软件项目中,界面的设计包括html界面、Wap界面及其它由文本字符协议为基本表示的界面等。以我们接触最多的html页面为例子,在 做这些界面的时候往往需要美工先使用photoshop或fireworks等图形界面设计工具进行全局设计,然后再使用进行Dreamweaver等 html页面制作工具进行加工制作。而强大的程序逻辑及后台处理都是由服务器端程序完成,这些程序具有较高的稳定性,其开发工具如JBuilder、 Eclipse等对View层的界面无法很好的支持(当然那些用记事本写界面的应用除外),这就使得很多MVC框架的设计都无法两全齐美。

作位一个比较友好的MVC的框架,在简化服务器应用开发的同时,还需要在View这一层设计上不要过多的影响到界面人员的工作,最基本的要求就是不要过 多的加入一些设计软件不支持的标签等元素(如Struts的很多标签在Dreamweaver中都不支持)。这里我们以EasyJWeb为例,探讨在 View层如何实现比较合理的设计。

EasyJWeb作为一个快速Java Web MVC框架,其设计目标不尽是要简化软件开发人员的代码书写工作,更是要能方便界面设计人员的工作。

当然,要使界面能跟后台程序逻辑能融合,显示界面及程序逻辑之间需要一定的对话协议在所难免。EasyJWeb作为一个MVC框架,同样也存在着这样的对话协议,这就是EasyJWeb中的界面模板标识语言。

在当前发布的版本中,EasyJWeb界面模板标识语言使用的是Apache开源的Velocity模板引擎(template engine),当然以后会根据际需要加入更多的模板引擎以供框架应用者选择。

Velocity是一个基于java的模板引擎(template engine),它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义的对象。作为一个比较完善的模板引擎,Velocity的功能是比较强大的,但强大的同时也增加了应用复杂 性。

理论上你可以在EasyjWeb模板使用所有Velocity的脚本及功能,但我们不推荐你在界面模板中使用过多过复杂的脚本表达方式,在万不得已的情况下,不要在界面模板中加入任何复杂的逻辑,更不要在界面模板中加入变量声明、逻辑运算符等等。

在EasyJWeb中,我们提供了四条基本的模板脚本语句,基本上就能满足所有应用模板的要求。这四条模板语句很简单,可以直接由界面设计人员来添加。在当前很多EasyJWeb的应用实践中,我们看到,所有界面模板中归纳起来只有下面四种简单模板脚本语句即可实现:

1、$!obj 直接返回对象结果。

如:在html标签中显示java对象msg的值。<p>$!msg</p>
在html标签中显示经过HtmlUtil对象处理过后的msg对象的值.<p>$!HtmlUtil.doSomething($!msg)</p>

2、#if($!obj) #else #end 判断语句

如:在EasyJWeb各种开源应用中,我们经常看到的用于弹出提示信息msg的例子。
#if($msg)
<script>
alert('$!msg');
</script>
#end
上面的脚本表示当对象msg对象存在时,输出<script>等后面的内容。

3、#foreach( $info in $list) $info.something #end 循环读取集合list中的对象,并作相应的处理。

如:EasyJF开源论坛系统中论坛首页显示热门主题的html界面模板脚本

#foreach( $info in $hotList1)
<a href="/bbsdoc.ejf?easyJWebCommand=show&&cid=$!info.cid" target="_blank">$!info.title</a><br>
#end
上面的脚本表示循环遍历hotList1集合中的对象,并输出对象的相关内容。

4、#macro(macroName)#end 脚本函数(宏)调用,不推荐在界面模板中大量使用。

如:在EasyJF简易订销管等系统中经常看到的一个排序状态显示的模板内容。
函数(宏)定义,一般放在最前面
#macro(orderPic $type)
#if ($orderField.equals($type))
<img src="http://images.cnblogs.com/ico/${orderType}.gif">
#end
#end

具体的调用如:<font color="#FFFFFF">头衔#orderPic("title")</font>


总结:
当然,在实际应用项目中,为了实现界面的更加友好、人性化,会出现很多复、易变的需求。如根据对象的不同状态,显示不同的提示颜色、提示语音等功能。在这 种时候,仍然要慎用太多的模板脚本功能,大多数需求都可以通过变通的方式解决,有些信息可以直接在对象中增加逻辑转化信息,有些界面要求可以通过在界面中 使用与特定界面有关的表达方式来实现,如html页面中使用javascript、css,Wap页面中使用WMLScript等等。只有,这样才能确保 证你的系统核心不受界面的的影响及控制,才能更好的扩展及维护。

我们希望你能成为真正的程序高手,而不只是精通某个处于表层的脚本语言,因此也不希望广大Java开发人员在View层消耗太多的时间。

由于水平有限,本文所谈的内容有N多不合理或者需要改进的地方,恳请大家指正!

附:EasyJWeb简介

EasyJWeb是基于java技术,应用于WEB应用程序快速开发的MVC框架,框架设计构思来源于国内众多项目实践,充分借签了当前主流的开源 Web框架(Struts、JSF、Tapestry 、Webwork等),吸取了其优点及精华,利用Velocity作为模板页面引擎,是一个实现了页面及代码完全分离的MVC开发框架,是一个旨在于为中 小型Web应用系统提供快速开发实践的简易Web框架。

EasyJF开源团队于2006年初才开始建设,因此当前整个开发团队组建以及所发布的作品,都显得极不成熟。EasyJWeb仍然处于测试阶段,请广大的Java爱好者多多批评及建议,同时也非常欢迎您能加入到我们的国产

posted @ 2011-11-12 14:40 云云 阅读(2720) | 评论 (0)编辑 收藏

仅列出标题
共12页: First 上一页 3 4 5 6 7 8 9 10 11 下一页 Last