blogjava-凯发k8网页登录

blogjava-凯发k8网页登录http://www.blogjava.net/usherlight/category/8573.html天平山上白云泉,云自无心水自闲。何必奔冲山下去,更添波浪向人间!zh-cnthu, 08 sep 2016 09:04:14 gmtthu, 08 sep 2016 09:04:14 gmt60selenium 下载文件http://www.blogjava.net/usherlight/archive/2016/01/28/429241.html云自无心水自闲云自无心水自闲thu, 28 jan 2016 10:06:00 gmthttp://www.blogjava.net/usherlight/archive/2016/01/28/429241.htmlhttp://www.blogjava.net/usherlight/comments/429241.htmlhttp://www.blogjava.net/usherlight/archive/2016/01/28/429241.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/429241.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/429241.html
我在网上搜索了一下如何使用selenium下载文件,其中确实有几篇文件介绍了实现的方法。
但是其主要思想都是使用httpclient或者url获得inputstream, 然后保存到文件中。
但是,其中的问题是用户登录的session不能维持。

我发现了一个简单的方法。
直接使用webdriver.get, 示例如下:

webdriver.get("https://website.com/login");
webelement element = driver.findelement( by.id( "userid" ) );
element.sendkeys( "user01" );

element = driver.findelement( by.id( "passwd" ) );
element.sendkeys( "password" );

element = driver.findelement( by.name( "login" ) );
element.submit();

webdriver.get("https://website.cm/download.do?start=xx&end=yy");
string source = webdriver.getpagesource();

这个source就是我们想保存的要下载的内容。
只要把这个string写到一个文件中,就实现了文件下载的目的

云自无心水自闲 2016-01-28 18:06
]]>
openpgp 验证签名http://www.blogjava.net/usherlight/archive/2015/12/11/428624.html云自无心水自闲云自无心水自闲fri, 11 dec 2015 13:40:00 gmthttp://www.blogjava.net/usherlight/archive/2015/12/11/428624.htmlhttp://www.blogjava.net/usherlight/comments/428624.htmlhttp://www.blogjava.net/usherlight/archive/2015/12/11/428624.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/428624.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/428624.html加密解密的基本操作流程是,用户使用公钥对明文进行加密,解密方使用私钥对密文进行解密。

在实际应用中,除了加密保证文本内容不泄露外,同时还要考虑能够验证密文发送方的身份,比较普遍使用的方法就是签名。
本文主要对具体的方法进行介绍并附上源代码。  

云自无心水自闲 2015-12-11 21:40
]]>
简单介绍如何使用powermock和mockito来mock 1. 构造函数 2. 静态函数 3. 枚举实现的单例 4. 选择参数值做为函数的返回值http://www.blogjava.net/usherlight/archive/2015/06/16/425740.html云自无心水自闲云自无心水自闲tue, 16 jun 2015 13:27:00 gmthttp://www.blogjava.net/usherlight/archive/2015/06/16/425740.htmlhttp://www.blogjava.net/usherlight/comments/425740.htmlhttp://www.blogjava.net/usherlight/archive/2015/06/16/425740.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/425740.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/425740.html 1. 构造函数
2. 静态函数
3. 枚举实现的单例
4. 选择参数值做为函数的返回值
5. 在调用mock出来的方法中,改变方法参数的值

一点简要说明:mockito其实已经可以满足大部分的需求,但是它的实现机制是使用cglib来动态创建接口的类的实例。但是这种实现方式不能用于构造函数和静态函数,因为那需要使用类的字节码(比如使用javassist). 所以我们才需要结合使用powermock.

1. mock构造函数, 如果有代码没有使用di注入依赖实例,在单元测试中可以使用powermock来模拟创建对象。
注意的开始两行的2个注解 @runwith 和 @preparefortest
@runwith比较简单,后面始终是powermockrunner.class
@preparefortext后面需要加的是调用构造函数的类名,而不是有构造函数的类本身。
在下面的例子中,我们要测试的类是:helper, 在helper类中调用了somthing类的构造函数来创建实例。
@runwith(powermockrunner.class)
@preparefortest(helper.
class)
public class helpertest {
  @mock
  
private something mocksomething;
      
  @injectmocks
  
private helper helper;
      
  @test
  
public void dosomething() throws exception {
      string argument 
= "arg";
          
      powermockito.whennew(something.
class).witharguments(argument).thenreturn(mocksomething);
         
      // 调用需要测试方法
      helper.dosomething(argument);
         
      // 进行验证
      verify(mocksomething).doit();
  }
}


public class helper {
  public void dosomething(string arg) {
      something something = new something(arg);
      something.doit();
  }
}


2,mock 静态函数, 单例模式就是一个典型的会调用静态函数的例子。 注意要点与mock构造函数相同。
class classwithstatics {
  
public static string getstring() {
    
return "string";
  }

  
public static int getint() {
    
return 1;
  }
}

@runwith(powermockrunner.
class)
@preparefortest(classwithstatics.
class)
public class stubjustonestatic {
  @test
  
public void test() {
    powermockito.mockstatic(classwithstatics.
class);

    when(classwithstatics.getstring()).thenreturn(
"hello!");

    system.out.println(
"string: "  classwithstatics.getstring());
    system.out.println(
"int: "  classwithstatics.getint());
  }
}

3。mock枚举实现的单例
singletonobject.java
public enum singletonobject { 
    instance
;
    private
int num;
    protected
void setnum(int num) {
        this.num = num;
    }
    public int getnum() {
        return
num;
    }

}
singletonconsumer.java

public class singletonconsumer {
    public string consumesingletonobject() { 
        return
string.valueof(singletonobject.instance.getnum());
    }
}
singletonconsumertest.java
@runwith(powermockrunner.class) 
@preparefortest({singletonobject.class})
public class singletonconsumertest {
    @test public void testconsumesingletonobject() throws exception {
        singletonobject
mockinstance = mock(singletonobject.class);
        whitebox
.setinternalstate(singletonobject.class, "instance", mockinstance);
        when
(mockinstance.getnum()).thenreturn(42);
        assertequals
("42", new singletonconsumer().consumesingletonobject());
    }
}
4。返回参数值做为函数返回值。
mockito 1.9.5之后,提供一个方便的方法来实现这个需要,在这之前可以使用一个匿名函数来返回一个answer来实现。
when(mymock.myfunction(anystring())).then(returnsfirstarg());
其中returnsfirstarg()是org.mockito.additionalanswers中的一个静态方法。
在这个类中还有其他的一些类似方法
returnssecondarg()
returnslastarg()
returnsargumentat(int position)

5. 在调用mock出来的方法中,改变方法参数的值
when( mymock.somemethod( any( list.class ) ) ).thenanswer( ( new answer<void>() {
    @override
    
public void answer( invocationonmock invocation )
            
throws throwable {
        object[] args 
= invocation.getarguments();
        list arg1 
= (list)args[0];
        arg1.add(
"12345");
        
return null;
    }
} ) );



verifying with generic parameters
verify(someservice).process(matchers.<collection<person>>any());
verify(adunomasterbaseprocessor).processbinfiles( anylistof(file.class) );


云自无心水自闲 2015-06-16 21:27 发表评论
]]>
简要说明如何在eclipse中的tomcat中进行配置使用springloaded在热加载更改的类http://www.blogjava.net/usherlight/archive/2015/06/11/425640.html云自无心水自闲云自无心水自闲thu, 11 jun 2015 13:59:00 gmthttp://www.blogjava.net/usherlight/archive/2015/06/11/425640.htmlhttp://www.blogjava.net/usherlight/comments/425640.htmlhttp://www.blogjava.net/usherlight/archive/2015/06/11/425640.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/425640.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/425640.htmltomcat都需要重新启动来使得刚才的更改生效。
而jrebel和springloaded都能有效地解决这个问题。其中springloaded是开源软件,可以免费使用,尤其难得。
其凯发k8网页登录主页:https://github.com/spring-projects/spring-loaded
在官方页面的简单介绍中,作者只讲述了如何在java程序中应用springloaded,而没有说明如何在tomcat中进行配置。
本文将简要进行介绍。

1,下载springloaded到本地目录,比如:c:\temp\springloaded-1.2.3.release.jar

2. 修改tomcat的应用,禁止tomcat自己的热加载,方法是在meta-inf目录下创建context.xml文件,里面包含如下语句,关键便是其中设置reloadable为false


