学习日记cvs库改变目录结构后eclipse2.1设置要点

  在网友ppig的建议下,我们把cvs库old目录下的目录结构作了一番调整。这样,使整个结构更合理,但是,在开发环境的设置下需要作一定的设置。

  这里以eclipse2.1+easyStruts0.6.4+tomcat5.0为例说明一下比较关键的地方:

  1、把源文件目录和class文件的输出目录作相应的改变;

  2、把编译库的目录设置为改变后的目录;

  3、把/web目录设为tomcat的工程根目录;

  4、在easyStruts设置<basePackage>/web</basePackage>;

  我在这个过程中有一个疑问,当新建一个工程并把用wincvs检出的工程文件导入已经存在的工程,cvs路径能够使用,但用eclipse的sychronize with Repository,显示所有的本地文件均以更新。但是查看文件内容,又没有更新的地方。可能是cvs比较更新的条件我不懂吧。

  由于必须存在.easystrutsplugin,.project,.tomcatplugin,eclipse2.1才能以导入存在的工程的方式,只有这样,用eclipse的sychronize with Repository才不会把没有更新的文件显示为更新,所以,我又把这3个文件从删除状态中恢复过来。真搞不懂是为什么。

  另外,在tomcat设置页上,要设置:subdirctory to set as web application root(optional)=/web;

在easyStruts的设置页上,web context也必须是/web,即对应上面的这1句:<basePackage>/web</basePackage>;

否则,不管是启动或关闭eclipse等操作,就会报:unable to load modules的错误。

现在写日记不大方便,应该使这个主要的功能变方便

  例如:在菜单栏中加入写作日记的项目,用户写日记时可以直接在一个下拉列表中选择日记所属的目标;

  在目标的内容显示页和目标的日记列表上部均加入写日记的链接,用户在这个目标下提交了日记即表示加入了这个目标。

  另外,现在是提倡个性的时代,有必要实现BLOG的界面形式,但核心思想-以目标为导向,大家共享目标和实现目标的过程这一核心思想不能变,还应该进一步的发展和发挥这个思想。

改变CVS库的目录结构

  根据网友ppig的建议,改变了CVS库old目录下面现在的工程目录结构,改变后的结构更加合理和方便大家的使用。

  但是,如果在网页上直接查看目录结构还是显得太乱,因为由于cvs固有的特点,在客户端不能移走目录。但是,用cvs客户程序(如在eclipse2.1中)检下来的程序的目录中就不会包含那些空的无用的文件了。命令行的cvs要带一个"-P"参数就不会检出无用的空文件夹了。

(转载来自umlchina讨论组)业务对象模型(领域模型)的作用?

 UMLChina@yahoogroups.com

From: "Stephen Suen (SUNRUJUN)" <stephen.suen@gmail.com>  Add to Address Book  Add Mobile Alert 

Date: Mon, 5 Dec 2005 18:42:44 +0800

Subject: Re: 答复: 回复: [UMLChina] 业务对象模型(领域模型)的作用? 请教专家

    

业务建模的作用是为企业现有业务建立模型,需要的话,在此基础之上进行业务重组或者优化。业务模型将用作后续软件过程的输入。

 

实践中,通常我们会跳过业务建模的过程。当然,前提是我们认为业务建模是没有必要的。对于某些应用所面对的业务,其流程和涉及的实体可能是极其复杂的,软件工程人员无法轻易了解业务。此时,业务建模过程将有效地帮助软件工程人员理解业务(尤其是借助UML等图形工具的情况下),并使这些理解得到记录和整理。同样借助图形工具,比如时序图,状态图等,可以分析业务,需要的话,可以进行重组和优化。

 

对于业务建模,常见的两个问题是该做的时候没有作和不必要的时候却做了。

 

面对复杂业务,缺失业务建模过程使得软件工程人员根本不可能真正的理解业务,更加无法真正的理解用户需求,而是仅仅依赖用户的口述等获得大量似是而非的理解,最终导致大量的变更,甚至更严重的问题。如果进行业务建模,基于模型,你甚至会发现用户没有告诉过你的事物。更好的理解,意味着更好的沟通,进而更完善的需求。

 

