funinhand

funinhand
随笔 - 9, 文章 - 0, 评论 - 0, 引用 - 0
数据加载中……

2009年7月1日

漫谈Java加密技术(一)

     摘要: 关键字: java 加密基础, base64, md5, mac, sha, 单向加密     加密解密,曾经是我一个毕业设计的重要组件。在工作了多年以后回想当时那个加密、解密算法,实在是太单纯了。     言归正传,这里我们主要描述Java已经实现的一些加密解密算法,最后介绍数字证书。     如...  阅读全文

posted @ 2009-07-01 20:53 funinhand| 编辑 收藏

2009年6月27日

Apache HTTPServer与JBoss或是Tomcat的整合与请求分发

如果需要一台服务器来做转发请求的话,用 apache的HttpServer再好不过了。

假如一个客户请求服务器A,A并不直接处理客户端的请求,而是把请求转发到
服务器B。

来看一个具体怎么操作吧。

首先先下载一个apache-httpserver,这里用的是apache_2.2.3-win32-x86-no_ssl.msi,你可以在此
http://apache.mirror.phpchina.com/httpd/  http://www.bt285.cn  进行下载。或此看此文最后的附件也可。

安装就不用说了吧,安装完毕后。有时候启动服务会失败,我的第一次就失败了。端口被占用。
这时我们:

首先用netstat -ano 看是得到占用80端口的进程的PID,然后打开任务管理器,选择->查看->选择列,勾上PID(进程标识符),结束这个进程,再启动Apache就成功了.
可以在浏览器输入:http://localhost 出现 'it works' 说明就ok了.

服务启动成功后去下载:mod_jk-apache-2.2.3.so,本文附件中会提供。


1.进入apache的安装目录。找到modules把下载好的mod_jk-apache-2.2.3.so复制进去。
2.在conf目录建立一个workers.properties文件,内容如下:

# Define 1 real worker using ajp13
worker.list
=admin
#
Set properties for admin (ajp13)
worker.admin.type
=ajp13
worker.admin.host
=127.0.0.1
worker.admin.port
=8009
worker.admin.lbfactor
=50
#worker.admin.cachesize
=10
# worker.admin.cache_timeout
=600
worker.admin.socket_keepalive
=1
# worker.admin.recycle_timeout
=300


其中host就是你要转发到的服务器IP,port是端口号。这里是用本机测试,所以只改端口号就行了。

3.打开conf目录下的httpd.conf文件,找到#LoadModule ssl_module modules/mod_ssl.so http://www.5a520.cn 这一行。在
这一行下面加上:

# 加载 mod_jk 模块
LoadModule jk_module modules
/mod_jk-apache-2.2.3.so

# 指定 mod_jk 模块所需的配置文件 workers.properties 的位置
JkWorkersFile conf
/workers.properties

# 指定 mod_jk 模块的日志文件位置
JkLogFile logs
/mod_jk.log

# 指定 mod_jk 模块的日志级别
JkLogLevel info

# 指定 mod_jk 模块的日志格式
JkLogStampFormat "
[%a %b %d %H:%M:%S %Y]

