最近由于工作原因在研究、应用Maven,有了一些体会就写成了此文。本文虽然是Maven2的入门文章,但并不涉及 Maven的历史、下载与安装,这些内容可以到Maven的官方网站上了解。本文主要是关注Maven中的重要概念,并以一个实例来阐述使用Maven的 基本方法。文末有例子代码下载的链接。 

Continue reading "Maven入门--概念与实例(转载)"
Posted on December 15, 2006 9:22 PM | | Comments (0) | TrackBacks (0)

Java世界中我们很多的开发人员选择用 Ant来构建项目,一个 build.xml能够完成编译、测试、打包、部署等很多任务,但我们也碰到了很多的问题,如 jar文件管理混乱,各个项目结构和 build.xml相差很大等等。而 Maven的出现,给项目提供了更多的支持。


Continue reading "用 Maven 做项目管理"
Posted on December 15, 2006 9:22 PM | | Comments (0) | TrackBacks (0)

[关键字]Maven 自动化 WASCE 

本文展示了使用 Maven 来管理项目,自动化项目的构建和到 WASCE 服务器的发布,提高项目的开发效率。
引言


Maven 是一个软件项目管理工具,它能够管理一个项目生命周期中的构建、文档、报告、发布等。Websphere Application Server Community Edition (简称WASCE)是IBM发布的一款免费的开源 J2EE 应用服务器。WASCE 构建在 Apache 社区开发的 Geronimo 服务器的基础之上,提供了更广泛的硬件和软件平台的支持。在开发 J2EE 项目时,代码的编译、单元测试、文档的生成以及把应用部署到 WASCE 是一个烦琐而且需要反复进行的过程。本文展示了使用 Maven 来管理项目,自动化项目的构建和到 WASCE 服务器的发布,提高项目的开发效率。

Continue reading "使用 Maven 自动化 WASCE 程序的开发部署"
Posted on December 15, 2006 9:19 PM | | Comments (0) | TrackBacks (0)

摘要:

如果你已经有十次输入同样的Ant targets来编译你的代码、jar或者war、生成javadocs,你一定会自问,是否有有一个重复性更少却能同样完成该工作的方法。Maven便 提供了这样一种选择,将你的注意力从作业层转移到项目管理层。Maven项目已经能够知道如何构建和捆绑代码,运行测试,生成文档并宿主项目网页。看完本 文,你应该能够从头建立一个Maven的项目,使用Maven进行相关管理,创建基于某些感兴趣报告的简单的web站点。
Continue reading "Maven起步-教你开始使用Maven"
Posted on December 15, 2006 9:16 PM | | Comments (0) | TrackBacks (0)


以XForum来说明如何使用JAAS做用户验证

JAAS的简单流程:
初始化一个generic的LoginContext
Call LoginContext.login()验证用户
如果成功,获得一个经过代表当前用户的Subject object,Subject中含有用户数据
不成功得到一个LoginException


开发过程:

1.建立一个Implements java.secuirty.principal的User object,因为在Subject中的数据必须是
Pricipal,所以我们建议个User principal,这个principal中目前只保存用户名信息

2.建立一个客户化的LoginModule,这个Class 需要Implement javax.security.auth.spi.LoginModule;
由于XForum使用Mysql数据库作为用户数据的数据源,因此我们建立一个Database LoginModule.
LoginModule中的所有methods都是由一个generic 的LoginContext来调用的.

/*
 * A dependent Database login module for JAAS
 * and create the connection
 *
 * @author Charles Huang
 * @since JDK1.4
 * @version $Id: DataBaseLoginModule.java,v 1.1 2002/09/10 02:05:48 charles Exp $
 */
public class DataBaseLoginModule implements LoginModule{

   /**
    *
    */
    public void initialize(Subject subject, CallbackHandler callbackHandler,
                       Map sharedState, Map options) {
        this.subject = subject;
        //CallbackHandler是JAAS用来在用户的application
        //比如说jsp或swing application的用户界面和LoginModule之间传递数据的
        //Data Holder
        this.callbackHandler = callbackHandler;
   }