另一个问题,是僵化的套用软件工程理论,在没有必要的情况下进行业务建模。对于一些简单业务,在全体人员可以轻易的理解业务的情况下,完全没有必要进行业务建模。有些组织为了诸如所谓"规范"等等理由而不是工程理由而要求这样的过程,反而会带来问题。因为业务建模和系统建模的过程具有传承关系,二者之间的一致性需要付出相当的代价。如果业务或者你的经验允许你直接进行系统建模,完全没有问题。当然,如果业务建模的文档可以卖出价钱的话,业务建模有相应的经济回报也未尝不可。

 

On 12/5/05, 赵鹏 <zhaopeng@webservice.com.cn> wrote:

是否可以认为"业务建模",就是"整合业务""优化流程"的过程?!

 

--------------------------------------------------------------------------------

发件人: UMLChina@yahoogroups.com [mailto: UMLChina@yahoogroups.com] 代表 孙向晖

发送时间: 2005年12月5日 14:19

收件人: UMLChina@yahoogroups.com

主题: 回复: [UMLChina] 业务对象模型(领域模型)的作用? 请教专家

 

首先,业务建模并不是开发过程中必需的。

其次,业务建模的作用还是很大的,而现实操作过程中,我们(开发商)往往会忽略业务建模。

业务建模其实分为两个部分来看。一个部分是对as-is建模。另一部分是对to-be建模。as-is,是对企业或者机构等业务建模范围的业务现状建模,以找出其业务过程中实际存在的问题。注意:很多问题,是IT所解决不了的。我们的售前经常跟客户说,只要你能想到的,我们就能做出来。这本身一个很大的问题。企业运营过程中的很多问题,IT都解决不了,或者靠IT来解决,既费工又费力,IT之外,还有更多的更优的方案。所以,在这个方面,IT人士可以做的就是,圈定哪些问题需要由IT来解决,而且必须靠IT来解决的有哪些。

第2个部分,也就是to-be建模。是对企业将来的建模。当我们对企业的业务运营问题给出一个比较好的解决方案后,企业会是一个什么样的运行状况呢?企业不知道,我们也不知道,最好的办法,就是对to-be进行建模。企业应该按照最新的业务模式进行哪方面的业务重组呢?企业是否能够接受这样的业务模式呢?毕竟,业务重组的过程中会牵扯到方方面面人的利益,重组的结果有可能会失败。IT人士也应该把此列入风险中。

 

业务建模的好处:圈定系统边界,理解业务核心,有效掌控风险。

在业务建模的过程中,出来的工具可以做为系统需求(用例)的输入。它们之间有很好的映射关系。但是,这跟是否使用requisitepro工具无关。你甚至可以简单的excel建立自己的跟踪矩阵。。

rockhai2005 < rockhai2005@yahoo.com.cn> 写道:

一个项目,采用ROSE的RUP模版建模。已经确定用到业务用例,进而用到业务对

象模型。现在有一些疑惑,不太明了:业务对象模型到底有什么作用?

我已经了解到的作用如下:

** 对执行业务功能的对象和这些对象之间的关系进行建模,即进一步(或同

时)解释业务用例。这样做的好处是在机构的层面上,更好地就未来系统完成的功

能与客户和项目组成员(相关项目干系人STAKE HOLDER)沟通;

那么它的其它作用呢?比如

1.它是否对分析模型有指导作用?就象业务用例指导系统用例一样?对应关系

如何?

2.如果1中的答案是肯定的,那么这种对应关系在ROSE中是否也可以靠

RequisitePro 工具来实现映射?

------------------------ Yahoo! Groups Sponsor --------------------~-->

Get Bzzzy! (real tools to help you find a job). Welcome to the Sweet Life.

http://us.click.yahoo.com/KIlPFB/vlQLAA/TtwFAA/saFolB/TM