# 发送所有请求上下文的请求给 admin
JkMount
/* admin

最后一个的admin就是第二步中的worker.list

<Service name="jboss.web">

????

??
????
<Connector port="8080" address="${jboss.bind.address}"????
????????? maxThreads
="250" maxHttpHeaderSize="8192"
????????? emptySessionPath
="true" protocol="HTTP/1.1"
????????? enableLookups
="false" redirectPort="8443" acceptCount="100"
????????? connectionTimeout
="20000" disableUploadTimeout="true" />??

????

????


????

????
<Connector port="8009" address="${jboss.bind.address}" protocol="AJP/1.3"
????????? emptySessionPath
="true" enableLookups="false" redirectPort="8443" />

??????
<Engine name="jboss.web" defaultHost="localhost" >

?????????

tomcat:
tomcat/conf/server.xml:


????
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />


其中关于AJP的配置是一样的,这里可以更改你需要的端口,当然上面的apache也需要同时更改。

最后打浏览器测试一下吧:
http://localhost

显示的其实就是http://127.0.0.1:8009 ,如果你JBoss/Tomat下部署有测试工程。看一下吧。已经出现了。

好的,操作成功了。说明已经转发成功。

相关附件下载



好了apache的配置都搞定了,重启一下ok.

我们再来看一下jboss的配置:

找到:
jboss-4.2.3.GA\server\default\deploy\jboss-web.deployer\server.xml

看看最上面的一段配置就行了:

posted @ 2009-06-27 20:16 funinhand| 编辑 收藏

2009年6月25日

xtable的介绍及需要改进的地方

xtable是由陈仁飞(http://www.bt285.cn )独自开发的jsp页面组件,目前提供分页、排序、无限层分组以及汇总功能,以及包括导出excel/pdf/xml等,xtable不同于displaytag,extrameTable的地方在于xtable自定义了一套宏插件模式,只要实现接口,你可以随意扩展xtable的功能。

xtable最大的优点在于简单易用,分组汇总就是很简单的几句话,而且能够支持无限层分组汇总。

页面代码:

 

看预览效果:

 

但xtable目前也暴露了一些缺陷,因第一版在项目过程中只有很短的时间实现,很多方面考虑欠妥,宏没有支持嵌套,此问题一直延续到现在,发现已经难以适应更强大的需求了,本期改进计划:

1、代码进行重构、标签的使用要更加简洁,去除一些无用的属性,增加一些智能判断(如displayProperties简单模式就无需定义)

2、xtable实现宏嵌套,增加默认个人扩展机制,宏嵌套的实现将有助于提升整个xtable的可扩展性,提升到一个表格的平台。

3、简单模式xtable支持grid模式:头固定,列可以拖动

4、最大的改进就是增加交叉报表功能,这个目标的实现将能够把xtable推到介于一般标签和专业报表工具之间的角色,稍微复杂的查询统计无需用报表工具(因为一般的业务系统复杂的报表就几个,用专业的工具费时费钱费力)

 

如xtable_code.gif中的@groupSum().  http://www.5a520.cn 这个就是自己扩展的宏,原项目并不存在分组汇总功能,后期自己实现宏接口实现了分组汇总等功能。

posted @ 2009-06-25 21:46 funinhand| 编辑 收藏

2009年6月24日

利用校内API开发程序

     摘要: 目前在51,校内,facebook开发小应用越来越热,这里我仅以xiaonei.com提供的APP Java API为例,探讨他的实现方法,简单来说就是分为2步: 申请个应用,得到应用的API Key和Secret两个数值 利用这两个数值,我们就可以使用xiaonei的Java API,以下代码用来实现获取你的个人信息和你的好友信息代码(由于邀请API已过期,所以不能使用)...  阅读全文

posted @ 2009-06-24 22:44 funinhand| 编辑 收藏

2009年6月23日

用java抓取百度Top500歌曲及源码下载

     摘要: 在我整理完在线听歌(http://www.5a520.cn )的模块后,剩下来的工作就是如何通过程序抓取最新的Baidu好听的歌曲,抓取的工作主要包括3个属性:歌名、歌曲在线播放地址和歌词内容(符合LRC歌词格式),目前完成歌曲和歌曲地址抓取,由于百度的歌曲地址很多通过js获取,所以歌曲地址获取我这里使用搜狗音乐搜索方便些,所有的源码如下: /** *//** http://www....  阅读全文

posted @ 2009-06-23 20:45 funinhand| 编辑 收藏

2009年6月22日

用JAVA实现缓冲多线程无阻塞读取远程文件

     摘要:     我平时比较喜欢从网上听歌,有些链接下载速度太慢了。如果用HttpURLConnection类的方法打开连接,然后用InputStream类获得输入流,再用BufferedInputStream构造出带缓冲区的输入流,如果网速太慢的话,无论缓冲区设置多大,听起来都是断断续续的,达不到真正缓冲的目的。于是尝试编写代码实现用缓冲方式读取远程文件,以下贴出的代码是我写...  阅读全文

posted @ 2009-06-22 22:25 funinhand| 编辑 收藏

2009年6月20日

java获得当前系统内存及硬盘使用情况的代码

java获得当前系统内存情况的代码如下: 
/**
 
http://www.bt285.cn http://www.5a520.cn
*/

