分类目录归档:java

maven list

pom error:  
org.apache.maven.archiver.mavenarchiver.getmanifest
:: 1.help ->Install New Software -> add
http://repo1.maven.org/maven2/.m2e/connectors/m2eclipse-mavenarchiver/0.17.2/N/LATEST/

文摘:Java各种反射性能对比

Java各种反射性能对比

对各种方法实现get方法的性能进行了一个测试。

总共有5个测试,,每个测试都是执行1亿次

1. 直接通过Java的get方法

2.通过高性能的ReflectAsm库进行测试

3.通过Java Class类自带的反射获得Method测试

4.使用Java自带的Property类获取Method测试

5.BeanUtils的getProperty测试

1 测试用Bean类

测试定义了如下一个bean类。

public class SimpleBean {
    private String name;
    public String getName() {
        return name;
    }
    public SimpleBean setName(String name) {
        this.name = name;
    }
}

注意定义要严格遵守JavaBean规范,否则在使用和反射相关工具时会出现NoSuchMethodException异常,或者导致性能非常差,JavaBean规范中最重要的几点如下:

1.类必须是public, 拥有public无参构造器,这样能够通过反射newInstance()动态构建对象.
         String className = ...;
         Class beanClass = Class.forName(className);
         Object beanInstance = beanClass.newInstance();
2.因为反射newInstance使用的是无参构造器, 所以对象实例化和配置是分开的
3.每一个property都有一个public的getter和setter方法, 命名方式是get/set+首字母大写的property名

经测试在SimpleBean为public时,1亿次调用method.invoke方法:

javaReflectGet 100000000 times using 218 ms

而SimpleBean为默认包可见时,1一亿次调用method.invoke方法:

javaReflectGet 100000000 times using 12955 ms

 

2.测试代码

public class TestIterator {
    private long times = 100_000_000L;
    private SimpleBean bean;
    private String formatter = "%s %d times using %d ms";
    @Before
    public void setUp() throws Exception {
        bean = new SimpleBean();
        bean.setName("haoyifen");
    }
    //直接通过Java的get方法
    @Test
    public void directGet() {
        Stopwatch watch = Stopwatch.createStarted();
        for (long i = 0; i < times; i++) {
            bean.getName();
        }
        watch.stop();
        String result = String.format(formatter, "directGet", times, watch.elapsed(TimeUnit.MILLISECONDS));
        System.out.println(result);
    }
    //通过高性能的ReflectAsm库进行测试,仅进行一次methodAccess获取
    @Test
    public void reflectAsmGet() {
        MethodAccess methodAccess = MethodAccess.get(SimpleBean.class);
        Stopwatch watch = Stopwatch.createStarted();
        for (long i = 0; i < times; i++) {
            methodAccess.invoke(bean, "getName");
        }
        watch.stop();
        String result = String.format(formatter, "reflectAsmGet", times, watch.elapsed(TimeUnit.MILLISECONDS));
        System.out.println(result);
    }
    //通过Java Class类自带的反射获得Method测试,仅进行一次method获取
    @Test
    public void javaReflectGet() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Method getName = SimpleBean.class.getMethod("getName");
        Stopwatch watch = Stopwatch.createStarted();
        for (long i = 0; i < times; i++) {
            getName.invoke(bean);
        }
        watch.stop();
        String result = String.format(formatter, "javaReflectGet", times, watch.elapsed(TimeUnit.MILLISECONDS));
        System.out.println(result);
    }
    //使用Java自带的Property属性获取Method测试,仅进行一次method获取
    @Test
    public void propertyGet() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, IntrospectionException {
        Method method = null;
        BeanInfo beanInfo = Introspector.getBeanInfo(SimpleBean.class);
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            if (propertyDescriptor.getName().equals("name")) {
                method = propertyDescriptor.getReadMethod();
                break;
            }
        }
        Stopwatch watch = Stopwatch.createStarted();
        for (long i = 0; i < times; i++) {
           
            method.invoke(bean);
        }
        watch.stop();
        String result = String.format(formatter, "propertyGet", times, watch.elapsed(TimeUnit.MILLISECONDS));
        System.out.println(result);
    }
    //BeanUtils的getProperty测试
    @Test
    public void beanUtilsGet() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Stopwatch watch = Stopwatch.createStarted();
        for (long i = 0; i < times; i++) {
            BeanUtils.getProperty(bean, "name");
        }
        watch.stop();
        String result = String.format(formatter, "beanUtilsGet", times, watch.elapsed(TimeUnit.MILLISECONDS));
        System.out.println(result);
    }
}