--------------------------------------------------------------------~->

Yahoo! Groups Links

<*> To visit your group on the web, go to:

http://groups.yahoo.com/group/UMLChina/

<*> To unsubscribe from this group, send an email to:

UMLChina-unsubscribe@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:

http://docs.yahoo.com/info/terms/

ant building 报找不到com.sun.tools.javac.Main

今天,在eclipse2.1中用run ant运行ppig写的ant脚本编译学习日记文档时,发现通不过,报找不到com.sun.tools.javac.main;但不在eclipse2.1环境中在dos命令行窗口中执行能通过。最后,在windows->preferences->ant->Runtime->Classpath->Add Jars中,添加了jdk下面的\lib\tools.jar后,编译通过。原来com.sun.tools.javac.Main在这个tools.jar中。

(转帖)如何在Web工程中实现任务计划调度

转自:http://www.javaresearch.org/article/showarticle.jsp?column=2&thread=12337

 首页 » 研究文集 » J2EE综合   搜索标题相关文章      发表评论     开始监控     加入收藏夹 

如何在Web工程中实现任务计划调度

nbDeveloper 原创  (参与分:4690,专家分:120)   发表:2004-02-23 22:53   更新:2004-02-26 08:19   版本:1.0   阅读:4263次 

 

    好多朋友用过Windows的任务计划,也有不少程序迷自己曾写过时钟报警、系统自动关机等趣味程序,可却很少有朋友在Web工程中实现过类似功能。今天有空把笔者先前曾在Tomcat上实现的类似功能,搬出来与大家共享。

    早在几年前,我公司跟某市财政局合作项目开发,为加强财政局对所属单位财务状况的有效监管,开发、实施了财政局数据中心项目。此项目采用B/S加C/S混合结构模式。财政局Web服务器上架设数据同步接收装置,由市属单位每天下班前把财务信息通过HTTP协议上传至财政局中心服务器,与Web服务器上的接收装置对接。财政局内部各部门需要查阅大量财务信息,获取完备的市属单位当前财务状况信息,各部门按职能划分,需要准确的获取各部门各自所关注的汇总信息,以财政报表的形式提供。

    因财政数据量大,实时计算财政报表速度较慢,当初就考虑用报表缓存来减轻服务器的负担,但用缓存需要一个合理的缓存更新机制。考虑到各市属单位每天下班前才把财务数据上传,财政局每天所查看到的财务信息其实并不包括当天(除非有某位领导等到所属单位全部上传完之后才来查看信息,应该已经下班了),所以要是能实现任务计划调度,在每晚深夜把当天及历史财务信息汇总,更新缓存,速度瓶颈不就解决了吗。

    当时由于系统核心是基于Web部署的,报表计算引擎也相应的部署在Tomcat容器上,因此如果想要借用Windows的任务计划来实现定时计算,就需要额外编写普通桌面应用程序接口,稍显复杂。于是就琢磨着想在Web上实现,经过查阅较多相关资料,发现Java定时器(java.util.Timer)有定时触发计划任务的功能,通过配置定时器的间隔时间,在某一间隔时间段之后会自动有规律的调用预先所安排的计划任务(java.util.TimerTask)。另外,由于我们希望当Web工程启动时,定时器能自动开始计时,在整个Web工程的生命期里,定时器能在每晚深夜触发一次报表计算引擎。因此定时器的存放位置也值得考查,不能简单的存在于单个Servlet或JavaBean中,必须能让定时器宿主的存活期为整个Web工程生命期,在工程启动时能自动加载运行。结合这两点,跟Servlet上下文有关的侦听器就最合适不过了,通过在工程的配置文件中加以合理配置,会在工程启动时自动运行,并在整个工程生命期中处于监听状态。

    下面就Servlet侦听器结合Java定时器来讲述整个实现过程。要运用Servlet侦听器需要实现javax.servlet.ServletContextListener接口,同时实现它的contextInitialized(ServletContextEvent event)和contextDestroyed(ServletContextEvent event)两个接口函数。考虑定时器有个建立和销毁的过程,看了前面两个接口函数,就不容置疑的把建立的过程置入contextInitialized,把销毁的过程置入contextDestroyed了。

    我把ServletContextListener的实现类取名为ContextListener,在其内添加一个定时器,示例代码如下所示(为考虑篇幅,仅提供部分代码供读者参考):

    private java.util.Timer timer = null;

    public void contextInitialized(ServletContextEvent event) {

        timer = new java.util.Timer(true);

        event.getServletContext().log("定时器已启动");        

         timer.schedule(new MyTask(event.getServletContext()), 0, 60*60*1000);

        event.getServletContext().log("已经添加任务调度表");

    }

    public void contextDestroyed(ServletContextEvent event) {

        timer.cancel();

        event.getServletContext().log("定时器销毁");

    }

    以上代码中, timer.schedule(new MyTask(event.getServletContext()), 0, 60*60*1000)这一行为定时器调度语句,其中MyTask是自定义需要被调度的执行任务(在我的财政数据中心项目中就是报表计算引擎入口),从java.util.TimerTask继承,下面会重点讲述,第三个参数表示每小时(即60*60*1000毫秒)被触发一次,中间参数0表示无延迟。其它代码相当简单,不再详细说明。

   下面介绍MyTask的实现,上面的代码中看到了在构造MyTask时,传入了javax.servlet.ServletContext类型参数,是为记录Servlet日志方便而传入,因此需要重载MyTask的构造函数(其父类java.util.TimerTask原构造函数是没有参数的)。在timer.schedule()的调度中,设置了每小时调度一次,因此如果想实现调度任务每24小时被执行一次,还需要判断一下时钟点,以常量C_SCHEDULE_HOUR表示(晚上12点,也即0点)。同时为防止24小时执行下来,任务还未执行完(当然,一般任务是没有这么长的),避免第二次又被调度以引起执行冲突,设置了当前是否正在执行的状态标志isRunning。示例代码如下所示:

    private static final int C_SCHEDULE_HOUR   = 0;

    private static boolean isRunning = false;

         private ServletContext context = null;

    public MyTask(ServletContext context) {

        this.context = context;

    }

    public void run() {

        Calendar cal = Calendar.getInstance();        

        if (!isRunning)  {           

            if (C_SCHEDULE_HOUR == cal.get(Calendar.HOUR_OF_DAY)) {            

                    isRunning = true;                

                context.log("开始执行指定任务");

                

                //TODO 添加自定义的详细任务,以下只是示例

                int i = 0;

                while (i++ < 10) {

                    context.log("已完成任务的" + i + "/" + 10);

                }

                isRunning = false;

                context.log("指定任务执行结束");               

            }            

        } else {

            context.log("上一次任务执行还未结束");

        }

    }

    上面代码中“//TODO……”之下四行是真正被调度执行的演示代码(在我的财政数据中心项目中就是报表计算过程),您可以换成自己希望执行的语句。