3.在运行环境中添加springloaded的jar文件,在eclipse中右键点击项目,run as->run configuration
在弹出的窗口中,选择arguments标签,在vm arguments的末尾添加:
-javaagent:c:\temp\springloaded-1.2.3.release.jar -noverify
点击应用按钮。

以上便完成了所有的配置,步骤并不复杂。


云自无心水自闲 2015-06-11 21:59
]]>
使用visualvm来监控包装为windows服务的java程序http://www.blogjava.net/usherlight/archive/2015/06/11/425624.html云自无心水自闲云自无心水自闲thu, 11 jun 2015 06:09:00 gmthttp://www.blogjava.net/usherlight/archive/2015/06/11/425624.htmlhttp://www.blogjava.net/usherlight/comments/425624.htmlhttp://www.blogjava.net/usherlight/archive/2015/06/11/425624.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/425624.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/425624.html并且可以通过简单的配置来允许使用visualvm进行监控。

配置方法:
在wrapper.conf中添加如下3行

wrapper.java.additional.1=-dcom.sun.management.jmxremote.port=9898 #这里的端口号可以自行选择。
wrapper.java.additional.2=-dcom.sun.management.jmxremote.ssl=false
wrapper.java.additional.3=-dcom.sun.management.jmxremote.authenticate=false

修改完毕保存后重新启动服务。

打开visualvm, 在菜单中选择 file->add jmx connection。
在弹出窗口中,connection一项中输入: localhost:9898 即可。

此配置对于jconsole也同样有效。

云自无心水自闲 2015-06-11 14:09
]]>
将java.util.logging的日志统一输出到slf4j的框架中http://www.blogjava.net/usherlight/archive/2015/04/27/424701.html云自无心水自闲云自无心水自闲mon, 27 apr 2015 07:31:00 gmthttp://www.blogjava.net/usherlight/archive/2015/04/27/424701.htmlhttp://www.blogjava.net/usherlight/comments/424701.htmlhttp://www.blogjava.net/usherlight/archive/2015/04/27/424701.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/424701.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/424701.html可以使用slf4j提供的类来转接这部分的日志输出。

方法:
1、类路径中添加
    slf4j-api-1.7.10.jar
    jul-to-slf4j.1.7.10.jar ( 用于将java.util.logging的日志桥接到slf4j中)
    logback-core.1.1.2.jar
    logback-classic-1.1.2.jar

2、在代码中添加:
         // optionally remove existing handlers attached to j.u.l root logger
         slf4jbridgehandler.removehandlersforrootlogger();  // (since slf4j 1.6.5)

         // add slf4jbridgehandler to j.u.l's root logger, should be done once during
         // the initialization phase of your application
         slf4jbridgehandler.install();

注意事项:
1、这个桥接可以会造成性能问题。
和其他的桥接实现(比如:log4j, commons logging)不同,这个模块并不真正的完全替代java.util.logging类,因为这个java.util.logging是java自带的。
所以只是把原来的日志对象进行了转换,简单的说,这个转换过程是有开销的。
关键在于,不管日志语句有没有根据日志级别被关闭,这个转换无法避免。

2、不能在类路径中放入
slf4j-jkd14.jar
jul-toslf4j.jar


云自无心水自闲 2015-04-27 15:31
]]>
angularjs中的依赖注入和服务(service)http://www.blogjava.net/usherlight/archive/2015/02/09/422835.html云自无心水自闲云自无心水自闲mon, 09 feb 2015 11:28:00 gmthttp://www.blogjava.net/usherlight/archive/2015/02/09/422835.htmlhttp://www.blogjava.net/usherlight/comments/422835.htmlhttp://www.blogjava.net/usherlight/archive/2015/02/09/422835.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/422835.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/422835.html
在前文(http://www.blogjava.net/usherlight/archive/2015/02/01/422633.html)中我们曾经介绍过,定义controller时,需要2个参数,第一个参数是controller的名称,第二个参数是一个数组,数组的最后一个元素将是controller的函数,前面的参数是controller的依赖项。我们现在就来仔细分析一下其中的具体过程。

先给一个例子:
angular. module('notesapp' , [])
 . controller('mainctrl' , ['$log' , function($log) {
 var self = this;
 self. logstuff = function() {
 $log. log('the button was pressed' );
 };
 }])

在这个例子中可以看到,我们在第一个参数中用字符串(服务名称)添加了一个依赖项。当我们通过字符串声明了这一个服务之后,我们就可以把它当作一个变量注入到函数中。angularjs会自动查找字符串名称对应的服务名,按照顺序将其注入到函数中。
mymodule.controller("mainctrl",  ["$log", "$window", function($l, $w) {}]);
在这个例子中,$log, $windows是angularjs自带的两个服务,在数组中通过名称声明后,会被注入到函数的两个参数中。
比较常用的angularjs自带的服务有:$window, $location, $http等

从上面的例子中可以看出,angularjs的设计思想就是不要在函数中自己去实例化或者通过其它途径来获取服务的实例,而是声明需要的对象,由angularjs来注入具体的实例。

创建自己的服务
什么时候应该创建服务,而不是controller呢?
1。 需要重用的时候
2。需要保留应用级的状态。这是非常重要的一点,controller是会不断地被创建和销毁的,如果需要保存应用级的状态,就需要使用service
3。和页面显示无关
4。需要和第三方服务整合
5。缓存

服务是会被延迟加载的,也就是说只有在第一次被引用的时候,才会被创建。
服务将会被定义一次,也只会被实例化一次。


云自无心水自闲 2015-02-09 19:28
]]>
angularjs的一些使用方法和技巧(2)http://www.blogjava.net/usherlight/archive/2015/02/03/422713.html云自无心水自闲云自无心水自闲tue, 03 feb 2015 11:36:00 gmthttp://www.blogjava.net/usherlight/archive/2015/02/03/422713.htmlhttp://www.blogjava.net/usherlight/comments/422713.htmlhttp://www.blogjava.net/usherlight/archive/2015/02/03/422713.html#feedback1http://www.blogjava.net/usherlight/comments/commentrss/422713.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/422713.html07. ng-repeart
a. 在循环map的时候,会自动根据键值进行排序。
b. 一些自带的变量,$first(是否是第一个), $last(是否是最后一个), $middle(是否是中间的), $index(下标,根据键值排序后的下标), $even, $odd
08. 自己定义新变量时不要使用$$开头。
09. 可以使用track-by表达式来优化对dom的操作,对dom对象使用从数据库取得的id来进行标记,这样的话,当我们重复多次从数据库中取出相同的数据的时候,dom对象就能够被重用。
10. 数据双向绑定的好处
a. 如果我们想改变页面form中的数值,我们不需要在javascript中,根据id或者名称来查找相应的form控件,只需要改变controller变量的值,不需要jquery的selector,也不需要findelementbyid
b. 如果我们想在javascript中获取form控件的值,在控件的变量中就能直接获得。
11. 使用ng-submit比在button上使用ng-click要好一些。html的表单的提交有多种方式,比如在输入域中按回车键就会触发ng-submit,而不会触发button的ng-click事件。
12. 在ng-model中,可以直接引用一个对象,比如:,而不需要事先在model中以self.user={}定义。在angularjs中,使用了ng-model的话,angularjs在初始化数据绑定的时候,自动创建其中的对象和键值。在刚才的例子中,一旦用户开始在输入域中键入第一个字母,用户user就会被自动创建。
13. 推荐使用将相关数据集中到一个对象的方式来进行数据绑定,比如,用户名和密码,推荐使用:
而不是:


云自无心水自闲 2015-02-03 19:36
]]>
angularjs的一些使用方法和技巧(1)http://www.blogjava.net/usherlight/archive/2015/02/01/422633.html云自无心水自闲云自无心水自闲sun, 01 feb 2015 11:19:00 gmthttp://www.blogjava.net/usherlight/archive/2015/02/01/422633.htmlhttp://www.blogjava.net/usherlight/comments/422633.htmlhttp://www.blogjava.net/usherlight/archive/2015/02/01/422633.html#feedback1http://www.blogjava.net/usherlight/comments/commentrss/422633.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/422633.html1. angularjs的module函数有两种用法,
a. 定义一个module, 需要传入2个参数,module('modulename', []), 第一个参数是新的module名称,第二个参数是新module所依赖的module数组。
b. 载入一个module, 只需要1个参数,module('modulename'), 唯一的一个参数指定要载入的module名称。
2. 使用controller函数来定义一个控制器(controller), 用ng-controller将控制器绑定到具体的html组件上。定义控制器的controller函数也需要2个参数,第一个是控制器名称,第二个参数同样也是一个数组,数组的最后一个元素就是controller本身的函数,前面的元素用字符串的形式指定其需要的依赖项。如果没有依赖项,那就只需要定义函数。比如:
angular.module('app1', [])
.controller('maincontrol', [function() {
console.log('controller created.');
}]);
3. 在controller函数中用var定义的局部变量,在html中是不可见的。
4. 推荐在controller函数中尽量避免直接引用this, 比较好的做法是使用代理。原因是一个函数中的this关键词在被外部调用的时候,是会被覆盖掉的。这样的话,在函数内部和外部的this会是完全不同两个对象。
代理用法示例:
angular.module('app1', [])
.controller('maincontrol', [function() {
var self = this;
self.message = 'hello world';
self.changemessage = function() {
self.message = 'goodbye.';
};
}]);
5. ng-bind与双大括号的区别, ng-bind和{{}}可以说基本上是可以互相替换的,但是也有区别。区别在于:angularjs在启动的时候就会执行ng-bind, 而{{}}的替换时间会稍晚一些。有可能发现页面在加载的时候,双括号被一闪而过地替换掉(只在页面初次加载的时候发生)。但是ng-bind就没有这个问题。
6. ng-cloak可以用于解决双括号闪现的问题。


云自无心水自闲 2015-02-01 19:19
]]>
openpgp加密解密文件 http://www.blogjava.net/usherlight/archive/2014/12/10/421238.html云自无心水自闲云自无心水自闲tue, 09 dec 2014 22:50:00 gmthttp://www.blogjava.net/usherlight/archive/2014/12/10/421238.htmlhttp://www.blogjava.net/usherlight/comments/421238.htmlhttp://www.blogjava.net/usherlight/archive/2014/12/10/421238.html#feedback5http://www.blogjava.net/usherlight/comments/commentrss/421238.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/421238.htmlopenpgp 号称是世界上使用最广泛的邮件加密标准.  openpgp is the most widely used email encryption standard in the world. ( http://www.openpgp.org/ )
这篇例子介绍如何使用这个标准进行文件的加密解密 (https://www.bouncycastle.org/latest_releases.html, 需要下载: bcprov-jdk15on-151.jar, bcpg-jdk15on-151.jar).

主要是使用bouncycastle提供的openpgp的库来完成这个功能,参照了其提供的示例程序,进行了部分改动 ( bouncy castle 是一种用于 java 平台的开放源码的轻量级密码术包。它支持大量的密码术算法,并提供 jce 1.2.1 的实现。因为 bouncy castle 被设计成轻量级的,所以从 j2se 1.4 到 j2me(包括 midp)平台,它都可以运行。它是在 midp 上运行的唯一完整的密码术包。)
1. 添加循环遍历来查找第一个可用的message
2. 需要注意的是在main函数中的,如果不添加这一句的话 security.addprovider(new bouncycastleprovider()); 程序运行中会报错:no such provider "bc"
3. 
错误exception in thread "main" java.security.invalidkeyexception: illegal key size or default parameters , 这是因为java缺省的库支持的key长度比较短,需要到oracle的网站上去下载一个支持更长key的库覆盖原有的库文件
/lib/securty/ 目录下的两个jar文件
local_policy.jar and us_export_policy.jar
搜索这个文件: java cryptography extension (jce) unlimited strength jurisdiction policy files
下载页面(以jdk6为例):

package org.bouncycastle.openpgp.examples;

import java.io.bufferedinputstream;
import java.io.bufferedoutputstream;
import java.io.file;
import java.io.fileinputstream;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.inputstream;
import java.io.outputstream;
import java.security.nosuchproviderexception;
import java.security.securerandom;
import java.security.security;
import java.util.iterator;

import org.bouncycastle.bcpg.armoredoutputstream;
import org.bouncycastle.bcpg.compressionalgorithmtags;
import org.bouncycastle.jce.provider.bouncycastleprovider;
import org.bouncycastle.openpgp.pgpcompresseddata;
import org.bouncycastle.openpgp.pgpencrypteddata;
import org.bouncycastle.openpgp.pgpencrypteddatagenerator;
import org.bouncycastle.openpgp.pgpencrypteddatalist;
import org.bouncycastle.openpgp.pgpexception;
import org.bouncycastle.openpgp.pgpliteraldata;
import org.bouncycastle.openpgp.pgponepasssignaturelist;
import org.bouncycastle.openpgp.pgpprivatekey;
import org.bouncycastle.openpgp.pgppublickey;
import org.bouncycastle.openpgp.pgppublickeyencrypteddata;
import org.bouncycastle.openpgp.pgpsecretkeyringcollection;
import org.bouncycastle.openpgp.pgpsignaturelist;
import org.bouncycastle.openpgp.pgputil;
import org.bouncycastle.openpgp.jcajce.jcapgpobjectfactory;
import org.bouncycastle.openpgp.operator.jcajce.jcakeyfingerprintcalculator;
import org.bouncycastle.openpgp.operator.jcajce.jcepgpdataencryptorbuilder;
import org.bouncycastle.openpgp.operator.jcajce.jcepublickeydatadecryptorfactorybuilder;
import org.bouncycastle.openpgp.operator.jcajce.jcepublickeykeyencryptionmethodgenerator;
import org.bouncycastle.util.io.streams;

/**
 * a simple utility class that encrypts/decrypts public key based
 * encryption files.
 * 


 * to encrypt a file: keybasedfileprocessor -e [-a|-ai] filename publickeyfile.

 * if -a is specified the output file will be "ascii-armored".
 * if -i is specified the output file will be have integrity checking added.
 * 


 * to decrypt: keybasedfileprocessor -d filename secretkeyfile passphrase.
 * 


 * note 1: this example will silently overwrite files, nor does it pay any attention to
 * the specification of "_console" in the filename. it also expects that a single pass phrase
 * will have been used.
 * 


 * note 2: if an empty file name has been specified in the literal data object contained in the
 * encrypted packet a file with the name filename.out will be generated in the current working directory.
 */
public class keybasedfileprocessor
{
    private static void decryptfile(
        string inputfilename,
        string keyfilename,
        char[] passwd,
        string defaultfilename)
        throws ioexception, nosuchproviderexception
    {
        inputstream in = new bufferedinputstream(new fileinputstream(inputfilename));
        inputstream keyin = new bufferedinputstream(new fileinputstream(keyfilename));
        decryptfile(in, keyin, passwd, defaultfilename);
        keyin.close();
        in.close();
    }

    /**
     * decrypt the passed in message stream
     
*/
    private static void decryptfile(
        inputstream in,
        inputstream keyin,
        char[]      passwd,
        string      defaultfilename)
        throws ioexception, nosuchproviderexception
    {
        in = pgputil.getdecoderstream(in);
        
        try
        {
            jcapgpobjectfactory pgpf = new jcapgpobjectfactory(in);
            pgpencrypteddatalist    enc;

            object                  o = pgpf.nextobject();
            //
            
// the first object might be a pgp marker packet.
            
//
            if (o instanceof pgpencrypteddatalist)
            {
                enc = (pgpencrypteddatalist)o;
            }
            else
            {
                enc = (pgpencrypteddatalist)pgpf.nextobject();
            }
            
            //
            
// find the secret key
            
//
            iterator                    it = enc.getencrypteddataobjects();
            pgpprivatekey               skey = null;
            pgppublickeyencrypteddata   pbe = null;
            pgpsecretkeyringcollection  pgpsec = new pgpsecretkeyringcollection(
                pgputil.getdecoderstream(keyin), new jcakeyfingerprintcalculator());

            while (skey == null && it.hasnext())
            {
                pbe = (pgppublickeyencrypteddata)it.next();
                
                skey = pgpexampleutil.findsecretkey(pgpsec, pbe.getkeyid(), passwd);
            }
            
            if (skey == null)
            {
                throw new illegalargumentexception("secret key for message not found.");
            }
    
            inputstream         clear = pbe.getdatastream(new jcepublickeydatadecryptorfactorybuilder().setprovider("bc").build(skey));
            
            jcapgpobjectfactory    plainfact = new jcapgpobjectfactory(clear);
            
            object              message = plainfact.nextobject();
    
            while ( true ) {
                if (message instanceof pgpcompresseddata)
                {
                    pgpcompresseddata   cdata = (pgpcompresseddata)message;
                    jcapgpobjectfactory    pgpfact = new jcapgpobjectfactory(cdata.getdatastream());
                    
                    message = pgpfact.nextobject();
                }
                
                if (message instanceof pgpliteraldata)
                {
                    pgpliteraldata ld = (pgpliteraldata)message;

                    string outfilename = ld.getfilename();
                    if (outfilename.length() == 0)
                    {
                        outfilename = defaultfilename;
                    }

                    inputstream unc = ld.getinputstream();
                    outputstream fout = new bufferedoutputstream(new fileoutputstream(outfilename));

                    streams.pipeall(unc, fout);

                    fout.close();
                    break;
                }
                else if (message instanceof pgponepasssignaturelist)
                {
                    system.out.println("encrypted message contains a signed message - not literal data.");
                }
                else if (message instanceof pgpsignaturelist)
                {
                    system.out.println("encrypted message contains a signed message - not literal data.");
                }
                else
                {
                    throw new pgpexception("message is not a simple encrypted file - type unknown.");
                }
                message = plainfact.nextobject();
            }
            
            if (pbe.isintegrityprotected())
            {
                if (!pbe.verify())
                {
                    system.err.println("message failed integrity check");
                }
                else
                {
                    system.err.println("message integrity check passed");
                }
            }
            else
            {
                system.err.println("no message integrity check");
            }
        }
        catch (pgpexception e)
        {
            system.err.println(e);
            if (e.getunderlyingexception() != null)
            {
                e.getunderlyingexception().printstacktrace();
            }
        }
    }

    private static void encryptfile(
        string          outputfilename,
        string          inputfilename,
        string          enckeyfilename,
        boolean         armor,
        boolean         withintegritycheck)
        throws ioexception, nosuchproviderexception, pgpexception
    {
        outputstream out = new bufferedoutputstream(new fileoutputstream(outputfilename));
        pgppublickey enckey = pgpexampleutil.readpublickey(enckeyfilename);
        encryptfile(out, inputfilename, enckey, armor, withintegritycheck);
        out.close();
    }

    private static void encryptfile(
        outputstream    out,
        string          filename,
        pgppublickey    enckey,
        boolean         armor,
        boolean         withintegritycheck)
        throws ioexception, nosuchproviderexception
    {
        if (armor)
        {
            out = new armoredoutputstream(out);
        }

        try
        {
            byte[] bytes = pgpexampleutil.compressfile(filename, compressionalgorithmtags.zip);

            pgpencrypteddatagenerator encgen = new pgpencrypteddatagenerator(
                new jcepgpdataencryptorbuilder(pgpencrypteddata.cast5).setwithintegritypacket(withintegritycheck).setsecurerandom(new securerandom()).setprovider("bc"));

            encgen.addmethod(new jcepublickeykeyencryptionmethodgenerator(enckey).setprovider("bc"));

            outputstream cout = encgen.open(out, bytes.length);

            cout.write(bytes);
            cout.close();

            if (armor)
            {
                out.close();
            }
        }
        catch (pgpexception e)
        {
            system.err.println(e);
            if (e.getunderlyingexception() != null)
            {
                e.getunderlyingexception().printstacktrace();
            }
        }
    }

    public static void main(
        string[] args)
        throws exception
    {
        security.addprovider(new bouncycastleprovider());

        if (args.length == 0)
        {
            system.err.println("usage: keybasedfileprocessor -e|-d [-a|ai] file [secretkeyfile passphrase|pubkeyfile]");
            return;
        }

        if (args[0].equals("-e"))
        {
            if (args[1].equals("-a") || args[1].equals("-ai") || args[1].equals("-ia"))
            {
                encryptfile(args[2]   ".asc", args[2], args[3], true, (args[1].indexof('i') > 0));
            }
            else if (args[1].equals("-i"))
            {
                encryptfile(args[2]   ".bpg", args[2], args[3], falsetrue);
            }
            else
            {
                encryptfile(args[1]   ".bpg", args[1], args[2], falsefalse);
            }
        }
        else if (args[0].equals("-d"))
        {
            decryptfile(args[1], args[2], args[3].tochararray(), new file(args[1]).getname()   ".out");
        }
        else
        {
            system.err.println("usage: keybasedfileprocessor -d|-e [-a|ai] file [secretkeyfile passphrase|pubkeyfile]");
        }
    }
}



asdf

云自无心水自闲 2014-12-10 06:50
]]>
nettyhttp://www.blogjava.net/usherlight/archive/2014/11/27/420676.html云自无心水自闲云自无心水自闲wed, 26 nov 2014 23:36:00 gmthttp://www.blogjava.net/usherlight/archive/2014/11/27/420676.htmlhttp://www.blogjava.net/usherlight/comments/420676.htmlhttp://www.blogjava.net/usherlight/archive/2014/11/27/420676.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/420676.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/420676.html
在netty in action中是这样描述的:
while the i/o thread must not be blocked at all, thus prohibiting any direct blocking operations within your channelhandler, there is a way to implement this requirement. 
you can specify an eventexecutorgroup when adding channelhandlers to the channelpipeline. 
this eventexecutorgroup will then be used to obtain an eventexecutor, which will execute all the methods of the channelhandler. 
this eventexecutor will use a different thread from the i/o thread, thus freeing up the eventloop.
i/o线程是不允许被阻塞的,也就是不能在channelhandler中进行任何阻塞式的处理,但是对此我们也有相应的解决方法.
就是在把channelhanders添加到channelpipeline的时候,指定一个eventexecutorgroup,channelhandler中所有的方法都将会在这个指定的eventexecutorgroup中运行。
而这个eventexecutorgroup运行的线程与i/o线程不同,达到不阻塞i/o的目的。 
程序示例如下:
channel ch = ...;
channelpipeline p = ch.pipeline();
eventexecutor e1 = new defaulteventexecutorgroup(16);
eventexecutor e2 = new defaulteventexecutorgroup(8);
 