   public boolean login() throws LoginException {
    try{
         //利用CallBack objects
         final Callback[] calls= new Callback[2];
         calls[0]=new NameCallback("name");
         calls[1]=new PasswordCallback("Password",false);
          
         //从 CallbackHandler里获得用户
         //输入的用户名和密码,
         callbackHandler.handle(calls);

         // 查询数据库,比较密码
     }catch( AccountNotFoundException ){
         throw LoginExceptionm("No such User");
     }
     isAuthenticated = true;
     return isAuthenticated;
   }

    /**
    * 这里做验证后的处理,在XForum如果成功,在Subject中加入用户名.一个Subject代表一个
    *被验证 的
    *用户.Subject中可以包含较丰富的数据,如用户名,role等数据,会被web application引用
    */
    public boolean commit() throws LoginException {
        if ( isAuthenticated ){
            subject.getPrincipals().add( new User( username ) );
            //TODO: Put in role information later
        }else{
            throw new LoginException("Authentication fails");
        }
        return isAuthenticated;
}

    ......
}

3.建立一个客户化的CallbackHandler用来在用户的application和LoginModule之间传递数据.因为web
application不回直接调用LoginModul.这里使用了visitor pattern.XForum中的CallbackHandler只传
递两个数据:用户名和密码

public class SimpleCallbackHandler implements CallbackHandler{
    private String username;
    private String password;

    public SimpleCallbackHandler( final String username, final String password) {
        this.username = username;
        this.password = password;
    }
     
    //在LoginModule的login method中,LoginModule 调用这个handle()并pass in 两个
    // CallBack Objects,着两个callback objects被populated
    public void handle(Callback[] callbacks)
            throws IOException, UnsupportedCallbackException {
        for( int index = 0; index < callbacks.length; index++ ){
            if(callbacks[ index ] instanceof NameCallback){
                NameCallback ncb = (NameCallback)callbacks[ index ];
                ncb.setName(username);
            }
            if(callbacks[ index ] instanceof PasswordCallback){
                PasswordCallback pcb = (PasswordCallback)callbacks[ index ];
                pcb.setPassword(password.toCharArray());
            }
        }
    }
}

4.在web application中用JAAS严正用户,在XForum中,这是在LogonAction

    ......
    // let the LoginContext instantiate a new Subject,其中userName and password
    //从HttpRequest中获得,并利用SimpleCallbackHandler传递给LoginModule
    LoginContext lc = new LoginContext("XForumLogin",
                       new SimpleCallbackHandler( userName, password ) );
    // LoginContext 调用LoginModule的login()来验证用户
    lc.login();

  //获得一个经过验证的Subject object,这个Subject中包含一个User object
    subject = lc.getSubject();
    ......

5.建里一个LoginModule的Configuration file.JAAS中的LoginContext会看这个文件,并动态的Load这
个class和产生一个LoginModule的Instance用来验证用户,在XForum中的configuration file为
XForumLogin.config

XForumLogin{
   org.redsoft.forum.security.DataBaseLoginModule required debug=true;
};

6.修改{java_home}/jre/lib/security/java.security来告诉JAAS 配置文件XForumLogin.config在那


#
# Default login configuration file
#
login.config.url.1=file:E:/jakarta-tomcat-4.0.2/webapps/forum/WEB-INF/XForumLogin.config

重起Tomcat,done

Posted on December 15, 2006 3:55 PM | | Comments (0) | TrackBacks (0)

1、

PermGen space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError: PermGen space从表面上看就是内存益出,解决方法也一定是加大内存。说说为什么会内存益出:这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。

改正方法:-Xms256m -Xmx256m -XX:MaxNewSize=256m -XX:MaxPermSize=256m
Continue reading "java.lang.OutOfMemoryError: PermGen space及其解决方法"
Posted on December 15, 2006 11:02 AM | | Comments (0) | TrackBacks (1)