到这儿,ServletContextListener和MyTask的代码都已完整了。最后一步就是把ServletContextListener部署到您的Web工程中去,在您工程的web.xml配置文件中加入如下三行:

    <listener>

        <listener-class>com.test.ContextListener</listener-class>

    </listener>

    当然,上面的com.test得换成您自己的包名了。保存web.xml文件后,把工程打包部署到Tomcat中即可。任务会在每晚12点至凌晨1点之间被执行,上面的代码会在Tomcat的日志文件中记录如下:

2003-12-05 0:21:39 开始执行指定任务

2003-12-05 0:21:39 已完成任务的1/10

    ……

2003-12-05 0:21:39 已完成任务的10/10

2003-12-05 0:21:39 指定任务执行结束

    以上代码在Tomcat 4.1.29以及Tomcat 5.0.16上调试通过。如果您需要完整代码,请通过nbDeveloper@hotmail.com与我联系。

 

 

 

(转帖)servlet 相关的Listener应用(内含web程序的定时器)

转自:http://www.mscenter.edu.cn/blog/wangpeng/archive/2005/05/07/2268.aspx

servlet 相关的Listener应用

ZhangLiHai.Com Blog

servlet 相关的Listener应用

 

张利海 于 2004年11月22日 23:27 发表 

关键词 : servlet listener timer 定时器