import java.lang.management.ManagementFactory;   
import com.sun.management.OperatingSystemMXBean;   
public class OSTest {   
    
public static void main(String[] args)    
    
{   
        OperatingSystemMXBean osmb 
= (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();   
        System.out.println(
"系统物理内存总计:" + osmb.getTotalPhysicalMemorySize() / 1024/1024 + "MB");   
        System.out.println(
"系统物理可用内存总计:" + osmb.getFreePhysicalMemorySize() / 1024/1024 + "MB");    }
   
}
  


ManagementFactory.getOperatingSystemMXBean()返回的是java.lang.management里面的OperatingSystemMXBean ;
我们要用的是com.sun.management.OperatingSystemMXBean;
在java类库中可以查到:
public abstract Interface com.sun.management.OperatingSystemMXBean extends java.lang.management.OperatingSystemMXBean
所以我们可以强制转换一下。

硬盘使用:

 

 

/**
http://www.bt285.cn http://www.5a520.cn
*/

import java.io.File;   
/**  
 *   
 * jdk6.0下的磁盘使用情况例子  
 
*/
  
public class Diskfree {   
    
public static void main(String[] args) {   
        File[] roots 
= File.listRoots();//获取磁盘分区列表   
        for (File file : roots) {   
            System.out.println(file.getPath()
+"信息如下:");   
            System.out.println(
"空闲未使用 = " + file.getFreeSpace()/1024/1024/1024+"G");//空闲空间   
            System.out.println("已经使用 = " + file.getUsableSpace()/1024/1024/1024+"G");//可用空间   
            System.out.println("总容量 = " + file.getTotalSpace()/1024/1024/1024+"G");//总空间   
            System.out.println();   
        }
   
    }
   
}
  

posted @ 2009-06-20 16:32 funinhand| 编辑 收藏

2009年6月19日

抽象类设计之我见

最近在做类设计时,正好有一个关于抽象类的定义,我顺便把定义抽象类的两种机制总结了一下,供大家参考。

在java中大家都知道对抽象类定义进行支持的两种机制(abstract和interface),因为这两种机制的存在,才赋予了java强大的面向对象的能力。abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于abstract class和interface的选择显得比较随意。

其实,两者之间还是有很大的区别,对于它们的选择甚至反映出对于问题领域本质的理解、对于设计意图的理解是否正确及合理性。通过本文希望能够加深大家对二者之间的理解。

 

什么是抽象类?

在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样。并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。

比如:如果我们进行一个图形编辑软件的开发,就会发现问题领域存在着圆、三角形这样一些具体概念,它们是不同的,但是它们又都属于形状这样一个概念,形状这个概念在问题领域是不存在的,它就是一个抽象概念。正是因为抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。

在面向对象领域,抽象类主要用来进行类型隐藏。我们可以构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。熟悉OCP的读者一定知道,为了能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle),抽象类是其中的关键所在。

实现抽象类的机制 ?

  1. 抽象类

public abstract class BaseCache {

}

 

  1. 接口

public interface class BaseCache {

}

 

二者之间区别


抽象机制

差异化

抽象类

  1. 通过abstract定义抽象类。
  2. 可以定义自己数据成员。
  3. 可以定义非abstarct的成员方法。
  4. 只能继承一个基类。

接口

  1. 通过interface定义接口。
  2. 只能够定义静态的不能被修改的数据成员(也就是必须是static final的)。
  3. 不能定义非abstarct的成员方法。
  4. 可以实现多个接口。

 

下面我们通过实际的例子来分析两种机制的差异化:

业务场景:定义一个缓存基类,有多个缓存实例的实现。

abstract 类的方式定义:

/**

http://www.bt285.cn  http://www.5a520.cn 

 */

Public abstract class BaseCache{

    public abstract void init();

    public abstract void clean();

}

Interface方式定义:

Public interface class BaseCache {

    public void init();

    public void clean();

}

我们其他的一些缓存实例类型通过继承abstract 类 BaseCache 和实现接口 BaseCache 方式来定义实例类型类,都可以满足业务场景需求,两者之间也没有什么差别,下面我们从细节点来分析,如果部分cache实例类型需要增加监控,判断当前缓存实例的容量是否超过系统的伐值。那么我们原来设计基础上增加一个monitor() 方法就可以实现了。

请看例子:

Public abstract class BaseCache{

    public abstract void init();

    public abstract void clean();

    public abstract Map<String,String> monitor();

}