p.addlast(new myprotocolcodec());
p.addlast(e1, new mydatabaseaccessinghandler());
p.addlast(e2, new myharddiskaccessinghandler());
需要补充说明一下,上面的示例程序似乎有点问题。使用上述方法添加channelhandler到pipeline中以后,channelhandler的所有方法确实什么在一个单独的线程中被处理。
但是,每次defaulteventexcutorgroup线程池中的线程不能被重用,每次都会生成一个新的线程,然后在新的线程中调用channelhandler, 在visualvm可以看到线程数量直线增长。

解决的方法是:不能使用局部变量形式的defaulteventexecutorgroup。而使用类静态成员变量:
static final eventexecutor e1 = new defaulteventexecutorgroup(16);

我分析原因可能是:在新的连接到来,创建channelpipeline给新channel的时候,如果不使用静态的共享变量,而使用局部变量的话,就造成defaulteventexecutorgroup被多次重复创建。因此,虽然一个defaulteventexecutorgroup中的thread数量是固定的,但是却产生了多余的defaulteventexecutorgroup。从visualvm中也可以看到,defaulteventexecutorgroup线程的名字会是:
xxx-2-1
xxx-3-1
xxx-4-1
xxx-n-1
说明是group的数量(第一个数字)在增多,而不是group中的线程数量(第二个数字)在增多
改成静态变量后,线程名会是:
xxx-2-1
xxx-2-2
xxx-2-3
xxx-2-n
最后一个n就是在创建defaulteventexecutorgroup时候,传入的线程个数参数的大小。


云自无心水自闲 2014-11-27 07:36
]]>
spring mvc spring security spring jdbc中注入datasource总是为null的原因和解决http://www.blogjava.net/usherlight/archive/2011/08/26/357316.html云自无心水自闲云自无心水自闲fri, 26 aug 2011 00:57:00 gmthttp://www.blogjava.net/usherlight/archive/2011/08/26/357316.htmlhttp://www.blogjava.net/usherlight/comments/357316.htmlhttp://www.blogjava.net/usherlight/archive/2011/08/26/357316.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/357316.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/357316.html
在applicationcontext.xml中定义了一个datasource:
但是在代码中,使用anotation进行注入的时候,却总是找不到这个datasource.

    @autowired
    public void setdatasource(datasource datasource) {
        jdbctemplate = new jdbctemplate(datasource);
        jdbcinsert = new simplejdbcinsert(datasource);
    }