MagickImage mi = null;
int srcWidth = mi.getDimension().width;
int srcHeight = mi.getDimension().height; 

以下是java的部分:

MagickImage mi = null;
int srcWidth = mi.getDimension().width;
int srcHeight = mi.getDimension().height;

再结合convert命令来完成图片压缩,使得图片压缩不至于失去真实效果。好啊

以下是php的实现:

 define(PIC_WIDTH, 260 , true);  // 区分大小写
 define(PIC_HEIGHT, 150 , true);// 区分大小写


if(true){
 // start convert big photo  to small photo
 if($tempFileName != "" && file_exists($tempFileName)){
  list($width, $height, $type, $attr) = getimagesize($tempFileName); 
  //echo "($width, $height, $type, $attr)";
   // 计算比例   
   $proportion = "100%";
   if($width > $height){
    // 宽度 大于 高度 , 以宽度为准
    $proportion = round(PIC_WIDTH/$width,4)*100 ;
   } else {
    $proportion = round(PIC_HEIGHT/$height,4)*100 ;
   }   
   //convert
   $CONVERT_BIN_PATH = "/usr/bin/convert";
   $PIC_SIZE = $proportion."%x".$proportion."%";  //w * h

   $exec_str = $CONVERT_BIN_PATH." -geometry ".$PIC_SIZE;
   $exec_str .= " ".$tempFileName." ".PHOTOSDIR.$smallphoto;
   
   /*    
   convert -sample 80x40 input.jpg output.jpg
   /usr/bin/convert -geometry 28.85%x28.85% 1090311879.jpg 10903118792.jpg
   echo $exec_str." <BR> \n ";
   */
   
   exec($exec_str);
   unset($exec_str);
 }
}

Posted on December 13, 2006 7:01 PM | | Comments (0) | TrackBacks (0)


下面的讨论以Windows平台的Sun MicroSystem实现的java5虚拟机为蓝本,其他操作系统或其他公司实现的虚拟机参数会有部分不同,但大部分含义都和Windows上的类似。Java5与以前版本相比,虚拟机参数大部分保持了向前兼容,同时也增加了一些新的参数,本文将对这些参数的作用作详细描述,使虚拟机能更符合运行环境的需要,获得更好的性能和稳定性。

Continue reading "Java虚拟机参数详解"
Posted on December 13, 2006 5:10 PM | | Comments (0) | TrackBacks (0)

“Nearly 80 to 85 percent of database performance problems arise from the application database's design or the application's own code. Good transaction throughput requires an application designed from the database up, with performance and scalability in mind.”
----DB2 Magazine

P6Spy & SQL Profiler & IronTrack SQL

P6Spy是一个可以用来在应用程序中拦截和修改数据操作语句的开源框架。
通过P6Spy我们可以对SQL语句进行拦截,相当于一个SQL语句的记录器,这样我们可以用它来作相关的分析,比如性能分析。

一、P6Spy的安装与使用
1、从 http://www.p6spy.com/ 下载P6Spy的文件包,也可以下载它的源文件包来研究;
2、把P6Spy的jar包p6spy.jar放到classpath中,如果是Web应用程序则放在YourWebApp/WEB-INF/lib/目录下;
3、把spy.properties放到classes目录下,如果是webapp就放在YourWebApp/WEB-INF/classess/目录下,记得不是lib/目录
4、修改你程序的数据库驱动名称为P6Spy的驱动程序名称com.p6spy.engine.spy.P6SpyDriver其它的都不用更改;
5、打开spy.properties文件,把realdriver的值改为你的程序的数据库驱动名称;
6、运行你的应用程序或Web应用程序,可以在spy.log里看到监测到的sql详细记录信息了。
7、驱动程序加载先后的问题解决
  如果spy.log里出现
  你的程序的数据库驱动名称 is a real driver in spy.properties, but it has been loaded before p6spy. p6spy will not wrap these connections. Either prevent the driver from loading, or try setting 'deregisterdrivers' to true in spy.properties
  请把spy.properties文件里的deregisterdrivers=false改为deregisterdrivers=true,重新运行即可。