从作用域范围来说,Servlet的作用域有ServletContext,HttpSession,ServletRequest.

Context范围:

   

ServletContextListener:

对一个应用进行全局监听.随应用启动而启动,随应用消失而消失主要有两个方法:

contextDestroyed(ServletContextEvent event)

 在应用关闭的时候调用

contextInitialized(ServletContextEvent event)

在应用启动的时候调用

这个监听器主要用于一些随着应用启动而要完成的工作,也就是很多人说的我想在容器

启动的时候干..........

一般来说对"全局变量"初始化,如

public void contextInitialized(ServletContextEvent event){

    ServletContex sc = event.getServletContext();

    sc.setAttribute(name,value);

}

以后你就可以在任何servlet中getServletContext().getAttribute(name);

我最喜欢用它来做守护性工作,就是在contextInitialized(ServletContextEvent event)

方法中实现一个Timer,然后就让应用在每次启动的时候让这个Timer工作:

public void contextInitialized(ServletContextEvent event){

    timer = new Timer();

    timer.schedule(new TimerTask(){

        public void run(){

            //do any things

        }

    },0,时间间隔);

}

    有人说Timer只能规定从现在开始的多长时间后,每隔多久做一次事或在什么时间做

一次事,那我想在每月1号或每天12点做一项工作如何做呢?

你只要设一个间隔,然后每次判断一下当时是不是那个时间段就行了啊,比如每月一号做,那你

时间间隔设为天,即24小时一个循环,然后在run方法中判断当时日期new Date().getDate()==1

就行了啊.如果是每天的12点,那你时间间隔设为小时,然后在run中判断new Date().getHour()

==12,再做某事就行了.

ServletContextAttributeListener:

这个监听器主要监听ServletContex对象在setAttribute()和removeAttribute()的事件,注意

也就是一个"全局变量"在被Add(第一次set),replace(对已有的变量重新赋值)和remove的时候.

分别调用下面三个方法:

public void attributeAdded(ServletContextAttributeEvent scab)这个方法不仅可以知道

哪些全局变量被加进来,而且可获取容器在启动时自动设置了哪些context变量:

public void attributeAdded(ServletContextAttributeEvent scab){

    System.out.println(scab.getName());

}

  public void attributeRemoved(ServletContextAttributeEvent scab)

  public void attributeReplaced(ServletContextAttributeEvent scab)

 

 

Session范围:

HttpSessionListener:

这个监听器主要监听一个Session对象被生成和销毁时发生的事件.对应有两个方法:

  public void sessionCreated(HttpSessionEvent se)

  public void sessionDestroyed(HttpSessionEvent se)

  一般来说,一个session对象被create时,可以说明有一个新客端进入.可以用来粗略统计在线人

数,注意这不是精确的,因为这个客户端可能立即就关闭了,但sessionDestroyed方法却会按一定

的策略很久以后才会发生.

HttpSessionAttributeListener:

和ServletContextAttributeListener一样,它监听一个session对象的Attribut被Add(一个特定

名称的Attribute每一次被设置),replace(已有名称的Attribute的值被重设)和remove时的事件.

对就的有三个方法.

  public void attributeAdded(HttpSessionBindingEvent se)

  public void attributeRemoved(HttpSessionBindingEvent se)

  public void attributeReplaced(HttpSessionBindingEvent se)

  上面的几个监听器的方法,都是在监听应用逻辑中servlet逻辑中发生了什么事,一般的来说.

我们只要完成逻辑功能,比如session.setAttribute("aaa","111");我只要把一个名为aaa的变量

