一、新特征
jdk1.6版本包括九大新特征,分别为JAXB、 STAX 、Compiler API 、Http Server 、Console控制台、Common Annotations、 Web服务元数据、JAX-WS、Scripting。
二、示例分析
1. JAXB
JAXB的全称是Java Architecture for XML Binding,实现java对象与XML格式间的转换,我们把这种映射关系简称OXM(Object XML Mapping).JDK6实现的JAXB2.0是通过JDK5版本Annotation来标识类和属性,相比1.0(JSR 31)实现更简单,其底层实现STAX(JSR173)来解析XML
测试JaxbTest主类
import java.io.FileReader;@b@import java.io.FileWriter;@b@import java.io.IOException;@b@import java.util.Calendar;@b@@b@import javax.xml.bind.JAXBContext;@b@import javax.xml.bind.JAXBException;@b@import javax.xml.bind.Marshaller;@b@import javax.xml.bind.Unmarshaller;@b@@b@public class JaxbTest {@b@ @b@ private static final String IO_FILE_XML_NAME="object.xml";@b@ @b@ /**@b@ * 将对象输出为XML文件@b@ * @param cls 对象类@b@ * @param obj 对象实例@b@ * @throws JAXBException@b@ * @throws IOException@b@ */@b@ public static void outXML(Class cls,Object obj) throws JAXBException, IOException{@b@ JAXBContext context = JAXBContext.newInstance(cls);@b@ Marshaller m = context.createMarshaller();@b@ FileWriter fw = new FileWriter(IO_FILE_XML_NAME);@b@ m.marshal(obj, fw);@b@ }@b@ @b@ /**@b@ * 解析XML为对象实例@b@ * @param cls 类对应对象类@b@ * @return 对象@b@ * @throws JAXBException@b@ * @throws IOException@b@ */@b@ public static Object parseXML(Class cls) throws JAXBException, IOException{@b@ JAXBContext context = JAXBContext.newInstance(cls);@b@ FileReader fr = new FileReader(IO_FILE_XML_NAME);@b@ Unmarshaller um = context.createUnmarshaller();@b@ return um.unmarshal(fr);@b@ }@b@ @b@ @b@@b@ public static void main(String[] args) throws JAXBException, IOException{@b@ //生成xml@b@ Student wobj=new Student("小木人","男",new Cclass("大一班","苹果","60平方"),Calendar.getInstance());@b@ outXML(Student.class,wobj);@b@ @b@ //读取之前生成xml为对象@b@ Student robj=(Student)parseXML(Student.class);@b@ System.out.println(robj.name);@b@ }@b@@b@}
学生XML实体映射关系类
import java.util.Calendar;@b@@b@import javax.xml.bind.annotation.XmlAttribute;@b@import javax.xml.bind.annotation.XmlElement;@b@import javax.xml.bind.annotation.XmlRootElement;@b@@b@@XmlRootElement@b@public class Student {@b@ @b@ @XmlAttribute@b@ String name;@b@ @b@ @XmlElement@b@ String sex;@b@ @b@ @XmlElement@b@ Cclass cclass;@b@ @b@ @XmlElement@b@ Calendar birthDay;@b@@b@ public Student() {@b@ super();@b@ }@b@@b@ public Student(String name, String sex, Cclass cclass, Calendar birthDay) {@b@ super();@b@ this.name = name;@b@ this.sex = sex;@b@ this.cclass = cclass;@b@ this.birthDay = birthDay;@b@ }@b@@b@}
学生班级XML关系映射实体类
import javax.xml.bind.annotation.XmlAttribute;@b@import javax.xml.bind.annotation.XmlElement;@b@@b@public class Cclass {@b@ @b@ @XmlAttribute@b@ String className;@b@ @b@ @XmlElement@b@ String classLogo;@b@ @b@ @XmlElement@b@ String classSize;@b@@b@ public Cclass() {@b@ super();@b@ }@b@@b@ public Cclass(String className, String classLogo, String classSize) {@b@ super();@b@ this.className = className;@b@ this.classLogo = classLogo;@b@ this.classSize = classSize;@b@ }@b@@b@}
通过JaxbTest主测试类运行结果如下:
输出“object.xml”文件内容为
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>@b@<student name="小木人">@b@ <sex>男</sex>@b@ <cclass className="大一班">@b@ <classLogo>苹果</classLogo>@b@ <classSize>60平方</classSize>@b@ </cclass>@b@ <birthDay>2015-08-06T23:20:46.641+08:00</birthDay>@b@</student>
控制台输出
小木人
2. STAX
STAX全称The Streaming API for XML,也就是JSR173(Java Specification Requests -Java 规范请求) ,除DOM和SAX外又一种解析处理XML文档的API
import java.io.FileNotFoundException;@b@import java.io.FileOutputStream;@b@import javax.xml.namespace.QName;@b@import javax.xml.stream.XMLEventReader;@b@import javax.xml.stream.XMLInputFactory;@b@import javax.xml.stream.XMLOutputFactory;@b@import javax.xml.stream.XMLStreamException;@b@import javax.xml.stream.XMLStreamWriter;@b@import javax.xml.stream.events.StartElement;@b@import javax.xml.stream.events.XMLEvent;@b@@b@public class StaxTest {@b@@b@ public static void main(String[] args) throws XMLStreamException,FileNotFoundException {@b@@b@ readXMLByStAX();// 用XMLEventReader 解析xml 文档@b@ writeXMLByStAX();// 用XMLStreamWriter 写xml文档@b@@b@ }@b@@b@ private static void readXMLByStAX() throws XMLStreamException,FileNotFoundException {@b@@b@ XMLInputFactory xmlif = XMLInputFactory.newInstance();@b@ XMLEventReader xmler = xmlif.createXMLEventReader(StaxTest.class.getResourceAsStream("/readData.xml"));@b@ XMLEvent event;@b@ @b@ StringBuffer parsingResult = new StringBuffer();@b@ while (xmler.hasNext()) {@b@ event = xmler.nextEvent();@b@ if (event.isStartElement()) { // 如果解析的是起始标记@b@ StartElement se = event.asStartElement();@b@ parsingResult.append("<");@b@ parsingResult.append(se.getName());@b@@b@ if (se.getName().getLocalPart().equals("catalog")) {@b@@b@ parsingResult.append(" id="");@b@ parsingResult.append(se.getAttributeByName(new QName("id")).getValue());@b@ parsingResult.append(""");@b@@b@ }@b@ parsingResult.append(">");@b@ } else if (event.isCharacters()) { // 如果解析的是文本内容@b@ parsingResult.append(event.asCharacters().getData());@b@ } else if (event.isEndElement()) { // 如果解析的是结束标记@b@ parsingResult.append("</");@b@ parsingResult.append(event.asEndElement().getName());@b@ parsingResult.append(">");@b@ }@b@ }@b@ System.out.println(parsingResult);@b@ }@b@@b@ private static void writeXMLByStAX() throws XMLStreamException,@b@ FileNotFoundException {@b@@b@ XMLOutputFactory xmlof = XMLOutputFactory.newInstance();@b@ XMLStreamWriter xmlw = xmlof.createXMLStreamWriter(new FileOutputStream("c:/NJ/outputData.xml"));@b@@b@ // 写入默认的XML 声明到xml文档@b@ xmlw.writeStartDocument();@b@ xmlw.writeCharacters("@b@");@b@@b@ // 写入注释到xml 文档@b@ xmlw.writeComment("测试写入");@b@ xmlw.writeCharacters("@b@");@b@@b@ // 写入一个catalogs根元素@b@ xmlw.writeStartElement("catalogs");@b@ xmlw.writeNamespace("myNS", "http://www.xwood.net/");@b@ xmlw.writeAttribute("owner", "Nj");@b@ xmlw.writeCharacters("@b@");@b@@b@ // 写入子元素catalog@b@ xmlw.writeStartElement("http://www.xwood.net/", "catalog");@b@ xmlw.writeAttribute("id", "007");@b@ xmlw.writeCharacters("Apparel");@b@@b@ // 写入catalog元素的结束标签@b@ xmlw.writeEndElement();@b@@b@ // 写入catalogs元素的结束标签@b@ xmlw.writeEndElement();@b@ // 结束XML 文档@b@ xmlw.writeEndDocument();@b@ xmlw.close();@b@@b@ }@b@@b@}
读取类根目录“readData.xml”文件,内容如下所示
<?xml version="1.0" encoding="UTF-8"?> @b@<catalogs> @b@ <catalog id="c1">知识库</catalog> @b@ <catalog id="c2">在线工具</catalog> @b@</catalogs>
控制台输出内容
<catalogs> <catalog id="c1">知识库</catalog> <catalog id="c2">在线工具</catalog></catalogs>
指定写出路径“c:/NJ/”目录下写出有文件“outputData.xml”,内容如下:
<?xml version="1.0" ?>@b@<!--测试写入-->@b@<catalogs xmlns:myNS="http://www.xwood.net/" owner="Nj">@b@ <myNS:catalog id="007">Apparel</myNS:catalog>@b@</catalogs>
3. Compiler API
JDK6定义JSR199实现动态编译Java源文件,例如我们动态修改jsp页面无需重新启动应用服务来重新装载初始化类,常用的jsp引擎容器都支持jsp页面热部署(一般通过Runtime.exec 或ProcessBuilder调用javac来重新编译),这时我们也可以借助Compiler API来实现这个过程,下面具体用示例代码说明。
动态编译器类Compiler.java
import java.io.File;@b@@b@import javax.tools.JavaCompiler;@b@import javax.tools.StandardJavaFileManager;@b@import javax.tools.ToolProvider;@b@@b@public class Compiler {@b@@b@ public static void main(String[] args) {@b@ try {@b@ JavaCompiler jc = ToolProvider.getSystemJavaCompiler();@b@ StandardJavaFileManager sjfm = jc.getStandardFileManager(null,@b@ null, null);@b@ File javaFile = new File("C:/NJ/JSPACE/modules/src/jh/modules/jdk6/Compiler/HelloWorld.java");@b@ Iterable fileObjects = sjfm.getJavaFileObjects(javaFile);@b@ jc.getTask(null, sjfm, null, null, null, fileObjects).call();@b@ sjfm.close();@b@ } catch (Exception e) {@b@ // TODO: handle exception@b@ }@b@ @b@ }@b@@b@}
测试编译类HelloWorld.java
public class HelloWorld {@b@ public String print(){@b@ return "Hello World";@b@ }@b@}
运行结果如下图所示
4. Http Server
该版本提供了轻量级Http Server API,已自定义嵌入式Http Server,用户使用时先实现HttpHandler,通过HttpExchange的对象获取用户请求HTTP报文内容,再定义响应规则内容返回,关于具体的使用,请参见下面示例代码
主HttpServer调用测试类
import java.net.InetSocketAddress;@b@import com.sun.net.httpserver.HttpServer;@b@@b@public class HttpServerMain {@b@@b@ public static void main(String[] args) {@b@ try {@b@ HttpServer server = HttpServer.create(new InetSocketAddress(8888), 0);//设置端口为8888@b@ server.createContext("/xwood", new XwoodHandler());//创建服务命名空间名字与其对应的处理器的对应关系@b@ server.setExecutor(null); //DefaultExecutor;根据用户需求进行自定义执行器@b@ server.start();@b@ } catch (Exception e) {@b@ e.printStackTrace();@b@ }@b@ }@b@}
用户自定义的处理器XwoodHandler类
import java.io.IOException;@b@import java.io.InputStream;@b@import java.io.OutputStream;@b@@b@import com.sun.net.httpserver.HttpExchange;@b@import com.sun.net.httpserver.HttpHandler;@b@@b@public class XwoodHandler implements HttpHandler {@b@@b@ @Override@b@ public void handle(HttpExchange ex) throws IOException {@b@ InputStream is =ex.getRequestBody();@b@ String response = "welcome to xwood!";@b@ ex.sendResponseHeaders(200, response.length());@b@ OutputStream os =ex.getResponseBody();@b@ os.write(response.getBytes());@b@ os.close();@b@ }@b@}
结果如下图所示:
5. Console控制台
该版本提供关于开发字符控制台的定义(java.io.Console类) ,示例如下图所示
import java.io.Console;@b@public class ConsoleTest {@b@ public static void main(String[] args) {@b@ Console console = System.console();//获得Console控制台实例@b@ if (console != null) {//判断console 是否可用@b@ String user = new String(console.readLine("Enter user:")); //读取整行字符@b@ String pwd = new String(console.readPassword("Enter passowrd:")); //读取密码,密码输入时不会显示@b@ console.printf("User is:" + user + "@b@");@b@ console.printf("Password is:" + pwd + "@b@");@b@ } else {@b@ System.out.println("Console is unavailable!!!");@b@ }@b@ }@b@}
直接在开发集成环境(如eclipse)运行,没法获取到控制台示例,会打印
Console is unavailable!!!
正常输出结果如下图所示,执行步骤a~c
a.界面提示输入用户名,输入“xwood”
b.回车,界面提示输入密码,如输入“123456”
c.回车,打印所有输入结果
6. Common Annotations
注释Annotations本是JDK5.0里的特性,很多Java技术(如EJB,Web Services,spring-tx)都会用Annotation部分代替XML 文件来配置运行参数(或者说是支持声明式编程,如EJB的声明式事务),对于这些技术都定义一套Annotation,复用性就太差了。JDK6.0版本里面定义通用的注释Annotations,来提高通用性。
Annotation | Retention | Target | Description |
Generated | Source | ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE | 用于标注生成的源代码 |
Resources | Runtime | TYPE, METHOD, FIELD | 用于标注所依赖的资源,容器据此注入外部资源依赖,有基于字段的注入和基于setter方法的注入两种方式 |
Resources | Runtime | TYPE | 同时标注多个外部依赖,容器会把所有这些外部依赖注入 |
PostConstruct | Runtime | METHOD | 标注当容器注入所有依赖之后运行的方法,用来进行依赖注入后的初始化工作,只有一个方法可以标注为PostConstruct |
PreDestroy | Runtime | METHOD | 当对象实例将要被从容器当中删掉之前,要执行的回调方法要标注为PreDestroy |
RunAs | Runtime | TYPE | 用于标注用什么安全角色来执行被标注类的方法,这个安全角色必须和Container 的Security角色一致的 |
RolesAllowed | Runtime | TYPE, METHOD | 用于标注允许执行被标注类或方法的安全角色,这个安全角色必须和Container 的Security角色一致的 |
PermitAll | Runtime | TYPE, METHOD | 允许所有角色执行被标注的类或方法 |
DenyAll | Runtime | TYPE, METHOD | 不允许任何角色执行被标注的类或方法,表明该类或方法不能在Java EE容器里面运行 |
DeclareRoles | Runtime | TYPE | 用来定义可以被应用程序检验的安全角色,通常用isUserInRole来检验安全角色 |
7. Web服务元数据
JSR-181的元数据参数说明
@WebService标注为Web Services 的类或接口@WebParam 定义服务方法参数到WSDL的映射@WebResult定义服务方法返回值到WSDL的映射@WebMethod 定义单个服务方法到WSDL的映射@Oneway 必须与@WebMethod连用,表明被标注方法只有输入没有输出,这就要求被标注方法不能有返回值,也不能声明checked exception@HandlerChain,Method,Field 将Web 服务与外部Handler chain 关联起来@SOAPBinding,Method 自定义SOAPBinding
import javax.jws.Oneway;@b@import javax.jws.WebMethod;@b@import javax.jws.WebParam;@b@import javax.jws.WebResult;@b@import javax.jws.WebService;@b@import javax.xml.ws.Endpoint;@b@@b@@WebService(targetNamespace = "http://www.xwood.net/ws", serviceName = "TestService")@b@public class WSProvider {@b@ @b@ @WebResult(name = "Hello")@b@ @WebMethod@b@ public String sayHello(@WebParam(name = "xwood") String name) {@b@ return "Hello," + name; @b@ }@b@@b@ @Oneway@b@ @WebMethod(action = "printSystemTime", operationName = "printSystemTime")@b@ public void printCurrentSysTime() {@b@ System.out.println(System.currentTimeMillis());@b@ }@b@@b@ public static void main(String[] args) {@b@ Thread wsPublisher = new Thread(new WSPublisher());@b@ wsPublisher.start();@b@ }@b@ @b@ private static class WSPublisher implements Runnable {@b@ public void run() {@b@ Endpoint.publish("http://localhost:8888/ws/WSProvider",@b@ new WSProvider());@b@ }@b@@b@ }@b@@b@}
运行结果如下图所示
8. JAX-WS
JAX-WS全称Java Architecture for XML Web Services,是结合xml实现Web Services开发框架。JDK6下通过JAX-WS2.0开发和测试Web Services的步骤
a. 编写服务类,通过上面7中的Web Services metadata标记定义的服务WSProvider类,具体参见上文7源码部分
b. 用wsgen生成上面服务类(见下面虚线框命令)或通过静态方法Endpoint.publish发布服务类
wsgen -cp . WebServices.WSProvider
c. 在客户端通过wsimport映射生成调用类,调用命令如下虚线框
wsimport http://localhost:8888/ws/WSProvider?wsdl
则在命令行运行命令后,会在当前目录生成下面类文件
TestService.class、ObjectFactory.class 、package-info.class、 printCurrentSysTime.class、 sayHello.class、sayHelloResponse.class、WSProvider.class
d. 客户端调用示例
TestService ts=new TestService();@b@WSProvider ws=ts.getWSProviderPort();@b@System.out.println(ws.sayHello("XMR"));@b@ws.printCurrentSysTime();
控制台输出结果
Hello,XMR
9. Scripting
实现在java中通过常用脚本语言(如javascript等)语法实现业务逻辑,在Javax.script中可以查找Scripting API,先通过ScriptEngineManager创建工厂对象如factory,通过工厂对象获取要创建某一种脚本的ScriptEngine 对象,通过ScriptEngine 对象的eval方法执行脚本操作
import javax.script.ScriptEngine;@b@import javax.script.ScriptEngineManager;@b@import javax.script.ScriptException;@b@@b@public class JavaScriptingTest {@b@@b@ public static void main(String[] args) {@b@ try {@b@ ScriptEngineManager factory = new ScriptEngineManager();@b@ ScriptEngine engine = factory.getEngineByName("JavaScript");@b@ engine.eval("print('Hello, JavaScript !')");@b@ } catch (ScriptException e) {@b@ // TODO Auto-generated catch block@b@ e.printStackTrace();@b@ }@b@ }@b@@b@}
控制台输出结果
Hello, JavaScript !
在JDK6的bin目录下已经提供jrunscript.exe工具,可以直接运行脚本代码,默认为JavaScript脚本语言,如下图所示
三、相关下载
32位windows关于jdk1.6安装版本下载,请点击下载页
上面1~9示例源码下载,请点击云盘下载