3.测试结果

在4核i5-4590@3.30GHz机器上跑以上测试,经过多次测量,基本在以下数值范围附近,测试数据如下:

1. directGet 100000000 times using 37 ms

2. reflectAsmGet 100000000 times using 39 ms

3. javaReflectGet 100000000 times using 222 ms

4. propertyGet 100000000 times using 335 ms

5. beanUtilsGet 100000000 times using 20066 ms

4.结果分析

1.使用reflectAsm库的性能能和直接调用get方法持平

2.Java自带的反射性能大致为直接get的1/6和1/9.

3.BeanUtils的getProperty非常的慢,为直接get性能的1/500,为Java自带反射性能的1/100和1/60.

 

为什么BeanUtils的getProperty方法性能这么慢?

...

摘自:https://www.cnblogs.com/Frank-Hao/p/5839096.html

参考:

https://blog.csdn.net/cike110120/article/details/51163668

https://blog.csdn.net/leixingbang1989/article/details/52035336

 

 

 

 

 

ByteBuffer

概述

ByteBuffer是NIO里用得最多的Buffer,它包含两个实现方式:HeapByteBuffer是基于Java堆的实现,而DirectByteBuffer则使用了unsafe的API进行了堆外的实现。这里只说HeapByteBuffer。

使用

ByteBuffer最核心的方法是put(byte)get()。分别是往ByteBuffer里写一个字节,和读一个字节。

值得注意的是,ByteBuffer的读写模式是分开的,正常的应用场景是:往ByteBuffer里写一些数据,然后flip(),然后再读出来。

这里插两个Channel方面的对象,以便更好的理解Buffer。

ReadableByteChannel是一个从Channel中读取数据,并保存到ByteBuffer的接口,它包含一个方法:

public intread(ByteBuffer dst) throwsIOException;

WritableByteChannel则是从ByteBuffer中读取数据,并输出到Channel的接口:

public intwrite(ByteBuffer src) throwsIOException;

那么,一个ByteBuffer的使用过程是这样的:

1. byteBuffer = ByteBuffer.allocate(N);    //创建

2. readableByteChannel.read(byteBuffer);   //读取数据,写入byteBuffer

3. byteBuffer.flip();              //变读为写

4. writableByteChannel.write(byteBuffer);   //读取byteBuffer,写入数据

看到这里,一般都不太明白flip()干了什么事,先从ByteBuffer结构说起:

 

ByteBuffer的创建和读写

 

1. ByteBuffer定义了4个static方法来做创建工作:

ByteBuffer allocate(int capacity) //创建一个指定capacity的ByteBuffer。
ByteBuffer allocateDirect(int capacity) //创建一个direct的ByteBuffer,这样的ByteBuffer在参与IO操作时性能会更好
ByteBuffer wrap(byte [] array)
ByteBuffer wrap(byte [] array, int offset, int length) //把一个byte数组或byte数组的一部分包装成ByteBuffer。

2. ByteBuffer定义了一系列get和put操作来从中读写byte数据,如下面几个:
byte get()
ByteBuffer get(byte [] dst)
byte get(int index)
ByteBuffer put(byte b)
ByteBuffer put(byte [] src)
ByteBuffer put(int index, byte b)
这些操作可分为绝对定位和相对定为两种,相对定位的读写操作依靠position来定位Buffer中的位置,并在操
作完成后会更新position的值。在其它类型的buffer中,也定义了相同的函数来读写数据,唯一不同的就是一
些参数和返回值的类型。