最后终于想明白了,原因大概是这样的,使用autowired的时候,默认是根据类型来匹配的,在xml中定义的类型是:basicdatasource,而不是接口datasource,所以默认情况下这样是无法自动装配的。解决办法是指令使用名字来进行bean的匹配,也就是用qualifier指定bean的id.

    @autowired
    public void setdatasource(@qualifier("datasource") datasource datasource) {
        jdbctemplate = new jdbctemplate(datasource);
        jdbcinsert = new simplejdbcinsert(datasource);
    }


另外一点,在网上搜索的过程中发现有不少人都有类似的问题,但是他们的原因是没有正确使用spring的注入,而是自己在代码中new了一个dao的实例,这样的话,spring是无法将datasource注入到dao的实例中的



云自无心水自闲 2011-08-26 08:57
]]>
我觉得最好用的mysql客户端工具-heidisqlhttp://www.blogjava.net/usherlight/archive/2011/08/08/355998.html云自无心水自闲云自无心水自闲mon, 08 aug 2011 02:36:00 gmthttp://www.blogjava.net/usherlight/archive/2011/08/08/355998.htmlhttp://www.blogjava.net/usherlight/comments/355998.htmlhttp://www.blogjava.net/usherlight/archive/2011/08/08/355998.html#feedback4http://www.blogjava.net/usherlight/comments/commentrss/355998.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/355998.html
heidisql是一家德国公司研发的轻量级的,开源mysql客户端工具。体积十分小巧,可是十分实用。

我之所以喜欢的原因:
1,有导入/导出的功能,可以将数据直接从文本文件中导入到数据库的数据表中。
2,可以将选中的数据导出成为sql语句
3,界面布置十分合理,操作简便

云自无心水自闲 2011-08-08 10:36
]]>
打开有密码保护(但是没有加密)的excel文件http://www.blogjava.net/usherlight/archive/2011/05/30/351313.html云自无心水自闲云自无心水自闲mon, 30 may 2011 02:42:00 gmthttp://www.blogjava.net/usherlight/archive/2011/05/30/351313.htmlhttp://www.blogjava.net/usherlight/comments/351313.htmlhttp://www.blogjava.net/usherlight/archive/2011/05/30/351313.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/351313.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/351313.html
主要是使用:
biff8encryptionkey.setcurrentuserpassword(password);
在打开workbook之前
hssfworkbook workbook = new hssfworkbook(inp);
注意事项:这个应该是只适用于xls,而不是xlsx


云自无心水自闲 2011-05-30 10:42
]]>
java串口编程需要注意的几个地方http://www.blogjava.net/usherlight/archive/2011/02/07/343929.html云自无心水自闲云自无心水自闲mon, 07 feb 2011 05:22:00 gmthttp://www.blogjava.net/usherlight/archive/2011/02/07/343929.htmlhttp://www.blogjava.net/usherlight/comments/343929.htmlhttp://www.blogjava.net/usherlight/archive/2011/02/07/343929.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/343929.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/343929.html
我使用的是sun提供的javax.comm包,不确定其他的comm支持包(比如:rxtx)行为与之相同
1、事件驱动的数据读取
需要注意的是:一个serialport只能注册一个事件监听程序,因此,有时候有会发现,你的事件监听处理程序会变得非常庞大
另外,要注意的就是事件处理如果比较耗时的话,最好是在单独的线程中运行,否则会阻塞数据的接收。
串口接收到数据后,默认在线程: win32serialport notification thread中运行。如果不及时释放的话,会造成数据无法读取。
我的做法是,接收到数据后,先判断数据的合法和完整性,如果没有接收到完整的数据,则在缓存数据后,马上返回
如果数据完整而且合法,则另开一个线程,进行数据处理
2、数据的发送
建议单独使用一个线程来发送数据,目的还是为了防止阻塞,有一个技巧就是使用output_buffer_empty事件来发送。


云自无心水自闲 2011-02-07 13:22
]]>
tapestry的一些最新动态http://www.blogjava.net/usherlight/archive/2010/11/24/338872.html云自无心水自闲云自无心水自闲tue, 23 nov 2010 22:08:00 gmthttp://www.blogjava.net/usherlight/archive/2010/11/24/338872.htmlhttp://www.blogjava.net/usherlight/comments/338872.htmlhttp://www.blogjava.net/usherlight/archive/2010/11/24/338872.html#feedback3http://www.blogjava.net/usherlight/comments/commentrss/338872.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/338872.html 1、tapestry5.2.4的发布,tapestry5.2.3版本在内部投票中被否决(主要是因为使用maven快速创建的原型有问题),所以在被否决的3天后便发布了5.2.4,相对5.2.2来说,变动并不大,只有8个错误修复和5个功能改进。但是至少说明tapestry的项目还在顺利的进行中。
2、tapestry凯发k8网页登录主页的全新改版。主要是完善了文档。这一点是非常重要的,tapestry项目组的成员也承认tapestry在推销自己或者是在市场推广方面做得非常失败(very bad in marketing),所以最近也采取了一些措施来进行改变,比如,预计明年会发行tapestry5 in action一书等等。
3、还有一件事需要提及的是:appfuse的作者最近对web框架进行了一番对比http://raibledesigns.com/rd/entry/my_comparing_jvm_web_frameworks,tapestry在13个框架中名列第7,刚好是中间的位置。tapestry项目的成员颇有不满,认为作者matt raible对tapestry不够了解,有误导观众之嫌。tapestry项目成员igor e. poteryaev认为matt在 认识度,开发效率,项目健康度,测试友好性,scalability等方面严重低估了tapestry的能力。


云自无心水自闲 2010-11-24 06:08
]]>
mybatis的一些新动态http://www.blogjava.net/usherlight/archive/2010/11/02/336750.html云自无心水自闲云自无心水自闲tue, 02 nov 2010 00:10:00 gmthttp://www.blogjava.net/usherlight/archive/2010/11/02/336750.htmlhttp://www.blogjava.net/usherlight/comments/336750.htmlhttp://www.blogjava.net/usherlight/archive/2010/11/02/336750.html#feedback1http://www.blogjava.net/usherlight/comments/commentrss/336750.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/336750.html 2、发布了mybatis-generator 1.3.0, 这是一个能够根据数据库的表自动生成mybatis的
        sqlmap xml文件
        与数据表对应的java class
        使用上两个文件的java类
我下载后,尝试着使用了一下,发现需要有一个配置文件,我觉得应该是用于提供数据库连接的信息。但是配置文件的格式不详。
现在发现mybatis的文档比较成问题,很多东西都没有说明,使用起来很困难啊。
3、新增了两个中方翻译文档
        # mybatis 3 user guide simplified chinese.pdf
        # mybatis-spring reference simplied chinese.pdf
4、发布了mybatis-spring-1.0.0-rc2
5、发布了mybatis-guice-1.0.0-rc3

云自无心水自闲 2010-11-02 08:10
]]>
tapestry5.2.2(beta release)发布了http://www.blogjava.net/usherlight/archive/2010/11/02/336747.html云自无心水自闲云自无心水自闲mon, 01 nov 2010 23:58:00 gmthttp://www.blogjava.net/usherlight/archive/2010/11/02/336747.htmlhttp://www.blogjava.net/usherlight/comments/336747.htmlhttp://www.blogjava.net/usherlight/archive/2010/11/02/336747.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/336747.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/336747.html 这主要是便于ajax的使用。

bug

    *  element.forceattribute uses the element's namespace to match the attribute.
    *  element.attribute(string name, string value) adds elements that already exist
    *  element#addclassname can create an additional new 'class' attribute
    *  properties defined in an interface are not exposed by propertyaccess for abstract classes that do not directly implement the methods
    *  some services require a notification that they have been reloaded, so they can clean up external dependencies
    *  whitespaces in symbolconstants.supported_locales cause that locales are not persised
    *  validation macros do not work when used in @validate annotation
    *  client-side validation of @pattern is broken
    *  linking a form to a zone will no longer work unless the form contains validated fields
    *  when using propertyshadowbuilder to build a service, if the property is null, an immediate exception is needed (rather than a nullpointerexception)
    *  when using a multizoneupdate, tapestry will clear the referenced zone