放在session中以便以后我能获取它,我并不关心当session.setAttribute("aaa","111");发生时

我还要干什么.(当然有些时候要利用的),但对于下面这个监听器,你应该好好发解一下:

HttpSessionBindingListener:

上面的监听器都是作为一个独立的Listener在容器中控制事件的.而HttpSessionBindingListener

对在一对象中监听该对象的状态,实现了该接口的对象如果被作为value被add到一个session中或从

session中remove,它就会知道自己已经作为一个session对象或已经从session删除,这对于一些非

纯JAVA对象,生命周期长于session的对象,以及其它需要释放资源或改变状态的对象非常重要.

比如:

session.setAttribute("abcd","1111");

以后session.removeAttribute("abcd");因为abcd是一个字符中,你从session中remove后,它就会

自动被垃圾回收器回收,而如果是一个connection:(只是举例,你千万不要加connection往session

中加入)

session.setAttribute("abcd",conn);

以后session.removeAttribute("abcd");这时这个conn被从session中remove了,你已经无法获取它

的句柄,所以你根本没法关闭它.而在没有remove之前你根本不知道什么时候要被remove,你又无法

close(),那么这个connection对象就死了.另外还有一些对象可以在被加入一个session时要锁定

还要被remove时要解锁,应因你在程序中无法判断什么时候被remove(),add还好操作,我可以先加锁

再add,但remove就后你就找不到它的句柄了,根本没法解锁,所以这些操作只能在对象自身中实现.

也就是在对象被add时或remove时通知对象自己回调相应的方法:

MyConn extends Connection implements HttpSessionBindingListener{

  public void valueBound(HttpSessionBindingEvent se){

    this.initXXX();

  }

  public void valueUnbound(HttpSessionBindingEvent se){

    this.close();

  }

}

session.setAttribute("aaa",new MyConn());

这时如果调用session.removeAttribute("aaa"),则触发valueUnbound方法,就会自动关闭自己.

而其它的需要改变状态的对象了是一样.

另外还有一个HttpSessionActivationListener监听器是实现分布式应用中session同步的.不作

多介绍,如果有要实现该功能的朋友可以和我联系.

在servlet2.4中,对于request范围已经实现对应的监听器:

ServletRequestListener,ServletRequestAttributeListener

但没有找到好的容器的支持所以没有做过多的测试.虽然从API可以掌握99%,但没有经过真正的

测试我是不会仅把API抄出来的.以后我会补齐这方面的内容

原作者:Axman

 

 

(转帖)一个实现MD5的简洁的java类

来自:http://www.javaresearch.org/article/showarticle.jsp?column=33&thread=10461

×××××××××××××××××××××××××××××××××××××××××××××××××××××

                         正文

一个实现MD5的简洁的java类

Jagie 原创  (参与分:100322,专家分:3090)   发表:2003-11-18 17:14   更新:2003-11-19 08:34   版本:1.0   阅读:6307次 

 

关键词:md5

由于消息摘要唯一性和不可逆性的特点,所以不失为一种简单的常用的加密手段,比如你可以用md5来加密你的应用中的用户口令。

package test;

import java.security.MessageDigest;

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2003</p>

 * <p>Company: </p>

 * @author unascribed

 * @version 1.0

 */

public class StringUtil {

  private final static String[] hexDigits = {

      "0", "1", "2", "3", "4", "5", "6", "7",

      "8", "9", "a", "b", "c", "d", "e", "f"};

  /**

   * 转换字节数组为16进制字串

   * @param b 字节数组

   * @return 16进制字串

   */

  public static String byteArrayToHexString(byte[] b) {

    StringBuffer resultSb = new StringBuffer();

    for (int i = 0; i < b.length; i++) {

      resultSb.append(byteToHexString(b[i]));

    }

    return resultSb.toString();

  }

  private static String byteToHexString(byte b) {

    int n = b;

    if (n < 0)

      n = 256 + n;

    int d1 = n / 16;

    int d2 = n % 16;

    return hexDigits[d1] + hexDigits[d2];

  }

