发布日期:2006 年底
新特性:
在 API 库方面的新特性显得不太多,
主要是在在 脚本,Web service,XML,编译器 API,数据库,JMX,网络和 Instrumentation 方面都有不错的新特性和功能加强。
(1)、HTTP 增强
a、 NTLM 认证
不可避免,网络中有很多资源是被安全域保护起来的。访问这些资源需要对用户的身份进行认证。
import java.net.*;
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception {
URL url = new URL("http://PROTECTED.com");
URLConnection connection = url.openConnection();
InputStream in = connection.getInputStream();
byte[] data = new byte[1024];
while(in.read(data)>0)
{
//do something for data
}
in.close();
}
}
当 Java 程序试图从一个要求认证的网站读取信息的时候,也就是说,从联系于 http://Protected.com 这个 URLConnection 的 InputStream 中 read 数据时,会引发 FileNotFoundException。Java 6 以前的版本,是不支持 NTLM 认证的。用户若想使用 HttpConnection 连接到一个使用有 Windows 域保护的网站时,是无法通过 NTLM 认证的。
Java 6 的 Authentication 类提供了对 NTLM 的支持。
class DefaultAuthenticator extends Authenticator {
private static String username = "username ";
private static String domain = "domain ";
private static String password = "password ";
public PasswordAuthentication getPasswordAuthentication() {
String usernamewithdomain = domain + "/ "+username;
return (new PasswordAuthentication(usernamewithdomain, password.toCharArray()));
}
}
Java 6 还提供了一个轻量级的纯 Java Http 服务器的实现
public static void main(String[] args) throws Exception{
HttpServerProvider httpServerProvider = HttpServerProvider.provider();
InetSocketAddress addr = new InetSocketAddress(7778);
HttpServer httpServer = httpServerProvider.createHttpServer(addr, 1);
httpServer.createContext("/myapp/", new MyHttpHandler());
httpServer.setExecutor(null);
httpServer.start();
System.out.println("started");
}
static class MyHttpHandler implements HttpHandler{
public void handle(HttpExchange httpExchange) throws IOException {
String response = "Hello world!";
httpExchange.sendResponseHeaders(200, response.length());
OutputStream out = httpExchange.getResponseBody();
out.write(response.getBytes());
out.close();
}
}
在浏览器中访问 http://localhost:7778/myapp/,我们得到:Hello world
(2) 、编译器 API
a)、JDK 6 提供了在运行时调用编译器的 API,后面我们将假设把此 API 应用在 JSP 技术中。在
传统的 JSP 技术中,服务器处理 JSP 通常需要进行下面 6 个步骤:
- 分析 JSP 代码;
- 生成 Java 代码;
- 将 Java 代码写入存储器;
- 启动另外一个进程并运行编译器编译 Java 代码;
- 将类文件写入存储器;
- 服务器读入类文件并运行。
但如果采用运行时编译,可以同时简化步骤 4 和 5,节约新进程的开销和写入存储器的输出开销,提高系统效率。
package compile;
import java.util.Date;
public class Target {
public void doSomething(){
Date date = new Date(10, 3, 3);
// 这个构造函数被标记为deprecated, 编译时会
// 向错误输出输出信息。
System.out.println("Doing...");
}
}
package compile;
import javax.tools.*;
import java.io.FileOutputStream;
public class Compiler {
public static void main(String[] args) throws Exception{
String fullQuanlifiedFileName = "compile" + java.io.File.separator +
"Target.java";
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
FileOutputStream err = new FileOutputStream("err.txt");
int compilationResult = compiler.run(null, null, err, fullQuanlifiedFileName);
if(compilationResult == 0){
System.out.println("Done");
} else {
System.out.println("Fail");
}
}
}
b)、JDK 6 的编译器 API 的另外一个强大之处在于,它可以编译的源文件的形式并不局限于文本文件。
c)、第三个新增加的功能,是收集编译过程中的诊断信息。诊断信息,通常指错误、警告或是编译过程中的详尽输出。
新安装了 JDK 6 的程序员们也许会发现,除了传统的 bin、jre 等目录,JDK 6 新增了一个名为 db 的目录。Java DB。这是一个纯 Java 实现、开源的数据库管理系统(DBMS)
public class HelloJavaDB {
public static void main(String[] args) {
try { // load the driver
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
System.out.println("Load the embedded driver");
Connection conn = null;
Properties props = new Properties();
props.put("user", "user1"); props.put("password", "user1");
//create and connect the database named helloDB
conn=DriverManager.getConnection("jdbc:derby:helloDB;create=true", props);
System.out.println("create and connect to helloDB");
conn.setAutoCommit(false);
// create a table and insert two records
Statement s = conn.createStatement();
s.execute("create table hellotable(name varchar(40), score int)");
System.out.println("Created table hellotable");
s.execute("insert into hellotable values('Ruth Cao', 86)");
s.execute("insert into hellotable values ('Flora Shi', 92)");
// list the two records
ResultSet rs = s.executeQuery(
"SELECT name, score FROM hellotable ORDER BY score");
System.out.println("name\t\tscore");
while(rs.next()) {
StringBuilder builder = new StringBuilder(rs.getString(1));
builder.append("\t");
builder.append(rs.getInt(2));
System.out.println(builder.toString());
}
// delete the table
s.execute("drop table hellotable");
System.out.println("Dropped table hellotable");
rs.close();
s.close();
System.out.println("Closed result set and statement");
conn.commit();
conn.close();
System.out.println("Committed transaction and closed connection");
try { // perform a clean shutdown
DriverManager.getConnection("jdbc:derby:;shutdown=true");
} catch (SQLException se) {
System.out.println("Database shut down normally");
}
} catch (Throwable e) {
// handle the exception
}
System.out.println("SimpleApp finished");
}
}
在 DBMS 中创建了一个名为 helloDB 的数据库;创建了一张数据表,取名为 hellotable;向表内插入了两条数据;然后,查询数据并将结果打印在控制台上;最后,删除表和数据库,释放资源。
(4)、对脚本语言的支持
javax.script
包提供的接口和类我们可以很方便为我们的 Java 应用程序添加对脚本语言的支持。
public class RunScript {
public static void main(String[] args) throws Exception {
String script = args[0];
String file = args[1];
FileReader scriptReader = new FileReader(new File(file));
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName(script);
engine.eval(scriptReader);
}
}
java RunScript javascript run.js
通过这种方式,Java 应用程序可以把一些复杂易变的逻辑过程,用更加灵活的弱类型的脚本语言来实现,然后通过 javax.Script
包提供的 API 获取运行结果,当脚本改变时,只需替换对应的脚本文件,而无需重新编译构建项目,好处是显而易见的,即节省了开发时间又提高了开发效率。