improvement

    *  add the facility to optionally disable on-focus-change triggered validation while retaining the on-form-submit validation
    *  form component should be able to render a secure url even on an insecure page
    *  new annotations @decorate and @advise to identify methods that decorate or annotate services
    *  extend link with new methods for producing absolute urls (that include scheme, hostname, etc.)
    *  simplify connecting a link or form to an (enclosing) zone
    *  beanblockcontribution should be split into two sub-classes: editblockcontribution and displayblockcontribution
    *  define a special css class to prevent a client-side form from submitting normally (for ajax use cases)
    *  additional method for link: addparametervalue(string,object) that uses contextpathencoder to encode object value to a string
    *  seleniumtestcase should expose the underlying commandprocessor, to allow execution of commands not defined by the selenium interface
    *  allow individual seleniumtestcases to run w/o configuring seleniumlauncher



云自无心水自闲 2010-11-02 07:58
]]>
tapestry5.2.1 beta已经发布http://www.blogjava.net/usherlight/archive/2010/10/20/335644.html云自无心水自闲云自无心水自闲tue, 19 oct 2010 23:38:00 gmthttp://www.blogjava.net/usherlight/archive/2010/10/20/335644.htmlhttp://www.blogjava.net/usherlight/comments/335644.htmlhttp://www.blogjava.net/usherlight/archive/2010/10/20/335644.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/335644.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/335644.html今天在网上转了转,发现tapestry又有了新动作。
1、从5.2.0alpha版8月11日发布到现在,终于发布5.2.1beta版了。这个版本主要是修改alpha版本中的bug.
5.2相对于5.1进行了许多重大的改进,详细内容可见:
2、据称在5.3版中将引入大量的新功能,具体内容不详。
3、以往最令人诟病的文档问题,目前开发小组也在努力解决。
     首先,建立了新的文档网页:http://people.apache.org/~uli/tapestry-site/,不过目前这个网站还没有完全完成,只能算是预览版,但是这毕竟是在正确的道路上前进。
     其次,tapestry 5 in action一书正在写作中,已经完成20%,预计明年一季度能够出版。
我相信,随着功能的不断完善和补充,再加上文档的逐渐充实,tapestry完全有理由能吸引更多的开发者来关注和使用。

云自无心水自闲 2010-10-20 07:38
]]>
mybatis3.0.2已经发布http://www.blogjava.net/usherlight/archive/2010/09/13/331886.html云自无心水自闲云自无心水自闲mon, 13 sep 2010 04:42:00 gmthttp://www.blogjava.net/usherlight/archive/2010/09/13/331886.htmlhttp://www.blogjava.net/usherlight/comments/331886.htmlhttp://www.blogjava.net/usherlight/archive/2010/09/13/331886.html#feedback1http://www.blogjava.net/usherlight/comments/commentrss/331886.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/331886.html这是mybatis从ibatis更名过来后,发布的第2个版本(第1个版本是3.0.1)。
在这个版本中只修复了4个bug(感觉数目有点少,难道是因为上一个版本的bug真的如此之少?),增加了一个小功能.
作者的话:尽管只有5个修改,但我还是觉得值得为此发布一个新版本。
这5个修改是:
1、在org.apache.ibatis.session中增加了一个新方法:void select(string statement, resulthandler handler);
原来只有:
 void select(string statement, object parameter, resulthandler handler);
 void select(string statement, object parameter, rowbounds rowbounds, resulthandler handler);

2、修复了managedconnection中关闭连接的问题
3、修复了schema migration中,语句提交(statement commit)不正确的问题
4、修复了延迟加载已经预读取属性时的问题
5、修复了schema migration中,fileinputstream没有正确关闭的问题



云自无心水自闲 2010-09-13 12:42
]]>
批处理图像http://www.blogjava.net/usherlight/archive/2010/08/20/329424.html云自无心水自闲云自无心水自闲fri, 20 aug 2010 00:51:00 gmthttp://www.blogjava.net/usherlight/archive/2010/08/20/329424.htmlhttp://www.blogjava.net/usherlight/comments/329424.htmlhttp://www.blogjava.net/usherlight/archive/2010/08/20/329424.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/329424.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/329424.html 批量处理图像就是通过一个批处理插件来完成的。这个插件的下载地址:http://members.ozemail.com.au/~hodsond/dbp.html
插件下载后,解压缩,然后把dbp.exe放在plugin目录下,比如:c:\program files\gimp-2.0\lib\gimp\2.0\plug-ins
启动gimp,在菜单 filter 里会发现一个新的选项:batch process...
点击这个选项,会弹出一个新窗口,这个就是批处理的操作界面了。
通过这个插件,我们可以完成 批量改变大小/重命名/旋转/锐化/模糊/调整亮度/裁剪 这些功能。

云自无心水自闲 2010-08-20 08:51
]]>
tapestry5.2的新变化http://www.blogjava.net/usherlight/archive/2010/08/18/329170.html云自无心水自闲云自无心水自闲tue, 17 aug 2010 23:13:00 gmthttp://www.blogjava.net/usherlight/archive/2010/08/18/329170.htmlhttp://www.blogjava.net/usherlight/comments/329170.htmlhttp://www.blogjava.net/usherlight/archive/2010/08/18/329170.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/329170.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/329170.html 1、增强了class reload的功能(我个人也认为这一点是5.2版本最令人激动的改进),以前tapestry和其他的web框架类似,修改页面不需要重新启动application server, 但是修改了类之后,必须重新启动应用服务器才行。但是在tapestry5.2中,对这一点进行了修改,如果只改变了接口的实现类,而不改变接口的方法签名,就不需要重新启动应用服务器
2、新增了若干个组件,比如:error和trigger。
error和原有的errors类似,但是error用于给指定的组件显示验证错误信息。
trigger提供了在泻染页面过程中触发任务事件的功能,常常用于通过rendersupport来给页面添加javascript代码
3、新的插件(mixin),包括renderclientid, rendernotification
4、集成了jsr-303 bean的验证,现在可以在页面中使用jsr-303标准的注解来给字段指定需要的验证
5、新的注解,包括@contribute,@requestparameter, @activationrequestparameter, 使用后两个注解能很容易地获取request中的参数
6、新的页面生命周期事件:pagereset
7、链接修饰过程中的新事件: decoratepagerenderlink, decoreatecomponenteventlink
8、页面解析器的更换,原来使用stax,造成了对google app engine和对osgi的不兼容,5.2版本中使用了标准的sax解析器
9、页面缓冲池的废除(我认为这是5.2版本的一个相当大而且也是非常重要的一个变化,我认为页面缓冲池技术是tapestry学习曲线陡峭的一个重要原因),5.2版本中所有页面将只有一个实例(也就是lewis howard说的单例化),页面属性的值将会在每个线程中使用一个map来保存。这样一个页面实例可以在多个线程中使用,而不会有同步问题。
但是,由于这是一个新的尝试,所以lewis也不确定这样做的效果是否很好(详见:http://tapestryjava.blogspot.com/2010/07/everyone-out-of-pool-tapestry-goes.html)所以,在5.2中可以通过配置恢复页面缓冲池的使用。

云自无心水自闲 2010-08-18 07:13
]]>
prototype版的table filterhttp://www.blogjava.net/usherlight/archive/2010/07/28/327294.html云自无心水自闲云自无心水自闲wed, 28 jul 2010 03:02:00 gmthttp://www.blogjava.net/usherlight/archive/2010/07/28/327294.htmlhttp://www.blogjava.net/usherlight/comments/327294.htmlhttp://www.blogjava.net/usherlight/archive/2010/07/28/327294.html#feedback1http://www.blogjava.net/usherlight/comments/commentrss/327294.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/327294.htmljquery有一个很方便的插件ui table filter可以根据输入的内容隐藏显示表格中相应的数据行。
因为目前使用的tapestry捆绑的是prototype,所以就自己写了一个类似的插件。







 
  filter: case-sensitive
  
   
    
     
     
     
     
     
     
     
    
   
   
    
    
    
    
    
    
    
   
   
    
    
    
    
    
    
    
   
   
    
    
    
    
    
    
    
   
   
    
    
    
    
    
    
    
   
   
    
    
    
    
    
    
    
   
  
namecolumn1column2column3column4column5column6
test00150002331238156075001172.16.14.201-1-05
test-200150002332238157075002172.16.14.211-1-05
test00150002333238158075003172.16.14.231-1-05
test00150002341238159075004172.16.14.241-1-05
test00150002339238186075006172.16.14.261-1-06

 
  

