首页

关于java6九大新特征通过示例代码进行具体说明

标签:jdk1.6,JAXB,STAX,Compiler API,Common Annotations,JAX-WS,Scripting,jdk新特性,ScriptEngine     发布时间:2015-08-05   

一、新特征

   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@}

运行结果如下图所示

关于java6九大新特征通过示例代码进行具体说明

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@}

结果如下图所示:

关于java6九大新特征通过示例代码进行具体说明

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”

2015-08-08_134553.png

b.回车,界面提示输入密码,如输入“123456”

2015-08-08_134657.png

c.回车,打印所有输入结果

2015-08-08_134802.png

6. Common Annotations

注释Annotations本是JDK5.0里的特性,很多Java技术(如EJB,Web Services,spring-tx)都会用Annotation部分代替XML 文件来配置运行参数(或者说是支持声明式编程,如EJB的声明式事务),对于这些技术都定义一套Annotation,复用性就太差了。JDK6.0版本里面定义通用的注释Annotations,来提高通用性。

AnnotationRetentionTargetDescription
GeneratedSourceANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE用于标注生成的源代码
ResourcesRuntimeTYPE, METHOD, FIELD用于标注所依赖的资源,容器据此注入外部资源依赖,有基于字段的注入和基于setter方法的注入两种方式
ResourcesRuntimeTYPE同时标注多个外部依赖,容器会把所有这些外部依赖注入
PostConstructRuntimeMETHOD标注当容器注入所有依赖之后运行的方法,用来进行依赖注入后的初始化工作,只有一个方法可以标注为PostConstruct
PreDestroyRuntimeMETHOD当对象实例将要被从容器当中删掉之前,要执行的回调方法要标注为PreDestroy
RunAsRuntimeTYPE用于标注用什么安全角色来执行被标注类的方法,这个安全角色必须和Container 的Security角色一致的
RolesAllowedRuntimeTYPE, METHOD用于标注允许执行被标注类或方法的安全角色,这个安全角色必须和Container 的Security角色一致的
PermitAllRuntimeTYPE, METHOD允许所有角色执行被标注的类或方法
DenyAllRuntimeTYPE, METHOD不允许任何角色执行被标注的类或方法,表明该类或方法不能在Java EE容器里面运行
DeclareRolesRuntimeTYPE用来定义可以被应用程序检验的安全角色,通常用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

下面定义Web Services服务类WSProvider

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@}

运行结果如下图所示

2015-08-08_211027.png

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脚本语言,如下图所示

2015-08-08_222001.png

三、相关下载

32位windows关于jdk1.6安装版本下载,请点击下载页

上面1~9示例源码下载,请点击云盘下载

  • ◆ 相关内容