3. 除了读写byte类型数据的函数,ByteBuffer的一个特别之处是它还定义了读写其它primitive数据的方法,如:

int getInt()             //从ByteBuffer中读出一个int值。
ByteBuffer putInt(int value)  // 写入一个int值到ByteBuffer中。

3.1 字节序

读写其它类型的数据牵涉到字节序问题,ByteBuffer会按其字节序(大字节序或小字节序)写入或读出一个其它
类型的数据(int,long…)。字节序可以用order方法来取得和设置:
ByteOrder order() //返回ByteBuffer的字节序。
ByteBuffer order(ByteOrder bo)   // 设置ByteBuffer的字节序。

3.2 ByteOrder
用来表示ByteBuffer字节序的类,可将其看成java中的enum类型。主要定义了下面几个static方法和属性:
ByteOrder BIG_ENDIAN       代表大字节序的ByteOrder。
ByteOrder LITTLE_ENDIAN 代表小字节序的ByteOrder。
ByteOrder nativeOrder()       返回当前硬件平台的字节序。

 

4. ByteBuffer另一个特别的地方是可以在它的基础上得到其它类型的buffer。如:
CharBuffer asCharBuffer()
为当前的ByteBuffer创建一个CharBuffer的视图。在该视图buffer中的读写操作会按照ByteBuffer的字节
序作用到ByteBuffer中的数据上。

用这类方法创建出来的buffer会从ByteBuffer的position位置开始到limit位置结束,可以看作是这段数据
的视图。视图buffer的readOnly属性和direct属性与ByteBuffer的一致,而且也只有通过这种方法,才可
以得到其他数据类型的direct buffer。

ByteBuffer内部字段

byte[] buff

buff即内部用于缓存的数组。

position

当前读取的位置。

读/写操作的当前下标。当使用buffer的相对位置进行读/写操作时,读/写会从这个下标进行,并在操作完成后,
buffer会更新下标的值。

mark

为某一读过的位置做标记,便于某些时候回退到该位置。

一个临时存放的位置下标。调用mark()会将mark设为当前的position的值,以后调用reset()会将position属性设
置为mark的值。mark的值总是小于等于position的值,如果将position的值设的比mark小,当前的mark值会被抛弃掉。

capacity

初始化时候的容量。

这个Buffer最多能放多少数据。capacity一般在buffer被创建的时候指定。

limit

在Buffer上进行的读写操作都不能越过这个下标。当写数据到buffer中时,limit一般和capacity相等,当读数据时,
limit代表buffer中有效数据的长度。

读写的上限,limit<=capacity。

 

这些属性总是满足以下条件:
0 <= mark <= position <= limit <= capacity

limit和position的值除了通过limit()和position()函数来设置,也可以通过下面这些函数来改变:

Buffer clear()
把position设为0,把limit设为capacity,一般在把数据写入Buffer前调用。

Buffer flip()
把limit设为当前position,把position设为0,一般在从Buffer读出数据前调用。

Buffer rewind()
把position设为0,limit不变,一般在把数据重写入Buffer前调用。

compact()

该方法的作用是将 position 与 limit之间的数据复制到buffer的开始位置,复制后 position  = limit -position,limit = capacity

但如果position 与limit 之间没有数据的话发,就不会进行复制  详细参考:java nio Buffer 中 compact的作用

mark()与reset()方法

  通过调用Buffer.mark()方法,可以标记Buffer中的一个特定position。之后可以通过调用Buffer.reset()方法恢复到这个position。例如:

1.buffer.mark();

2.//call buffer.get() a couple of times, e.g. during parsing.

3.buffer.reset(); //set position back to mark

equals()与compareTo()方法

  可以使用equals()和compareTo()方法两个Buffer。

  equals()

  当满足下列条件时,表示两个Buffer相等:

  1. 有相同的类型(byte、char、int等)。
  2. Buffer中剩余的byte、char等的个数相等。
  3. Buffer中所有剩余的byte、char等都相同。

