自Java 7以来的数字证书兼容性问题

在使用JavaApns做IOS推送的时候报如下错误

javapns.communication.exceptions.
    InvalidCertificateChainException

使用Java 6和PHP就没有问题。网上粗略调查过发现是java 7以来的安全机制的问题。尝试使用如下方法解决:

使用JDK 7附带的keytool做两次转换:

.p12 到 jks:

keytool -importkeystore -destkeystore temp.jks -srckeystore src.p12 -srcstoretype PKCS12

jks 到 .p12:

keytool -importkeystore -srckeystore temp.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore dest.p12

使用新生成的p12密钥文件,一切正常。

利用Java获取网络标准时间

import java.net.*;
import java.io.*;
public class DaytimeClient
{
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		// TODO Auto-generated method stub
		String[] hostname = new String[]{"", "time.windows.com","time.nist.gov","time-nw.nist.gov","time-a.nist.gov","time-b.nist.gov"};
		int i = 1;
		boolean RecvFlag = false;
		if(args.length > 0)
		{
			hostname[0] = args[0];
			i = 0;
		}
		while(i <=5 && !RecvFlag)
		{
			try
			{
				Socket timeSocket = new Socket(hostname[i], 13);
				InputStream timeStream = timeSocket.getInputStream();
				StringBuffer time = new StringBuffer();
				int c;
				while((c=timeStream.read()) != -1)
					time.append((char)c);
				String timeString = time.toString().trim();
				System.out.println("It is " + timeString +" at " + hostname[i] +" on port " + timeSocket.getPort());
				RecvFlag = true;
				timeSocket.close();
			}
			catch(UnknownHostException e)
			{
				System.out.println("Failed to get the information from " + hostname[i]);
				System.out.println(e);
				i++;
			}
			catch(Exception e)
			{
				System.out.println("Failed to get the information from " + hostname[i]);
				System.out.println(e);
				i++;
			}
		}
		if(i == 6)
			System.out.println("Failed to get the information please check your network settings.");
		else
			System.out.println("Complete.");
	}
}

JavaApplet程序编译注意事项

首先附上一JavaApplet的Helloworld程序,及在html中的嵌入代码:
源代码路径:JavaAppletsrcHelloworld.java
JavaAppletbinJavaTest.html

import java.awt.*;
import java.applet.*;
public class HelloWorld extends Applet
{
	public void paint(Graphics g)
	{
		g.drawString("Hello World!", 5, 35);
	}
}
<HTML>
<HEAD><TITLE>JavaApplet-Text</TITLE></HEAD>
<BODY>
<applet code = "HelloWorld.class" width = 200 height = 200></applet>
</BODY>
</HTML>

要使上述代码正常运行要注意以下几点:
1、Helloworld.java编译成功后会在…bin中生成Helloworld.class文件,要将html文件同class文件放在同一目录下。若不在同一目录,则要在html中加入”codebase”代码,即

<applet code = "HelloWorld.class" codebase= "location" width = 200 height = 200></applet>

2、确保Java是最新版
3、在控制面板->程序->Java->安全设置中,把安全等级调到最低
4、不要为Helloworld创建包(package),否则要在html中指定包名。P.S.目前DS还不会指定包名=。=!

Java PrintWriter flush属性

在做当前项目的socket开发时候,按照惯例使用BufferedReader和PrintWriter做输入输出,发现使用telnet连接服务器的时候,客户端输入正常,服务器输出正常 ,但是客户端没有接收到服务器的消息。考虑过是和Flush有关的问题,依稀记得以前看到过有关PrintWriter的介绍,是在调用println等方法的时候自动flush的,于是一直没仔细研究。研究过各个方面后以及其他代码之后,又重新把目光投向flush问题上,最终也确定了是这个问题。

首先,与PrintStream不同,PrintWriter不是遇到新行(ln,或n)就flush,而是在调用println,printf或者format方法被调用的时候flush的。然而这有一个前提,就是要开启自动flush的功能。这一设定是在PrintWriter的构造函数中的,autoFlush参数指定了构造的PrintWriter对象是否自动Flush:

PrintWriter(OutputStream out, boolean autoFlush)

PrintWriter(Writer out, boolean autoFlush)

以下构造函数构造的PrintWriter对象没有自动Flush属性:

PrintWriter(OutputStream out)

PrintWriter(Writer out)

PrintWriter(File file)

PrintWriter(File file, String csn)

PrintWriter(String fileName)

PrintWriter(String fileName, String csn)

Java SQL Statement初探

前几天说到新开始的Java项目,里面使用到了Java SQLite JDBC driver,今天继续来探讨一下Java中SQL数据库的使用。

应当注意到,在java当中,SQL语句的执行是以java.sql.Statement为载体的。我们先来看Statement的方法成员。有关java.sql.Statement的文档可以在Oracle找到。

Method 方法

executeQuery

ResultSet executeQuery(String sql)
                       throws SQLException

执行指定的SQL语句并返回一个结果集对象(ResultSet);

参数:

sql – 发送给数据库的sql语句,通常是静态的SQL SELECT语句;

返回:

一个包含查询结果的ResultSet对象,永远非空;

抛出:

SQLException – 如果数据库访问错误则抛出异常,比如说在已结束的Statement中调用这个方法或者SQL语句执行结果不是一个ResultSet。

executeUpdate

int executeUpdate(String sql)
                  throws SQLException

执行指定的SQL语句,比如INSERT,UPDATE或者DELETE语句,或者说是一个不产生结果的SQL语句,比如SQL DDL语句;

参数:

sql – 一组SQL Data Manipulation Language (DML)语句,比如INSERT,UPDATE或者DELETE;再或者说是一个不产生结果的SQL语句,比如SQL DDL语句;

返回:

以下可能:
(1)SQL Data Manipulation Language (DML)语句行数;
(2)如果SQL语句执行结果没有返回值则返回0;

抛出:

SQLException – 如果数据库访问错误则抛出异常,比如说在已结束的Statement中调用这个方法或者SQL语句执行结果产生了一个ResultSet。

close

void close()
           throws SQLException

立即释放Statement对象的数据库和JDBC资源而不是等待其自动关闭。通常来说在工作完成后立即释放资源是一个好的做法以避免耗尽数据库资源。
在一个一杯关闭的Statement对象上调用此方法不会有任何效果。

备注:

当一个Statement被关闭,其当前的结果集如果存在,则也会被关闭;

抛出:

SQLException – 如果数据库访问错误则抛出异常。

Java SQLite 初探

最近开始新的项目,初步规划使用Java,以及SQLite做CS架构的应用。目前用的是SQLite JDBC Driver 3.7.2。

使用的时候,首先引用

import java.sql.*

然后连接到数据库:

java.sql.Connection connection = java.sql.DriverManager.getConnection("jdbc:sqlite:sample.db");

执行SQL语句,准备查询字符串,以及执行查询:

java.sql.Statement statement = connection.createStatement();
statement.executeUpdate("drop table if exists sample");
statement.executeUpdate("create table sample(int_1 integer, str_1 string)");
statement.executeUpdate("insert into sample values(1, 'first')");
statement.executeUpdate("insert into sample values(2, 'second')");
java.sql.ResultSet rs = statement.executeQuery("select * from sample");

从结果集中取出内容:

while(rs.next())
{
    System.out.println("string = " + rs.getString("str_1"));
    System.out.println("integer = " + rs.getInt("int_1"));
}

到此为止上述代码完成了最基础的SQL语句的执行操作,SQLite数据库和java语言环境成功地连接起来了。

然而必须要说的是,这里使用的JDBC Driver尽管实现了上述操作,达到了在java环境中使用SQLite数据库的目标,但是数据库性能真的是令人堪忧。目前我们还没有进一步的需求使用更高性能的数据库,所以依然在使用JDBC Driver,但是如果日后对数据库的要求上来了,我估计在维持java和SQLite两个选项不变的前提下,是很需要把JDBC Driver换成相应的C Wrapper的。