如果页面中多个表格,而只需要对其中的一个表格的数据进行过滤的话,简单地把其中:$$('tr').each(function(ele, index) 改成 $$('#tableid, tr').each(function(ele, index) 就行了,其中的tableid就是表格的id

云自无心水自闲 2010-07-28 11:02
]]>
使用gimp将图片背景透明化http://www.blogjava.net/usherlight/archive/2010/07/14/326050.html云自无心水自闲云自无心水自闲wed, 14 jul 2010 01:33:00 gmthttp://www.blogjava.net/usherlight/archive/2010/07/14/326050.htmlhttp://www.blogjava.net/usherlight/comments/326050.htmlhttp://www.blogjava.net/usherlight/archive/2010/07/14/326050.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/326050.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/326050.html 1、选择要保留的图形,
有2种办法,第一种就是直接用魔术棒工具来选择,但一般来说这部分图形的色彩比较复杂,选择起来相对困难
第2种办法是先选择背景,然后使用“反向选择”。
友情提示:在使用魔术棒的时候,有4种模式,可以利用其中的添加,减少来不断地修正选择的范围
2、打开图层面板
3、菜单:选择->浮动,在图层面板中可以看到多一个浮动的图层,但是现在图层里还没有东西
4、菜单:图层->创建,这时候就可以看到,在刚才多出来的浮动图层中出现了选择好的要保留的图像
5、去除背景图层,点击背景图层前面的眼睛,使得背景图层不可见
保存,生成透明背景的新图像

云自无心水自闲 2010-07-14 09:33
]]>
java swing 布局管理器http://www.blogjava.net/usherlight/archive/2010/07/05/325258.html云自无心水自闲云自无心水自闲mon, 05 jul 2010 01:38:00 gmthttp://www.blogjava.net/usherlight/archive/2010/07/05/325258.htmlhttp://www.blogjava.net/usherlight/comments/325258.htmlhttp://www.blogjava.net/usherlight/archive/2010/07/05/325258.html#feedback2http://www.blogjava.net/usherlight/comments/commentrss/325258.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/325258.htmlcardlayout布局管理器能够帮助用户处理两个以至更多的成员共享同一显示空间,它把容器分成许多层,每层的显示空间占据整个容器的大小,但是每层只允许放置一个组件,当然每层都可以利用panel来实现复杂的用户界面.布局管理器(cardlayout)就象一副叠得整整齐齐的扑克牌一样,有54 张牌,但是你只能看见最上面的一张牌,每一张牌就相当于布局管理器中的每一层.

流式布局管理器把容器看成一个行集,好象平时在一张纸上写字一样,一行写满就换下一行。行高是用一行中的控件高度决定的。flowlayout是所有 japplet/japplet的默认布局。在生成流式布局时能够指定显示的对齐方式,默认情况下是居中(flowlayout.center)

gridlayout 将成员按网格型排列,每个成员尽可能地占据网格的空间,每个网格也同样尽可能地占据空间,从而各个成员按一定的大小比例放置。如果你改变大小, gridlayout将相应地改变每个网格的大小,以使各个网格尽可能地大,占据container容器全部的空间。
基本布局策略是把容器的空间划分成若干行乘若干列的网格区域,组件就位于这些划分出来的小区域中,所有的区域大小一样。组件按从左到右,从上到下的方法加入。

boxlayout布局能够允许将控件按照x轴(从左到右)或者y轴(从上到下)方向来摆放,而且沿着主轴能够设置不同尺寸。



云自无心水自闲 2010-07-05 09:38
]]>
http协议返回代码的含义http://www.blogjava.net/usherlight/archive/2010/06/23/324225.html云自无心水自闲云自无心水自闲tue, 22 jun 2010 23:16:00 gmthttp://www.blogjava.net/usherlight/archive/2010/06/23/324225.htmlhttp://www.blogjava.net/usherlight/comments/324225.htmlhttp://www.blogjava.net/usherlight/archive/2010/06/23/324225.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/324225.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/324225.htmlhttp status codes explained
all valid http 1.1 status codes simply explained.

http, hypertext transfer protocol, is the method by which clients (i.e. you) and servers communicate. when someone clicks a link, types in a url or submits out a form, their browser sends a request to a server for information. it might be asking for a page, or sending data, but either way, that is called an http request. when a server receives that request, it sends back an http response, with information for the client. usually, this is invisible, though i'm sure you've seen one of the very common response codes - 404, indicating a page was not found. there are a fair few more status codes sent by servers, and the following is a list of the current ones in http 1.1, along with an explanation of their meanings.

a more technical breakdown of http 1.1 status codes and their meanings is available at . there are several versions of http, but currently http 1.1 is the most widely used.

informational

  • 100 - continue
    a status code of 100 indicates that (usually the first) part of a request has been received without any problems, and that the rest of the request should now be sent.
  • 101 - switching protocols
    http 1.1 is just one type of protocol for transferring data on the web, and a status code of 101 indicates that the server is changing to the protocol it defines in the "upgrade" header it returns to the client. for example, when requesting a page, a browser might receive a statis code of 101, followed by an "upgrade" header showing that the server is changing to a different version of http.

successful

  • 200 - ok
    the 200 status code is by far the most common returned. it means, simply, that the request was received and understood and is being processed.
  • 201 - created
    a 201 status code indicates that a request was successful and as a result, a resource has been created (for example a new page).
  • 202 - accepted
    the status code 202 indicates that server has received and understood the request, and that it has been accepted for processing, although it may not be processed immediately.
  • 203 - non-authoritative information
    a 203 status code means that the request was received and understood, and that information sent back about the response is from a third party, rather than the original server. this is virtually identical in meaning to a 200 status code.
  • 204 - no content
    the 204 status code means that the request was received and understood, but that there is no need to send any data back.
  • 205 - reset content
    the 205 status code is a request from the server to the client to reset the document from which the original request was sent. for example, if a user fills out a form, and submits it, a status code of 205 means the server is asking the browser to clear the form.
  • 206 - partial content
    a status code of 206 is a response to a request for part of a document. this is used by advanced caching tools, when a user agent requests only a small part of a page, and just that section is returned.

redirection

  • 300 - multiple choices
    the 300 status code indicates that a resource has moved. the response will also include a list of locations from which the user agent can select the most appropriate.
  • 301 - moved permanently
    a status code of 301 tells a client that the resource they asked for has permanently moved to a new location. the response should also include this location. it tells the client to use the new url the next time it wants to fetch the same resource.
  • 302 - found
    a status code of 302 tells a client that the resource they asked for has temporarily moved to a new location. the response should also include this location. it tells the client that it should carry on using the same url to access this resource.
  • 303 - see other
    a 303 status code indicates that the response to the request can be found at the specified url, and should be retrieved from there. it does not mean that something has moved - it is simply specifying the address at which the response to the request can be found.
  • 304 - not modified
    the 304 status code is sent in response to a request (for a document) that asked for the document only if it was newer than the one the client already had. normally, when a document is cached, the date it was cached is stored. the next time the document is viewed, the client asks the server if the document has changed. if not, the client just reloads the document from the cache.
  • 305 - use proxy
    a 305 status code tells the client that the requested resource has to be reached through a proxy, which will be specified in the response.
  • 307 - temporary redirect
    307 is the status code that is sent when a document is temporarily available at a different url, which is also returned. there is very little difference between a 302 status code and a 307 status code. 307 was created as another, less ambiguous, version of the 302 status code.