如你所见,equals只是比较Buffer的一部分,不是每一个在它里面的元素都比较。实际上,它只比较Buffer中的剩余元素。

  compareTo()方法

  compareTo()方法比较两个Buffer的剩余元素(byte、char等), 如果满足下列条件,则认为一个Buffer“小于”另一个Buffer:

    1. 第一个不相等的元素小于另一个Buffer中对应的元素 。
    2. 所有元素都相等,但第一个Buffer比另一个先耗尽(第一个Buffer的元素个数比另一个少)。

Buffer对象有可能是只读的,这时,任何对该对象的写操作都会触发一个ReadOnlyBufferException。
isReadOnly()方法可以用来判断一个Buffer是否只读。

 

图解

put

写模式下,往buffer里写一个字节,并把postion移动一位。写模式下,一般limit与capacity相等。

flip

写完数据,需要开始读的时候,将postion复位到0,并将limit设为当前postion。

get

从buffer里读一个字节,并把postion移动一位。上限是limit,即写入数据的最后位置。

clear

将position置为0,并不清除buffer内容。

mark相关的方法主要是mark()(标记)和reset()(回到标记)

 

.

原文: https://www.cnblogs.com/ruber/p/6857159.html

 

 

[netty] ByteBuf

netty 中的 ByteBuf 默认是使用 big-endian
一、创建
1、池化创建 ByteBufAllocator
获取ByteBufAllocator
Channel channel = ...;
ByteBufAllocator allocator = channel.alloc();
//1....ChannelHandlerContext ctx = ...;
ByteBufAllocator allocator2 = ctx.alloc();
//2
ByteBufAllocator中创建byteBuf的方法
名称
描述
buffer() buffer(int) buffer(int, int)
Return a ByteBuf with heap-based or direct data storage.
heapBuffer() heapBuffer(int) heapBuffer(int, int)
Return a ByteBuf with heap-based storage.
directBuffer() directBuffer(int) directBuffer(int, int)
Return a ByteBuf with direct storage.
compositeBuffer() compositeBuffer(int) heapCompositeBuffer() heapCompositeBuffer(int) directCompositeBuffer()directCompositeBuffer(int)
Return a CompositeByteBuf that can be expanded by adding heapbased or direct buffers.
ioBuffer()
Return a ByteBuf that will be used for I/O operations on a socket.
2、Unpooled (非池化)缓存
当未引用 ByteBufAllocator 时,上面的方法无法访问到 ByteBuf。对于这个用例 Netty 提供一个实用工具类称为 Unpooled,,它提供了静态辅助方法来创建非池化的 ByteBuf 实例。表5.9列出了最重要的方法
Table 5.9 Unpooled helper class
名称
描述
buffer() buffer(int) buffer(int, int)
Returns an unpooled ByteBuf with heap-based storage
directBuffer() directBuffer(int) directBuffer(int, int)
Returns an unpooled ByteBuf with direct storage
wrappedBuffer()
Returns a ByteBuf, which wraps the given data.
copiedBuffer()
Returns a ByteBuf, which copies the given data
在 非联网项目,该 Unpooled 类也使得它更容易使用的 ByteBuf API,获得一个高性能的可扩展缓冲 API,
3、ByteBufUtil创建 (ByteBufUtil中有很多操作buf的API)
二、读 get/read get不会改变读索引,read会改变读索引
getBoolean(int)
返回当前索引的 Boolean 值
getByte(int) getUnsignedByte(int)
返回当前索引的(无符号)字节
getMedium(int) getUnsignedMedium(int)
返回当前索引的 (无符号) 24-bit 中间值
getInt(int) getUnsignedInt(int)
返回当前索引的(无符号) 整型
getLong(int) getUnsignedLong(int)
返回当前索引的 (无符号) Long 型
getShort(int) getUnsignedShort(int)
返回当前索引的 (无符号) Short 型
getBytes(int, ...)
字节
方法名称
描述
readBoolean()
 返回当前索引的Boolean值,读索引加一