二、结合SQL Profiler进行图形化监控与使用
1、从 http://www.jahia.net/ 下载SQL Profiler的文件包进行安装;
2、把p6spy.jar及sqlprofiler.jar放到classpath中,如果是Web应用程序则放在YourWebApp/WEB-INF/lib/目录下;
3、把spy.properties放到classes目录下,如果是webapp就放在YourWebApp/WEB-INF/classess/目录下,记得不是lib/目录
4、修改你程序的数据库驱动名称为P6Spy的驱动程序名称com.p6spy.engine.spy.P6SpyDriver其它的都不用更改;
5、打开spy.properties文件,把realdriver的值改为你的程序的数据库驱动名称;
6、注意要先运行 java -jar sqlprofiler.jar 来启动SQL Profiler,并成功看到启动后界面;
7、然后再启动你的应用程序或服务器,并开始进行正常的系统请求处理操作;
8、这样可以在SQL Profiler图形化的界面上看到结果并进行分析了。
并且可以通过保存按钮导出数据库优化建议的索引脚本

三、结合IronTrack SQL进行图形化监控与使用
1、从 http://www.irongrid.com/ironeyesql 下载IronTrack SQL的文件包进行安装;
2、把irontracksql.jar、p6spy.jar、log4j-1.2.8.jar放到classpath中,如果是Web应用程序则放在YourWebApp/WEB-INF/lib/目录下;
3、把spy.properties放到classes目录下,如果是webapp就放在YourWebApp/WEB-INF/classess/目录下,记得不是lib/目录
4、修改你程序的数据库驱动名称为P6Spy的驱动程序名称com.p6spy.engine.spy.P6SpyDriver其它的都不用更改;
5、打开spy.properties文件,把realdriver的值改为你的程序的数据库驱动名称;
6、设置监听端口号monitorport=2000
6、先运行 java -jar irontracksql.jar 来启动IronTrack SQL;
7、再启动你的应用程序或服务器;
8、可以在 IronTrack SQL 图形化的界面上看到结果并进行分析了。

Continue reading "P6Spy、SQL Profiler、IronTrack SQL"
Posted on December 13, 2006 5:07 PM | | Comments (0) | TrackBacks (0)

首先感谢JScud提供的好文章。《使用FreeMarker生成Html静态文件(实例)》
      在我们的项目中也用到了Freemarker生成静态文件。不过这里我要说的是编码的问题。我们的项目使用的都是UTF-8编码,我直接使用 飞云小侠提供的方法生成的文件在UTF-8编码下察看是乱码,而GBK正常(后来发现因为我用的中文操作系统所以用GBK查看正常)。
      当然我把Freemarker的配置都改成了UTF-8,我的模版文件也是UTF-8编码的。下面是原来的代码
    public void setTemplatePath(Resource templatePath) {
        this.templatePath = templatePath;
        //设置freemarker的参数
        freemarkerCfg = new Configuration();
        try {
            freemarkerCfg.setDirectoryForTemplateLoading(this.templatePath.getFile());
            freemarkerCfg.setObjectWrapper(new DefaultObjectWrapper());
            freemarkerCfg.setDefaultEncoding("UTF-8");
        } catch (IOException ex) {
            throw new SystemException("No Directory found,please check you config.");
        }
    }
    /**
     * 生成静态文件
     * @param templateFileName 模版名称eg:(biz/order.ftl)
     * @param propMap 用于处理模板的属性Object映射
     * @param htmlFilePath 要生成的静态文件的路径,相对设置中的根路径,例如 "/biz/2006/5/"
     * @param htmlFileName 要生成的文件名,例如 "123.htm"
     * @return
     */
    private boolean buildHtml(String templateFileName,Map propMap, String htmlFilePath,String htmlFileName){
        try {
            Template template = freemarkerCfg.getTemplate(templateFileName);
            template.setEncoding("UTF-8");
            //创建生成文件目录
            creatDirs(buildPath.getFilename(),htmlFilePath);
            File htmlFile = new File(buildPath + htmlFilePath + htmlFileName);
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile)));
            template.process(propMap,out);
            out.flush();
            return true;
        } catch (TemplateException ex){
            log.error("Build Error"+templateFileName,ex);
            return false;
        } catch (IOException e) {
            log.error("Build Error"+templateFileName,e);
            return false;
        }
        
    }