我们一起来分析一下这种方法缺点,它违反了面向对象设计中的一个核心原则ISP(Interface Segregation Priciple)在cache固有的行为和方式和监控混淆在一起了。因monitor()方法的存在会影响到cache类型的设计概念。如果我们根据ISP的原则,把不同概念的类型定义为两个抽象类,按照abstract 类的方式肯定是不行的,因为在java里面是不支持多继承的,显然没办法满足业务场景。如果是接口的方式呢?

请看例子:

Public interface class BaseCache {

    public void init();

    public void clean();

public Map<String,String> monitor();

}

这种做法分析,就很难清楚的区分设计意图,把概念混淆在一起,显然是没有理清业务意图。我们需求上真正业务意图是Cache具备init 和clean两种行为,部分cache实例需要具备监控的行为。

我现在的做法是一个abstract 和interface:

Public abstract class BaseCache{

    public abstract void init();

    public void clean();

}

Public interface class ICacheMonitor {

public Map<String,String> monitor();

}

 

public class PermissionCache extends BaseCache implements ICacheMonitor{

}

 

在BaseCache 类中Clean()方法定义为非abstract ,由基类提供默认实现,提升类的复用价值,如果部分cache实例需要进行监控的就实现ICacheMonitor 接口。

posted @ 2009-06-19 22:01 funinhand| 编辑 收藏

2009年6月18日

腾讯算法面试题算法与代码

题目是这样的:给你10分钟时间,根据上排给出十个数,在其下排填出对应的十个数
要求下排每个数都是先前上排对应那个数在下排十个数中出现的次数。
上排的十个数如下:
【0,1,2,3,4,5,6,7,8,9】

/**
http://www.bt285.cn http://www.5a520.cn
*/

public class Test   
{   
  
public static void main(String[] args)   
  
{   
    NumberTB nTB 
= new NumberTB(10);   
       
    
int[] result = nTB.getBottom();   
    
for(int i=0;i<result.length;i++)   
    
{   
      System.out.print(result[i] 
+ " ");   
    }
   
  }
   
}
   
  
class NumberTB   
{   
  
private int[] top;   
  
private int[] bottom;   
  
private int len;   
  
private boolean success;   
     
  
//please into len >= 4   
  public NumberTB(int len)   
  
{   
    
this.len = len <= 4 ? 4 : len;   
    
this.success = false;   
       
    
this.top = new int[this.len];   
    
this.bottom = new int[this.len];   
       
    
//format top   
    for(int i=0;i<this.len;i++)   
    
{   
      
this.top[i] = i;   
    }
   
  }
   
     
  
public int[] getBottom()   
  
{   
    
int i = 0;   
       
    
while(!this.success)   
    
{   
      i
++;   
      setNextBottom();   
    }
   
       
    System.out.println(
"执行了: " + i + "次循环得到结果");   
       
    
return this.bottom;   
  }
   
     
  
//set next bottom   
  private void setNextBottom()   
  
{   
    
boolean reB = true;   
       
    
for(int i=0;i<this.len;i++)   
    
{   
      
int frequecy = getFrequecy(i);   
         
      
if(this.bottom[i] != frequecy)   
      
{   
        
this.bottom[i] = frequecy;   
        reB 
= false;   
      }
   
    }
   
       
    
this.success = reB;   
  }
   
     
  
//get frequency in bottom   
  private int getFrequecy(int num)   
  
{   
    
int count = 0;   
       
    
for(int i=0;i<this.len;i++)   
    
{   
      
if(this.bottom[i] == num)   
        count
++;   
    }
   
       
    
return count;   
  }
   
}
  


 

下面给出一个更具一般性的结论:

这个是有规律可循的,不仅0~9有唯一解,0~n都只有唯一解。关键是最后面一个1它可以左右移动,1和2下面的数永远是2和1,0下面对应的数为n-3(n>=3),上排数n-3下面对应的数为1,其它上排数下面对应为0就ok了。有了这个一般性的结论再大的数都可以马上给出答案。
比如 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    12 2 1 0 0 0 0 0 0 0 0 0 1 0 0 0

请大家验证,这个算法可以用到数据压缩领域。

posted @ 2009-06-18 21:13 funinhand| 编辑 收藏