readByte()
readUnsignedByte()
返回当前索引的(无符号)字节,读索引加一
readMedium()
readUnsignedMedium()
返回当前索引的 (无符号) 24-bit 中间值,读索引加3
readInt()
readUnsignedInt()
 返回当前索引的(无符号) 整型,读索引加4
readLong()
readUnsignedLong()
 返回当前索引的 (无符号) Long 型,读索引加8
readShort()
readUnsignedShort()
返回当前索引的 (无符号) Short 型,读索引加2
readBytes(int,int, ...)
、放回当前位置到length
得一个字节数组,读索引加length
三、写操作 set/write
方法名称
描述
setBoolean(int, boolean)
在指定的索引位置设置 Boolean 值
setByte(int, int)
在指定的索引位置设置 byte 值
setMedium(int, int)
在指定的索引位置设置 24-bit 中间 值
setInt(int, int)
在指定的索引位置设置 int 值
setLong(int, long)
在指定的索引位置设置 long 值
setShort(int, int)
在指定的索引位置设置 short 值
方法名称
描述
writeBoolean(boolean)
在指定的索引位置设置 Boolean 值,写索引加一
writeByte(int)
在指定的索引位置设置 byte 值,写索引加一
writeMedium(int)
在指定的索引位置设置 24-bit 中间 值,写索引加3
writeInt(int)
在指定的索引位置设置 int 值,写索引加4
writeLong(long)
在指定的索引位置设置 long 值,写索引加8
writeShort(int)
在指定的索引位置设置 short 值,写索引加2
writeBytes(int,...)
 在当前索引写入一个Byte数组,写索引加数组长度
四、索引管理
markReaderIndex(),
 markWriterIndex()
标记读(写)索引
resetReaderIndex()
resetWriterIndex()
读(写)索引回到mark标记的索引值
readerIndex(int)
 writerIndex(int)
将读(写)索引设置到指定位置
clear()
可以同时设置 readerIndex 和 writerIndex 为 0。这不会清除内存中的内容
五、查找
forEachByte(ByteBufProcessor.FIND_NUL)
查找byte,返回byte的索引
六、副本
duplicate()
slice()
slice(int, int)
readOnly(),
order(ByteOrder)
所有这些都返回一个新的 ByteBuf 实例包括它自己的 reader, writer 和标记索引。然而,内部数据存储共享就像在一个 NIO 的 ByteBuffer
 copy()
 copy(int, int)
返回的 ByteBuf 有数据的独立副本。
七、其他
方法名称
描述
isReadable()
返回是否有字节可读
isWritable()
返回是否可以写
readableBytes()
返回可以读的字节长度
writablesBytes()
返回可以写的字节场地
capacity()
返回byteBuf的容量
maxCapacity()
返回byteBuf可以有的最大容量
hasArray()
如果byteBuf可以直接返回一个数组就返回true
(heap buf才会为true)
array()
hasArray返回true,该方法就会返回一个数组
.

SpringMVC 注解与绑定

系统提供的常用注解清单:

1、@RequestParam绑定单个请求参数值;

2、@PathVariable绑定URI模板变量值;

3、@CookieValue绑定Cookie数据值;

4、@RequestHeader绑定请求头数据;

5、@ModelAttribute绑定参数到命令对象;

6、@SessionAttributes绑定命令对象到session;

7、@RequestBody绑定请求的内容区数据并能进行自动类型转换等。

8、@RequestPart绑定“multipart/data”数据,除了能绑定@RequestParam能做到的请求参数外,还能绑定上传的文件等。

除上述提到的注解,我们还可以通过如HttpServletRequest等API得到请求数据。

图示:

 

@RequestMapping

RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

RequestMapping注解有六个属性,下面我们把她分成三类进行说明(下面有相应示例)。

1、 value, method;

value:     指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);

method:  指定请求的method类型, GET、POST、PUT、DELETE等;