下面是修改之后的代码
    /**
     * 生成静态文件
     * @param templateFileName 模版名称eg:(biz/order.ftl)
     * @param propMap 用于处理模板的属性Object映射
     * @param htmlFilePath 要生成的静态文件的路径,相对设置中的根路径,例如 "/biz/2006/5/"
     * @param htmlFileName 要生成的文件名,例如 "123.htm"
     * @return
     */
    private boolean buildHtml(String templateFileName,Map propMap, String htmlFilePath,String htmlFileName){
        try {
            Template template = freemarkerCfg.getTemplate(templateFileName);
            template.setEncoding("UTF-8");
            //创建生成文件目录
            creatDirs(buildPath.getFilename(),htmlFilePath);
            File htmlFile = new File(buildPath + htmlFilePath + htmlFileName);
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile),"UTF-8"));
            template.process(propMap,out);
            out.flush();
            return true;
        } catch (TemplateException ex){
            log.error("Build Error"+templateFileName,ex);
            return false;
        } catch (IOException e) {
            log.error("Build Error"+templateFileName,e);
            return false;
        }
        
    }
原因就在于OutputStreamWriter的不同构造方法

OutputStreamWriter(OutputStream out)
          创建使用默认字符编码的 OutputStreamWriter。
OutputStreamWriter(OutputStream out, String charsetName)
          创建使用指定字符集的 OutputStreamWriter。

 这个是中文JDK的文档说明,刚开始我使用默认的构造函数,所以使用了系统默认的编码,GBK,所以在生成静态文件的时候把UTF-8内容用GBK编码写入了,所以在UTF-8下浏览就有问题。

还有关于修改模版文件同样也要注意这个问题。
    public String loadTemplate(String templateName) {
        StringBuffer sb = new StringBuffer();
        try {
            File file = new File(templatePath+"/"+templateName);
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8"));
            String line = reader.readLine();
            while(line != null)    {
                sb.append(line);
                sb.append("\r\n");
                line = reader.readLine();
            }
            reader.close();
        } catch (IOException e) {
            throw new SystemException("Loading template Error:",e);
        }
        return sb.toString();
    }
    public void saveTemplate(String templateName, String templateContent) {
        try {
            File file = new File(templatePath + "/" + templateName);
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));
            out.write(templateContent);
            out.flush();
            //扔出templatesave事件
            TemplateSaveEvent evt = new TemplateSaveEvent();
            evt.setTemplateName(templateName);
            dispatchTemplateEvent(evt);
        } catch (IOException e) {
            throw new SystemException("Write template Error",e);
        }
    }

Posted on December 11, 2006 9:41 PM | | Comments (0) | TrackBacks (0)
上一页 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 下一页
相关内容
广告计划
最新评论
[评论] 鸿雁 : 默默地为他们祈祷吧
[评论] lym328 : 客源CRM非常不错-----如有需要可以了解
[评论] kevinwu : 作用肯定是有的,Google会首先搜索站
[评论] ss : 其实还真的感觉不到sitemap的作用~
[评论] kevinwu : 谢谢你的关注 :-)
[评论] h51h : 贵博客写得非常的好,界面简洁但内
[评论] snguo : 这里很好 来这里支持下呢?
[评论] redondo : 感谢你分享知识! 这篇文章我转载到
[评论] kevinwu : 就是这本;看来我买的贵了点 - 8折;我
[评论] 安妮 : 《Flex3.0 RIA开发详解:基于ActionScript3.0