  public static String MD5Encode(String origin) {

    String resultString = null;

    try {

      resultString=new String(origin);

      MessageDigest md = MessageDigest.getInstance("MD5");

      resultString=byteArrayToHexString(md.digest(resultString.getBytes()));

    }

    catch (Exception ex) {

    }

    return resultString;

  }

  public static void main(String[] args){

    System.err.println(MD5Encode("a"));

  }

}

在RFC 1321中,给出了Test suite用来检验你的实现是否正确:

MD5 ("") = d41d8cd98f00b204e9800998ecf8427e

MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661

MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72

MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0

MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b

参考资料:《java security handbook》 jamie jaworski

版权声明   给作者写信  本篇文章对您是否有帮助?  投票: 是    否     投票结果:     24       1

 

 

 

作者其它文章:

在MIDP2.0中操作图片像素

用MMAPI拍照

如何在Swing中实现文件路径选择的TableCellEditor

MIDP中一个简单的折行文本绘制办法

在MIDP1.0下实现图片翻转

作者全部文章 

 

 

  评论人:yipsilon    参与分: 15609    专家分: 290    来自: Dalian

 发表时间: 2003-11-20 19:29 

使用这种方式的前提是必需有JCE支持。如果在J2SDK 1.3中,则必需下载额外的jce包。 

 

  评论人:Jagie    参与分: 100322    专家分: 3090    来自: 北京

 发表时间: 2003-11-21 11:11 

java.security.MessageDigest是jdk自带的,无需使用javax.crypto包,所以无需下载jce.

至少我在运行这个例子的时候就没有下载jce

 

 

  评论人:rower    参与分: 167    专家分: 0  发表时间: 2004-04-10 17:10 

实际测试,在J2SDK 1.3中无需下载额外的jce包,运行良好。 

 

  评论人:huangyafei    参与分: 80    专家分: 0  发表时间: 2005-03-06 13:41 

怎么我在运行上面的程序的时候出错了:出错信息为:

D:\works\java\MD5Encode.java:12: class StringUtil is public, should be declared in a file named StringUtil.java

public class StringUtil {

       ^

1 error

 

 

  评论人:yifenggege    参与分: 259    专家分: 70  发表时间: 2005-07-13 14:12 

好! 

 

  评论人:keli    参与分: 34262    专家分: 1320  发表时间: 2005-11-16 17:24 

加密是可以的,但是解密就难了。呵呵。

我看第5个答复想笑,哈哈哈哈。 

 

  评论人:gui_jq    参与分: 73813    专家分: 1070    来自: 广州天河

 发表时间: 2005-12-01 18:28 

写得不错,我最近要写个radius协议分析的工具想用java来编写,所以第一得弄java下面的MD5实现,没有想到如此简单,jdk原来就带有了,最坏的打算我还想用c的代码改一个呢。呵呵。在这里我补充一下:

1,MD5本来就是不可逆的,加密只是保证在网络传输中内容不被修改,可以通过md5来检查,防止有人修改包内容进行模仿发包,所以服务端在受到包写更加对方的算法来md5一次然后在处理包内容,如果不通过则直接丢弃包。另外就是用来验证下载的重要文件是否正确和完整。

2,程序中的打印16进制方法有点欠妥,在c里面可以通过printf("%02x",buf[])就可以,但是java对byte的处理没有这个。所以我推荐下面的方法:

private static String dumpBytes(byte[] bytes) {

    int i;

    StringBuffer sb = new StringBuffer();

    for (i = 0; i < bytes.length; i++) {

      if (i % 32 == 0 && i != 0) {

        sb.append("\n");

      }

      String s = Integer.toHexString(bytes[i]);

      if (s.length() < 2) {

        s = "0" + s;

      }

      if (s.length() > 2) {

        s = s.substring(s.length() - 2);

      }

      sb.append(s);

    }

    return sb.toString();

  }

这个更加灵活高效。

补充结束。谢谢大家。呵呵。