2、consumes,produces

consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;

produces:    指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;

3、params,headers

params: 指定request中必须包含某些参数值是,才让该方法处理。

headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。

 

@Resource和@Autowired

@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。

 

@ModelAttribute和 @SessionAttributes

代表的是:该Controller的所有方法在调用前,先执行此@ModelAttribute方法,可用于注解和方法参数中,可以把这个@ModelAttribute特性,应用在BaseController当中,所有的Controller继承BaseController,即可实现在调用Controller时,先执行@ModelAttribute方法。

@PathVariable

用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数

@RequestParam

@requestParam主要用于在SpringMVC后台控制层获取参数,类似一种是request.getParameter("name"),它有三个常用参数:defaultValue = "0", required = false, value = "isApp";defaultValue 表示设置默认值,required 铜过boolean设置是否是必须要传入的参数,value 值表示接受的传入的参数类型。

@ResponseBody

作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。

使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;

@Component

相当于通用的注解,当不知道一些类归到哪个层时使用,但是不建议。

@Repository

用于注解dao层,在daoImpl类上面注解。

 

 

 

使用 ServletRequest/HttpServletRequest 和 ServletResponse/HttpServletResponse:

public String requestOrResponse (
ServletRequest servletRequest, HttpServletRequest httpServletRequest,
ServletResponse servletResponse, HttpServletResponse httpServletResponse
)

 

使用 InputStream/OutputStream:

public void inputOrOutBody(InputStream requestBodyIn, OutputStream responseBodyOut)
throws IOException {
responseBodyOut.write("success".getBytes());
}

requestBodyIn:获取请求的内容区字节流,等价于request.getInputStream()
responseBodyOut:获取相应的内容区字节流,等价于response.getOutputStream()

 

使用 Reader/Writer:

public void readerOrWriteBody(Reader reader, Writer writer)
throws IOException {
writer.write("hello");
}

 

使用 @RequestParam/@SessionAttributes/@CookieValue:

public void readerOrWriteBody(@RequestParam String uid, @SessionAttributes String uid){}

 

参考:

https://www.cnblogs.com/leskang/p/5445698.html

..

 

 

 

Java常用Json库性能对比

Java对于处理JSON数据的序列化与反序列化目前常用的类库有Gson、FastJSON、Jackson、jettison以及json-lib。在这里我们将对这些类库在json序列化与反序列化方面的性能进行测试对比。

个例测试,仅供参考。

 

测试环境如下:

电脑:cpu为I3-4160,Win7 64位系统

编译环境:jdk1.8.0_65,Myeclipse2014

各类库版本:gson-2.6.2、fastjson-1.2.8、jackson -2.7.2、jettison-1.3.7(2014年后无更新)、json-lib-2.4(2012年后停止更新)

 

序列化的简单对象:

publicclass User {

    intid;

    String name;

    intage;

    String address;

    //get、set

}

测试结果

序列化测试结果(Object->String),耗时单位均为ms

测试次数

类库

100

1K

1W

10W

50W

100W

1000W

gson

8

25

63

230

680

1100

7790

fastjson

85

100

155

200

270

350

1850

jackson

35

48

80

150

255

360

2400

Json-lib

75

130

280

910

2725

4900

42500

jettison

70

85

110

210

400

590

4000

反序列化测试结果(String->Object),耗时单位均为ms

测试次数

类库

100

1K

1W

10W

50W

100W

1000W

gson

9

21

60

195

570

950

7760

fastjson

85

105

150

225

370

545

3800

jackson

36

50

110

210

380

570

4460

Json-lib

86

185

405

1180

2950

4850

38300

jettison

6

20

50

230

460

710

4650

测试总结:

1、从测试结果可以看出gson在小于10w的数据量处理上,耗时相对较少,但是在数据越来越大的情况下耗时会明显的增长。

2无论那种情况下,json-lib的耗时都是最多的,引用时还需要额外几个依赖包,且目前已经停止了更新,所以不推荐使用。