client error

  • 400 - bad request
    a status code of 400 indicates that the server did not understand the request due to bad syntax.
  • 401 - unauthorized
    a 401 status code indicates that before a resource can be accessed, the client must be authorised by the server.
  • 402 - payment required
    the 402 status code is not currently in use, being listed as "reserved for future use".
  • 403 - forbidden
    a 403 status code indicates that the client cannot access the requested resource. that might mean that the wrong username and password were sent in the request, or that the permissions on the server do not allow what was being asked.
  • 404 - not found
    the best known of them all, the 404 status code indicates that the requested resource was not found at the url given, and the server has no idea how long for.
  • 405 - method not allowed
    a 405 status code is returned when the client has tried to use a request method that the server does not allow. request methods that are allowed should be sent with the response (common request methods are post and get).
  • 406 - not acceptable
    the 406 status code means that, although the server understood and processed the request, the response is of a form the client cannot understand. a client sends, as part of a request, headers indicating what types of data it can use, and a 406 error is returned when the response is of a type not i that list.
  • 407 - proxy authentication required
    the 407 status code is very similar to the 401 status code, and means that the client must be authorised by the proxy before the request can proceed.
  • 408 - request timeout
    a 408 status code means that the client did not produce a request quickly enough. a server is set to only wait a certain amount of time for responses from clients, and a 408 status code indicates that time has passed.
  • 409 - conflict
    a 409 status code indicates that the server was unable to complete the request, often because a file would need to be editted, created or deleted, and that file cannot be editted, created or deleted.
  • 410 - gone
    a 410 status code is the 404's lesser known cousin. it indicates that a resource has permanently gone (a 404 status code gives no indication if a resource has gine permanently or temporarily), and no new address is known for it.
  • 411 - length required
    the 411 status code occurs when a server refuses to process a request because a content length was not specified.
  • 412 - precondition failed
    a 412 status code indicates that one of the conditions the request was made under has failed.
  • 413 - request entity too large
    the 413 status code indicates that the request was larger than the server is able to handle, either due to physical constraints or to settings. usually, this occurs when a file is sent using the post method from a form, and the file is larger than the maximum size allowed in the server settings.
  • 414 - request-uri too long
    the 414 status code indicates the the url requested by the client was longer than it can process.
  • 415 - unsupported media type
    a 415 status code is returned by a server to indicate that part of the request was in an unsupported format.
  • 416 - requested range not satisfiable
    a 416 status code indicates that the server was unable to fulfill the request. this may be, for example, because the client asked for the 800th-900th bytes of a document, but the document was only 200 bytes long.
  • 417 - expectation failed
    the 417 status code means that the server was unable to properly complete the request. one of the headers sent to the server, the "expect" header, indicated an expectation the server could not meet.

server error

  • 500 - internal server error
    a 500 status code (all too often seen by perl programmers) indicates that the server encountered something it didn't expect and was unable to complete the request.
  • 501 - not implemented
    the 501 status code indicates that the server does not support all that is needed for the request to be completed.
  • 502 - bad gateway
    a 502 status code indicates that a server, while acting as a proxy, received a response from a server further upstream that it judged invalid.
  • 503 - service unavailable
    a 503 status code is most often seen on extremely busy servers, and it indicates that the server was unable to complete the request due to a server overload.
  • 504 - gateway timeout
    a 504 status code is returned when a server acting as a proxy has waited too long for a response from a server further upstream.
  • 505 - http version not supported
    a 505 status code is returned when the http version indicated in the request is no supported. the response should indicate which http versions are supported.


云自无心水自闲 2010-06-23 07:16
]]>
java comm操作串口http://www.blogjava.net/usherlight/archive/2010/06/18/323829.html云自无心水自闲云自无心水自闲fri, 18 jun 2010 09:06:00 gmthttp://www.blogjava.net/usherlight/archive/2010/06/18/323829.htmlhttp://www.blogjava.net/usherlight/comments/323829.htmlhttp://www.blogjava.net/usherlight/archive/2010/06/18/323829.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/323829.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/323829.html阅读全文

云自无心水自闲 2010-06-18 17:06
]]>
在myeclipse8.5中安装反编译插件(java decompiler)http://www.blogjava.net/usherlight/archive/2010/06/17/323676.html云自无心水自闲云自无心水自闲wed, 16 jun 2010 22:18:00 gmthttp://www.blogjava.net/usherlight/archive/2010/06/17/323676.htmlhttp://www.blogjava.net/usherlight/comments/323676.htmlhttp://www.blogjava.net/usherlight/archive/2010/06/17/323676.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/323676.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/323676.html"java decompiler"是一个非常出色的java反编译工具,详见凯发k8网页登录主页:http://java.decompiler.free.fr/

在myeclipse8.5中的安装也比较简单,下载:http://java.decompiler.free.fr/jd-eclipse/update/jdeclipse_update_site.zip
然后把这个压缩包解开放在myeclipse8.5的dropins目录下,比如:c:\programs\genuitec\myeclipse-8.5\dropins\jdeclipse_update_site
重起myeclipse就行了,第一次打开class文件,可能会稍微有一点慢,要等待一小会才会反编译出来。

好像还有点问题



云自无心水自闲 2010-06-17 06:18
]]>
windows7下可以使用的免费虚拟光驱软件http://www.blogjava.net/usherlight/archive/2010/06/16/323664.html云自无心水自闲云自无心水自闲wed, 16 jun 2010 12:08:00 gmthttp://www.blogjava.net/usherlight/archive/2010/06/16/323664.htmlhttp://www.blogjava.net/usherlight/comments/323664.htmlhttp://www.blogjava.net/usherlight/archive/2010/06/16/323664.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/323664.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/323664.htmliso, cue, nrg, mds/mdf, ccd, img




云自无心水自闲 2010-06-16 20:08
]]>
spring security - using custom authentication processing filterhttp://www.blogjava.net/usherlight/archive/2010/06/11/323293.html云自无心水自闲云自无心水自闲fri, 11 jun 2010 00:12:00 gmthttp://www.blogjava.net/usherlight/archive/2010/06/11/323293.htmlhttp://www.blogjava.net/usherlight/comments/323293.htmlhttp://www.blogjava.net/usherlight/archive/2010/06/11/323293.html#feedback0http://www.blogjava.net/usherlight/comments/commentrss/323293.htmlhttp://www.blogjava.net/usherlight/services/trackbacks/323293.html springsecurityfilterchain org.springframework.web.filter.delegatingfilterproxy springsecurityfilterchain /* request include forward if you want to externalize all of your security related configuration into a separate file, you can do so and add that to your context location param. contextconfiglocation /web-inf/beans.xml , /web-inf/springsecurity.xml now comes the part of security configuration for your application, adding the url security patterns is pretty simple and straight forward. add all the url patterns which you want to secure and add the wild card pattern at the end. you need to have some default principal and role even for non logged in users as you need to give access to pages like log in, register and forgot password kind of functionality even to non logged in users. i tried to add comments to pretty much every element which i am using here. as an example i added just a wild card intercept url which make every page of my application secure. you need to exclude different urls based on the roles. following is my custom implementation of authenticationentrypoint, which currently is not doing any thing except leveraging the commence to its super class which is the spring implementation of authenticationprocessingfilterentrypoint. i hooked it to add any custom logic. public class customauthenticationentrypoint extends authenticationprocessingfilterentrypoint { private static final log logger = logfactory.getlog(customauthenticationentrypoint.class); @override public void commence(servletrequest request, servletresponse response, authenticationexception authexception) throws ioexception, servletexception { super.commence(request, response, authexception); } } this is my custom authentication manager which actually does the custom login of the user. it will throw an badcredentialsexception in case of invalid credentials or thorws a authenticationserviceexception in case of a service error (database error, sql error or any other error). public class customauthunticationmanager implements authenticationmanager { @autowired usermanagerservice usermanagerservice; public authentication authenticate(authentication authentication) throws authenticationexception { if(stringutils.isblank((string) authentication.getprincipal()) || stringutils.isblank((string) authentication.getcredentials())){ throw new badcredentialsexception("invalid username/password"); } user user = null; grantedauthority[] grantedauthorities = null; try{ user = usermanagerservice.getuser((string) authentication.getprincipal(), (string) authentication.getcredentials()); } catch(invalidcredentialsexception ex){ throw new badcredentialsexception(ex.getmessage()); } catch(exception e){ throw new authenticationserviceexception("currently we are unable to process your request. kindly try again later."); } if (user != null) { list roles = user.getassociatedroles(); grantedauthorities = new grantedauthority[roles.size()]; for (int i = 0; i < roles.size(); i ) { role role = roles.get(i); grantedauthority authority = new grantedauthorityimpl(role.getrolecode()); grantedauthorities[i] = authority; } } else{ throw new badcredentialsexception("invalid username/password"); } return new usernamepasswordauthenticationtoken(user, authentication.getcredentials(), grantedauthorities); } } at the client side (jsp), the simple configuration you need to do is post the request to"/j_spring_security_check" with parameters "j_username" and "j_password". that's pretty much all you need to do for enabling spring security to your existing web application. i will try to explain about doing the method security using acl's and configuring the view using spring security tags in another post.

云自无心水自闲 2010-06-11 08:12
]]>
网站地图