3、jackson在各阶段数据量都有很不错的性能,而fastjson在数据量较多的情况下也有很好性能。

4、jettison性能不错,但只提供json和其JSONObject对象相互转化的方法,转为自定义bean时需要再手动将JSONObject对象转为需要的bean。

文章来源: https://www.cnblogs.com/aurain/p/6734873.html

Java/Android RSA使用时注意补位

java

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 

android

Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding"); 

参考:
 
http://stackoverflow.com/questions/6069369/rsa-encryption-difference-between-java-and-android
http://stackoverflow.com/questions/2956647/rsa-encrypt-with-base64-encoded-public-key-in-android

java base64

代码来源于网络

import java.io.UnsupportedEncodingException;  

public class Base64Utils  
{  
    private static char[] base64EncodeChars = new char[]  
    { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',  
            'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',  
            'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',  
            '6', '7', '8', '9', '+', '/' };  
    private static byte[] base64DecodeChars = new byte[]  
    { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53,  
            54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,  
            12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29,  
            30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1,  
            -1, -1, -1 };  
 
    /**
     * 加密
     *  
     * @param data
     * @return
     */  
    public static String encode(byte[] data)  
    {  
        StringBuffer sb = new StringBuffer();  
        int len = data.length;  
        int i = 0;  
        int b1, b2, b3;  
        while (i < len)  
        {  
            b1 = data[i++] & 0xff;  
            if (i == len)  
            {  
                sb.append(base64EncodeChars[b1 >>> 2]);  
                sb.append(base64EncodeChars[(b1 & 0x3) << 4]);  
                sb.append("==");  
                break;  
            }  
            b2 = data[i++] & 0xff;  
            if (i == len)  
            {  
                sb.append(base64EncodeChars[b1 >>> 2]);  
                sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);  
                sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);  
                sb.append("=");  
                break;  
            }  
            b3 = data[i++] & 0xff;  
            sb.append(base64EncodeChars[b1 >>> 2]);  
            sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);  
            sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);  
            sb.append(base64EncodeChars[b3 & 0x3f]);  
        }  
        return sb.toString();  
    }  
 
    /**
     * 解密
     *  
     * @param str
     * @return
     */  
    public static byte[] decode(String str)  
    {  
        try  
        {  
            return decodePrivate(str);  
        } catch (UnsupportedEncodingException e)  
        {  
            e.printStackTrace();  
        }  
        return new byte[]  
        {};  
    }  
 
    private static byte[] decodePrivate(String str) throws UnsupportedEncodingException  
    {  
        StringBuffer sb = new StringBuffer();  
        byte[] data = null;  
        data = str.getBytes("US-ASCII");  
        int len = data.length;  
        int i = 0;  
        int b1, b2, b3, b4;  
        while (i < len)  
        {  
 
            do  
            {  
                b1 = base64DecodeChars[data[i++]];  
            } while (i < len && b1 == -1);  
            if (b1 == -1)  
                break;  
 
            do  
            {  
                b2 = base64DecodeChars[data[i++]];  
            } while (i < len && b2 == -1);  
            if (b2 == -1)  
                break;  
            sb.append((char) ((b1 << 2) | ((b2 & 0x30) >>> 4)));  
 
            do  
            {  
                b3 = data[i++];  
                if (b3 == 61)  
                    return sb.toString().getBytes("iso8859-1");  
                b3 = base64DecodeChars[b3];  
            } while (i < len && b3 == -1);  
            if (b3 == -1)  
                break;  
            sb.append((char) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2)));  
 
            do  
            {  
                b4 = data[i++];  
                if (b4 == 61)  
                    return sb.toString().getBytes("iso8859-1");  
                b4 = base64DecodeChars[b4];  
            } while (i < len && b4 == -1);  
            if (b4 == -1)  
                break;  
            sb.append((char) (((b3 & 0x03) << 6) | b4));  
        }  
        return sb.toString().getBytes("iso8859-1");  
    }  
 

...