JDOM是一个开源项目,它基于树型结构,利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作。

一、JDOM 简介

JDOM是一个开源项目,它基于树型结构,利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作。

JDOM 直接为JAVA编程服务。它利用更为强有力的JAVA语言的诸多特性(方法重载、集合概念以及映射),把SAX和DOM的功能有效地结合起来。

在使用设计上尽可能地隐藏原来使用XML过程中的复杂性。利用JDOM处理XML文档将是一件轻松、简单的事。

JDOM 在2000年的春天被Brett McLaughlin和Jason Hunter开发出来,以弥补DOM及SAX在实际应用当中的不足之处。

这些不足之处主要在于SAX没有文档修改、随机访问以及输出的功能,而对于DOM来说,JAVA程序员在使用时来用起来总觉得不太方便。

DOM的缺点主要是来自于由于Dom是一个接口定义语言(IDL),它的任务是在不同语言实现中的一 个最低的通用标准,并不是为JAVA特别设计的。JDOM的最新版本为JDOM Beta 9。最近JDOM被收录到JSR-102内,这标志着JDOM成为了JAVA平台组成的一部分。

二、JDOM 包概览

JDOM是由以下几个包组成的
org.jdom                包含了所有的xml文档要素的java类

 

org.jdom.adapters         包含了与dom适配的java类

 

org.jdom.filter            包含了xml文档的过滤器类

 

org.jdom.input            包含了读取xml文档的类

 

org.jdom.output           包含了写入xml文档的类

 

org.jdom.transform        包含了将jdom xml文档接口转换为其他xml文档接口

 

org.jdom.xpath            包含了对xml文档xpath操作的类三、JDOM 类说明

1、org.JDOM这个包里的类是你J解析xml文件后所要用到的所有数据类型。

Attribute

CDATA

Coment

DocType

Document

Element

EntityRef

Namespace

ProscessingInstruction

Text

2、org.JDOM.transform在涉及xslt格式转换时应使用下面的2个类

JDOMSource

JDOMResult

org.JDOM.input

3、输入类,一般用于文档的创建工作

SAXBuilder

DOMBuilder

ResultSetBuilder

org.JDOM.output

4、输出类,用于文档转换输出

XMLOutputter

SAXOutputter

DomOutputter

JTreeOutputter

使用前注意事项:

1.JDOM对于JAXP 以及 TRax 的支持

JDOM 支持JAXP1.1:你可以在程序中使用任何的parser工具类,默认情况下是JAXP的parser。

制定特别的parser可用如下形式

SAXBuilder parser

  = new SAXBuilder("org.apache.crimson.parser.XMLReaderImpl");

 Document doc = parser.build("http://www.cafeconleche.org/");

 // work with the document...

JDOM也支持TRaX:XSLT可通过JDOMSource以及JDOMResult类来转换(参见以后章节)

2.注意在JDOM里文档(Document)类由org.JDOM.Document 来表示。这要与org.w3c.dom中的Document区别开,这2种格式如何转换在后面会说明。

以下如无特指均指JDOM里的Document。

四、JDOM主要使用方法

1.Ducument类

(1)Document的操作方法:

Element root = new Element("GREETING");

Document doc = new Document(root);

root.setText("Hello JDOM!");

或者简单的使用Document doc = new Document(new Element("GREETING").setText("Hello JDOM!t"));

这点和DOM不同。Dom则需要更为复杂的代码,如下:

DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();

DocumentBuilder builder =factory.newDocumentBuilder();

Document doc = builder.newDocument();

Element root =doc.createElement("root");

Text text = doc.createText("This is the root");

root.appendChild(text);

doc.appendChild(root);

注意事项:JDOM不允许同一个节点同时被2个或多个文档相关联,要在第2个文档中使用原来老文档中的节点的话。首先需要使用detach()把这个节点分开来。

(2)从文件、流、系统ID、URL得到Document对象:

DOMBuilder builder = new DOMBuilder();

Document doc = builder.build(new File("jdom_test.xml"));

SAXBuilder builder = new SAXBuilder();

Document doc = builder.build(url);

在新版本中DOMBuilder 已经Deprecated掉 DOMBuilder.builder(url),用SAX效率会比较快。

这里举一个小例子,为了简单起见,使用String对象直接作为xml数据源:

 public jdomTest() {

    String textXml = null;

    textXml = "<note>";

    textXml = textXml +

        "<to>aaa</to><from>bbb</from><heading>ccc</heading><body>ddd</body>";

    textXml = textXml + "</note>";

    SAXBuilder builder = new SAXBuilder();

    Document doc = null;

    Reader in= new StringReader(textXml);

    try {

      doc = builder.build(in);

      Element root = doc.getRootElement();

      List ls = root.getChildren();//注意此处取出的是root节点下面的一层的Element集合

      for (Iterator iter = ls.iterator(); iter.hasNext(); ) {

        Element el = (Element) iter.next();

        if(el.getName().equals("to")){

         System.out.println(el.getText());

        }

      }

    }

    catch (IOException ex) {

      ex.printStackTrace();

    }

    catch (JDOMException ex) {

      ex.printStackTrace();

    }

  }

(3)DOM的document和JDOM的Document之间的相互转换使用方法,简单!

DOMBuilder builder = new DOMBuilder();

org.jdom.Document jdomDocument = builder.build(domDocument);

DOMOutputter converter = new DOMOutputter();// work with the JDOM document…

org.w3c.dom.Document domDocument = converter.output(jdomDocument);

// work with the DOM document…

2.XML文档输出

XMLOutPutter类:

JDOM的输出非常灵活,支持很多种io格式以及风格的输出

Document doc = new Document(...);

XMLOutputter outp = new XMLOutputter();

outp.output(doc, fileOutputStream); // Raw output

outp.setTextTrim(true); // Compressed output

outp.output(doc, socket.getOutputStream());

outp.setIndent(" ");// Pretty output

outp.setNewlines(true);

outp.output(doc, System.out);

详细请参阅最新的JDOM API手册

3.Element 类:

(1)浏览Element树

Element root = doc.getRootElement();//获得根元素element

List allChildren = root.getChildren();// 获得所有子元素的一个list

List namedChildren = root.getChildren("name");// 获得指定名称子元素的list

Element child = root.getChild("name");//获得指定名称的第一个子元素

JDOM给了我们很多很灵活的使用方法来管理子元素(这里的List是java.util.List)

List allChildren = root.getChildren();

allChildren.remove(3); // 删除第四个子元素

allChildren.removeAll(root.getChildren("jack"));// 删除叫“jack”的子元素

root.removeChildren("jack"); // 便捷写法

allChildren.add(new Element("jane"));// 加入

root.addContent(new Element("jane")); // 便捷写法

allChildren.add(0, new Element("first"));

(2)移动Elements:

在JDOM里很简单

Element movable = new Element("movable");

parent1.addContent(movable); // place

parent1.removeContent(movable); // remove

parent2.addContent(movable); // add

在Dom里

Element movable = doc1.createElement("movable");

parent1.appendChild(movable); // place

parent1.removeChild(movable); // remove

parent2.appendChild(movable); // 出错!

补充:纠错性

JDOM的Element构造函数(以及它的其他函数)会检查element是否合法。

而它的add/remove方法会检查树结构,检查内容如下:

1.在任何树中是否有回环节点

2.是否只有一个根节点

3.是否有一致的命名空间(Namespaces)

(3)Element的text内容读取

<description>

A cool demo

</description>

// The text is directly available

// Returns "\n A cool demo\n"

String desc = element.getText();

// There's a convenient shortcut

// Returns "A cool demo"

String desc = element.getTextTrim();

(4)Elment内容修改

element.setText("A new description");

3.可正确解释特殊字符

element.setText("<xml> content");

4.CDATA的数据写入、读出

element.addContent(new CDATA("<xml> content"));

String noDifference = element.getText();

混合内容

element可能包含很多种内容,比如说

<table>

<!-- Some comment -->

Some text

<tr>Some child element</tr>

</table>

取table的子元素tr

String text = table.getTextTrim();

Element tr = table.getChild("tr");

也可使用另外一个比较简单的方法

List mixedCo = table.getContent();

Iterator itr = mixedCo.iterator();

while (itr.hasNext()) {

Object o = i.next();

if (o instanceof Comment) {...}

// 这里可以写成Comment, Element, Text, CDATA,ProcessingInstruction, 或者是EntityRef的类型

}

// 现在移除Comment,注意这里游标应为1。这是由于回车键也被解析成Text类的缘故,所以Comment项应为1。

mixedCo.remove(1);

4.Attribute类

<table width="100%" border="0"> </table>

String width = table.getAttributeValue("width");//获得attribute

int border = table.getAttribute("width").getIntValue();

table.setAttribute("vspace", "0");//设置attribute

table.removeAttribute("vspace");// 删除一个或全部attribute

table.getAttributes().clear();

5.处理指令(Processing Instructions)操作

一个Pls的例子

<?br?>

<?cocoon-process type="xslt"?>

          |        |

          |        |

        目标     数据

处理目标名称(Target)

String target = pi.getTarget();

获得所有数据(data),在目标(target)以后的所有数据都会被返回。

String data = pi.getData();

String type = pi.getValue("type");获得指定属性的数据

List ls = pi.getNames();获得所有属性的名称

6.命名空间操作

<xhtml:html

 xmlns:xhtml="http://www.w3.org/1999/xhtml">

<xhtml:title>Home Page</xhtml:title>

</xhtml:html>

Namespace xhtml = Namespace.getNamespace("xhtml", "http://www.w3.org/1999/xhtml");

List kids = html.getChildren("title", xhtml);

Element kid = html.getChild("title", xhtml);

kid.addContent(new Element("table", xhtml));

7.XSLT格式转换

使用以下函数可对XSLT转换

最后如果你需要使用w3c的Document则需要转换一下。

public static Document transform(String stylesheet,Document in)

                                        throws JDOMException {

     try {

       Transformer transformer = TransformerFactory.newInstance()

                             .newTransformer(new StreamSource(stylesheet));

       JDOMResult out = new JDOMResult();

       transformer.transform(new JDOMSource(in), out);

       return out.getDeocument();

     }

     catch (TransformerException e) {

       throw new JDOMException("XSLT Trandformation failed", e);

     }

   }

五、用例:

1、生成xml文档:

 

 

public class WriteXML{

    public void BuildXML() throws Exception {

        Element root,student,number,name,age;        

        root = new Element("student-info"); //生成根元素:student-info

        student = new Element("student"); //生成元素:student(number,name,age)                            

        number = new Element("number");

        name = new Element("name");

        age = new Element("age");

        Document doc = new Document(root); //将根元素植入文档doc中

        number.setText("001");

        name.setText("lnman");

        age.setText("24");

        student.addContent(number);

        student.addContent(name);

        student.addContent(age);

        root.addContent(student);

        Format format = Format.getCompactFormat();

        format.setEncoding("gb2312"); //设置xml文件的字符为gb2312

        format.setIndent("    "); //设置xml文件的缩进为4个空格

        XMLOutputter XMLOut = new XMLOutputter(format);//元素后换行一层元素缩四格

        XMLOut.output(doc, new FileOutputStream("studentinfo.xml")); 

}

    public static void main(String[] args) throws Exception {

        WriteXML w = new WriteXML();

        System.out.println("Now we build an XML document .....");

        w.BuildXML();

        System.out.println("finished!");

}

}

生成的xml文档为:

<?xml version="1.0" encoding="gb2312"?>

<student-info>

    <student>

        <number>001</number>

        <name>lnman</name>

        <age>24</age>

    </student>

</student-info>

 

 

创建XML文档2:

 public class CreateXML {

  public void Create() {

   try {

    Document doc = new Document();  

    ProcessingInstruction pi=new ProcessingInstruction("xml-stylesheet","type="text/xsl" href="test.xsl"");

    doc.addContent(pi);   

    Namespace ns = Namespace.getNamespace("http://www.bromon.org" );

    Namespace ns2 = Namespace.getNamespace("other", "http://www.w3c.org" );

    Element root = new Element("根元素", ns);

    root.addNamespaceDeclaration(ns2);

    doc.setRootElement(root);

    Element el1 = new Element("元素一");

    el1.setAttribute("属性", "属性一");   

    Text text1=new Text("元素值");

             Element em = new Element("元素二").addContent("第二个元素");

    el1.addContent(text1);

             el1.addContent(em);            

             Element el2 = new Element("元素三").addContent("第三个元素");

             root.addContent(el1);

             root.addContent(el2);            

             //缩进四个空格,自动换行,gb2312编码

             XMLOutputter outputter = new XMLOutputter("  ", true,"GB2312");

             outputter.output(doc, new FileWriter("test.xml"));

         }catch(Exception e)  {

          System.out.println(e);

         }

     }    

     public static void main(String args[]) {

      new CreateXML().Create();

     }    

 }

2、读取xml文档的例子:

import org.jdom.output.*;

import org.jdom.input.*;

import org.jdom.*;

import java.io.*;

import java.util.*;

public class ReadXML{

    public static void main(String[] args) throws Exception {

        SAXBuilder builder = new SAXBuilder();

        Document read_doc = builder.build("studentinfo.xml");

        Element stu = read_doc.getRootElement();

        List list = stu.getChildren("student");

        for(int i = 0;i < list.size();i++) {

            Element e = (Element)list.get(i);

            String str_number = e.getChildText("number");

            String str_name = e.getChildText("name");

            String str_age = e.getChildText("age");

            System.out.println("---------STUDENT--------------");

            System.out.println("NUMBER:" + str_number);

            System.out.println("NAME:" + str_name);

            System.out.println("AGE:" + str_age);

            System.out.println("------------------------------");

            System.out.println();

        } 

       }

}

3、DTD验证的:

 public class XMLWithDTD {

  public void validate()  {

   try {

    SAXBuilder builder = new SAXBuilder(true);

    builder.setFeature("http://xml.org/sax/features/validation";,true);

    Document doc = builder.build(new FileReader("author.xml"));   

    System.out.println("搞掂");

    XMLOutputter outputter = new XMLOutputter();

    outputter.output(doc, System.out);

   }catch(Exception e) {

    System.out.println(e);

   }  

  }

  public static void main(String args[]) {

   new XMLWithDTD().validate();

  } 

 }

   需要说明的是,这个程序没有指明使用哪个DTD文件。DTD文件的位置是在XML中指定的,而 且DTD不支持命名空间,一个XML只能引用一个DTD,所以程序直接读取XML中指定的DTD,程序本身不用指定。不过这样一来,好象就只能使用外部式 的DTD引用方式了?高人指点。

 

 

4、XML Schema验证的:

 public class XMLWithSchema {

  String xml="test.xml";

  String schema="test-schema.xml";

  public void validate() {

   try {

    SAXBuilder builder = new SAXBuilder(true);

    //指定约束方式为XML schema

    builder.setFeature("http://apache.org/xml/features/validation/schema";,  true);

    //导入schema文件

builder.setProperty("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation";,schema);

    Document doc = builder.build(new FileReader(xml));   

    System.out.println("搞掂");

    XMLOutputter outputter = new XMLOutputter();

    outputter.output(doc, System.out);

   }catch(Exception e) {

    System.out.println("验证失败:"+e);

   } 

  }

 }

 上面的程序就指出了要引入的XML Schema文件的位置。

 

 

 系统默认输出是UTF-8,这有可能导致出现乱码。

5、Xpath例子:

JDOM的关于XPATH的api在org.jdom.xpath这个包里。这个包下,有一个抽象类 XPath.java和实现类JaxenXPath.java, 使用时先用XPath类的静态方法newInstance(String xpath)得到XPath对象,然后调用它的selectNodes(Object context)方法或selectSingleNode(Object context)方法,前者根据xpath语句返回一组节点(List对象);后者根据一个xpath语句返回符合条件的第一个节点(Object类 型)。请看jdom-1.0自带的范例程序:

     它分析在web.xml文件中的注册的servlet的个数及参数个数,并输出角色名。

web.xml文件:

<?xml version="1.0" encoding="ISO-8859-1"?>

<!--

<!DOCTYPE web-app

    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"

    "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">

-->

<web-app>

    <servlet>

        <servlet-name>snoop</servlet-name>

        <servlet-class>SnoopServlet</servlet-class>

    </servlet>

    <servlet>

        <servlet-name>file </servlet-name>

        <servlet-class>ViewFile</servlet-class>

        <init-param>

            <param-name>initial</param-name>

            <param-value>1000</param-value>

            <description>The initial value for the counter  <!-- optional --></description>

        </init-param>

    </servlet>

    <servlet-mapping>

        <servlet-name>mv</servlet-name>

        <url-pattern>*.wm</url-pattern>

    </servlet-mapping>

    <distributed/>

    <security-role>

      <role-name>manager</role-name>

      <role-name>director</role-name>

      <role-name>president</role-name>

    </security-role>

</web-app>

处理程序:

import java.io.*;

import java.util.*; 

public class XPathReader {     

    public static void main(String[] args) throws IOException, JDOMException {

        if (args.length != 1) {

            System.err.println("Usage: java XPathReader web.xml");

            return;

        }

        String filename = args[0];//从命令行输入web.xml

        PrintStream out = System.out;

        SAXBuilder builder = new SAXBuilder();

        Document doc = builder.build(new File(filename));//得到Document对象

 

 

        // Print servlet information

        XPath servletPath = XPath.newInstance("//servlet");//,选择任意路径下servlet元素

        List servlets = servletPath.selectNodes(doc);//返回所有的servlet元素。

        out.println("This WAR has "+ servlets.size() +" registered servlets:");

        Iterator i = servlets.iterator();

        while (i.hasNext()) {//输出servlet信息

            Element servlet = (Element) i.next();

            out.print("\t" + servlet.getChild("servlet-name")

                                    .getTextTrim() +

                      " for " + servlet.getChild("servlet-class")

                                       .getTextTrim());

            List initParams = servlet.getChildren("init-param");

            out.println(" (it has " + initParams.size() + " init params)"); 

        }             

        // Print security role information

        XPath rolePath = XPath.newInstance("//security-role/role-name/text()");

        List roleNames = rolePath.selectNodes(doc);//得到所有的角色名

        if (roleNames.size() == 0) {

            out.println("This WAR contains no roles");

        } else {

            out.println("This WAR contains " + roleNames.size() + " roles:");

            i = roleNames.iterator();

            while (i.hasNext()) {//输出角色名

                out.println("\t" + ((Text)i.next()).getTextTrim());

            }

        }

    }    

}

 

 

输出结果:

C:\java>java   XPathReader web.xml

This WAR has 2 registered servlets:

        snoop for SnoopServlet (it has 0 init params)

        file for ViewFile (it has 1 init params)

This WAR contains 3 roles:

        manager

        director

        president

 

 

6、数据输入要用到XML文档要通过org.jdom.input包,反过来需要org.jdom.output。如前面所说,关是看API文档就能够使用。

我们的例子读入XML文件exampleA.xml,加入一条处理指令,修改第一本书的价格和作者,并添加一条属性,然后写入文件exampleB.xml:

//exampleA.xml

<?xml version="1.0" encoding="GBK"?>

<bookList>

<book>

<name>Java编程入门</name>

<author>张三</author>

<publishDate>2002-6-6</publishDate>

<price>35.0</price>

</book>

<book>

<name>XML在Java中的应用</name>

<author>李四</author>

<publishDate>2002-9-16</publishDate>

<price>92.0</price>

</book>

</bookList>

//testJDOM.java

import org.jdom.*;

import org.jdom.output.*;

import org.jdom.input.*;

import java.io.*;

public class TestJDOM{

public static void main(String args[])throws Exception{

SAXBuilder sb = new SAXBuilder();

//从文件构造一个Document,因为XML文件中已经指定了编码,所以这里不必了

Document doc = sb.build(new FileInputStream("exampleA.xml"));

ProcessingInstruction pi = new ProcessingInstruction//加入一条处理指令

("xml-stylesheet","href=\"bookList.html.xsl\" type=\"text/xsl\"");

doc.addContent(pi);

Element root = doc.getRootElement(); //得到根元素

java.util.List books = root.getChildren(); //得到根元素所有子元素的集合

Element book = (Element)books.get(0); //得到第一个book元素

//为第一本书添加一条属性

Attribute a = new Attribute("hot","true");

book.setAttribute(a);

Element author = book.getChild("author"); //得到指定的字元素

author.setText("王五"); //将作者改为王五

//或 Text t = new Text("王五");book.addContent(t);

Element price = book.getChild("price"); //得到指定的字元素

//修改价格,比较郁闷的是我们必须自己转换数据类型,而这正是JAXB的优势

author.setText(Float.toString(50.0f));

String indent = " ";

boolean newLines = true;

XMLOutputter outp = new XMLOutputter(indent,newLines,"GBK");

outp.output(doc, new FileOutputStream("exampleB.xml"));

}

};

执行结果exampleB.xml:

<?xml version="1.0" encoding="GBK"?>

<bookList>

<book hot=”true”>

<name>Java编程入门</name>

<author>50.0</author>

<publishDate>2002-6-6</publishDate>

<price>35.0</price>

</book>

<book>

<name>XML在Java中的应用</name>

<author>李四</author>

<publishDate>2002-9-16</publishDate>

<price>92.0</price>

</book>

</bookList>

<?xml-stylesheet href="bookList.html.xsl" type="text/xsl"?>

在默认情况下,JDOM的Element类的getText()这类的方法不会过滤空白字符,如果你需要过滤,用setTextTrim() 。

posted @ 2007-04-29 14:08 flustar 阅读(357) | 评论 (0)编辑 收藏

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmplay/mmp_sdk/settingsobject.asp

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<link href="style/style.css" rel="stylesheet" type="text/css">

<script language="JavaScript">
var state;

//初始化
function playerinit()
{
 player.url="mp3.m3u";
 player.settings.autoStart = false ;
}

//播放
function play()
{
 if (player.controls.isavailable('play'))
 {
  player.controls.play();
  state=setInterval("updatetime()",1000);
  playerinfo.innerHTML = "播放";
 }
}

//暂停
function pause()
{
 if (player.controls.isavailable('pause'))
 {
  player.controls.pause();
  clearInterval(state);
  playerinfo.innerHTML = "暂停";
 }
}

//停止
function stop()
{
 if (player.controls.isavailable('stop'))
 {
  player.controls.stop();
  clearInterval(state);
  playerinfo.innerHTML = "停止";
 }
}

//前首
function previous()
{
 if (player.controls.isavailable( 'previous' ))
 {
  player.controls.previous();
  playerinfo.innerHTML = "前一首";
 }
}

//后首
function next()
{
 if (player.controls.isavailable( 'next' ))
 {
  player.controls.next();
  playerinfo.innerHTML = "下一首";
 }
}

//?
function step()
{
 if (player.controls.isavailable( 'step' ))
 player.controls.step( 1 );
}

//音量-
function voldown()
{
 if ( player.settings.volume < 5 )
 {
  player.settings.volume = 0;
  playerinfo.innerHTML = "0";
 }
 else
 {
  player.settings.volume -= 5;
  playerinfo.innerHTML = player.settings.volume;
 }
}

//音量+
function volup()
{
 if ( player.settings.volume > 95 )
 {
  player.settings.volume = 100;
  playerinfo.innerHTML = "100";
 }
 else
 {
  player.settings.volume += 5;
  playerinfo.innerHTML = player.settings.volume;
 }
}

//静音
function mute()
{
 player.settings.mute = !player.settings.mute;
}

//声道
function balance()
{
 switch (player.settings.balance)
 {
  case 0:
   player.settings.balance = 100;
   playerinfo.innerHTML = '左声道';
   break;
  case 100:
   player.settings.balance = -100;
   playerinfo.innerHTML = '右声道';
   break;
  case -100:
   player.settings.balance = 0;
   playerinfo.innerHTML = '全声道';
   break;
  default :
   player.settings.balance = 0;
   playerinfo.innerHTML = '全声道';
   break;
 }
}

//更新时间
function updatetime()
{
 playerinfo.innerHTML = player.controls.currentPositionString + " | " + player.currentMedia.durationString;
}

</script>
</head>
<body onload="playerinit();">
<table width="300">
  <tr>
    <td><object id="player" classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" type="application/x-oleobject" width="300" height="60">
      <param name="autoStart" value="false">
      <param name="balance" value="0">
      <param name="currentPosition" value="0">
      <param name="currentMarker" value="0">
      <param name="enableContextMenu" value="true">
      <param name="enableErrorDialogs" value="false">
      <param name="enabled" value="true">
      <param name="fullScreen" value="false">
      <param name="invokeURLs" value="false">
      <param name="mute" value="true">
      <param name="playCount" value="1">
      <param name="rate" value="1">
      <param name="uiMode" value="none">
      <param name="volume" value="100">
    </object></td>
  </tr>
  <tr>
    <td><span id="playerinfo"></span></td>
  </tr>
  <tr>
    <td>
      <div align="center">
<input type="button" class="but11" onmouseover=this.className="but12"; onmouseout=this.className="but11"; name="previous" title="上一首" onclick="previous();">
<input type="button" class="but21" onmouseover=this.className="but22"; onmouseout=this.className="but21"; name="play" title="播放" onclick="play();">
<input type="button" class="but31" onmouseover=this.className="but32"; onmouseout=this.className="but31"; name="pause" title="暂停" onclick="pause();">
<input type="button" class="but41" onmouseover=this.className="but42"; onmouseout=this.className="but41"; name="stop" title="停止" onclick="stop();">
<input type="button" class="but51" onmouseover=this.className="but52"; onmouseout=this.className="but51"; name="next" title="下一首" onclick="next();">
<input type="button" class="but61" onmouseover=this.className="but62"; onmouseout=this.className="but61"; name="voldown" title="音量-" onclick="voldown();">
<input type="button" class="but61" onmouseover=this.className="but62"; onmouseout=this.className="but61"; name="volup" title="音量+" onclick="volup();">
<input type="button" class="but61" onmouseover=this.className="but62"; onmouseout=this.className="but61"; name="mute" title="静音" onclick="mute();">
<input type="button" class="but61" onmouseover=this.className="but62"; onmouseout=this.className="but61"; name="balance" title="声道" onclick="balance();">
   </div>
 </td>
  </tr>
</table>
<script language = "JavaScript"  for = player event = playstatechange(newstate)>
switch (newstate){
  case 1:
   playerinfo.innerHTML = "停止";
   break;
  case 2:
   playerinfo.innerHTML = "暂停";
   break;
  case 3:
   playerinfo.innerHTML = "正在播放";
   break;
  case 4:
   playerinfo.innerHTML = "4";
   break;
  case 5:
   playerinfo.innerHTML = "5";
   break;
  case 6:
   playerinfo.innerHTML = "正在缓冲...";
   break;
  case 7:
   playerinfo.innerHTML = "7";
   break;
  case 8:
   playerinfo.innerHTML = "8";
   break;
  case 9:
   playerinfo.innerHTML = "正在连接...";
   break;
  case 10:
   playerinfo.innerHTML = "准备就绪。欢迎光临<a href='http://www.knowsky.com'>http://www.knowsky.com</a>";
   break;
  case 11:
   playerinfo.innerHTML = "11";
   break;
  default:
   playerinfo.innerHTML = "";
}
</script>

</body>
</html>

posted @ 2007-04-29 10:32 flustar 阅读(729) | 评论 (0)编辑 收藏

一.设置端口
在server.xml文件中找到<!--   Define a non-SSL HTTP/1.1 Connector on port 8080, change it to 80.   -->
     < Connector
port ="80"                maxHttpHeaderSize ="8192"
               maxThreads ="150"  minSpareThreads ="25"  maxSpareThreads ="75"
               enableLookups ="false"  redirectPort ="8443"  acceptCount ="100"
               connectionTimeout ="20000"  disableUploadTimeout ="true"   />把其中的port改为你想要的端口即可。
二 .设置虚拟路径
  要在TOMCAT中设置虚拟路径/abc/,映射到D:\temp中,可以有两种方法:
1. 在$Tomcat_home$\conf\Catalina\localhost路径下新建一个XML文件,注意:XML文件的名称必须和虚拟路径的名称相同,本例为abc.xml。内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<Context    docBase="D:\temp"    reloadable="true"    debug="0"/>//此处不用写" path="/abc",写不写效果一样

这样就设置好了/abc的虚拟路径
2.
编辑server文件(%tomcathome%\conf\server.xml)
因为在tomcat启动时要读取server文件的信息,所以更改server文件后,一定要重新启动tomcat。
举个例子:
我们打算建立一个myjsp的虚拟目录,只要在%tomcathome%\conf\server.xml文件,在<host>标签中加入文件中加入如下代码即可:
<Context path="/myjsp" docBase="c:\myjsp" debug="0" reloadable="true" crossContext="true"></Context>
其中,path为我们要建立的虚拟目录,docBase为实际目录在硬盘上的位置。

posted @ 2007-04-29 10:19 flustar 阅读(2299) | 评论 (1)编辑 收藏



 一、环境

1.eclipse 3.2.2
2.myeclipse 5.1.1
3.jdk 1.5

二、简要说明

数据库为mysql

 在mysql中建立一个test数据库,建立cat表
CREATE TABLE `cat` (
  `cat_id` varchar(32) NOT NULL,
  `name` varchar(16) NOT NULL,
  `sex` varchar(1) default NULL,
  `weight` float(9,3) default NULL,
  PRIMARY KEY  (`cat_id`)
)

三、步骤

1.导入包的准备工作

a.新建java project.建立包example
在它下面编写类Cat.java

package example;

 public class Cat  implements java.io.Serializable {


    // Fields   

     private String catId;
     private String name;
     private String sex;
     private Float weight;


    // Constructors

    /** default constructor */
    public Cat() {
    }

 /** minimal constructor */
    public Cat(String name) {
        this.name = name;
    }
   
    /** full constructor */
    public Cat(String name, String sex, Float weight) {
        this.name = name;
        this.sex = sex;
        this.weight = weight;
    }

  
    // Property accessors

    public String getCatId() {
        return this.catId;
    }
   
    public void setCatId(String catId) {
        this.catId = catId;
    }

    public String getName() {
        return this.name;
    }
   
    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return this.sex;
    }
   
    public void setSex(String sex) {
        this.sex = sex;
    }

    public Float getWeight() {
        return this.weight;
    }
   
    public void setWeight(Float weight) {
        this.weight = weight;
    } 
}

同样在此包下面编写Cat.hbm.xml

  <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
    <class name="example.Cat" table="cat" catalog="testhibernate">
        <id name="catId" type="java.lang.String">
            <column name="cat_id" length="32" />
            <generator class="uuid.hex"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="16" not-null="true" />
        </property>
        <property name="sex" type="java.lang.String">
            <column name="sex" length="1" />
        </property>
        <property name="weight" type="java.lang.Float">
            <column name="weight" precision="9" scale="3" />
        </property>
    </class>
</hibernate-mapping>

b.在工程的src里面加入一个包,用来存放将要生成的HibernateSessionFactory。包名如(example.util)。
导入hibernate(生成的代码:
package example.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;

/**
 * Configures and provides access to Hibernate sessions, tied to the
 * current thread of execution.  Follows the Thread Local Session
 * pattern, see {@link http://hibernate.org/42.html }.
 */
public class HibernateSessionFactory {

    /**
     * Location of hibernate.cfg.xml file.
     * Location should be on the classpath as Hibernate uses 
     * #resourceAsStream style lookup for its configuration file.
     * The default classpath location of the hibernate config file is
     * in the default package. Use #setConfigFile() to update
     * the location of the configuration file for the current session.  
     */
    private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
 private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    private  static Configuration configuration = new Configuration();
    private static org.hibernate.SessionFactory sessionFactory;
    private static String configFile = CONFIG_FILE_LOCATION;

    private HibernateSessionFactory() {
    }
 
 /**
     * Returns the ThreadLocal Session instance.  Lazy initialize
     * the <code>SessionFactory</code> if needed.
     *
     *  @return Session
     *  @throws HibernateException
     */
    public static Session getSession() throws HibernateException {
        Session session = (Session) threadLocal.get();

  if (session == null || !session.isOpen()) {
   if (sessionFactory == null) {
    rebuildSessionFactory();
   }
   session = (sessionFactory != null) ? sessionFactory.openSession()
     : null;
   threadLocal.set(session);
  }

        return session;
    }

 /**
     *  Rebuild hibernate session factory
     *
     */
 public static void rebuildSessionFactory() {
  try {
   configuration.configure(configFile);
   sessionFactory = configuration.buildSessionFactory();
  } catch (Exception e) {
   System.err
     .println("%%%% Error Creating SessionFactory %%%%");
   e.printStackTrace();
  }
 }

 /**
     *  Close the single hibernate session instance.
     *
     *  @throws HibernateException
     */
    public static void closeSession() throws HibernateException {
        Session session = (Session) threadLocal.get();
        threadLocal.set(null);

        if (session != null) {
            session.close();
        }
    }

 /**
     *  return session factory
     *
     */
 public static org.hibernate.SessionFactory getSessionFactory() {
  return sessionFactory;
 }

 /**
     *  return session factory
     *
     * session factory will be rebuilded in the next call
     */
 public static void setConfigFile(String configFile) {
  HibernateSessionFactory.configFile = configFile;
  sessionFactory = null;
 }

 /**
     *  return hibernate configuration
     *
     */
 public static Configuration getConfiguration() {
  return configuration;
 }

}

对工程名点鼠标右键。选择myeclipse->add

hibernate capabicities。

在弹出的窗口选择中Hibernate 3.0 Core Libraries和Hibernate 3.0 Advanced Support Libraries

下面选中Copy checked Library Jars to project folder and add to build-path。点击下一步。

c.默认(hibernate cofig file),下一步。

d.选中User JDBC driver
connect url:  jdbc:mysql://localhost:3306/test
Driver class:  org.gjt.mm.mysql.Driver
username:  root
password: ******
Dialect: mysql

e.在第一行包选择里面,选择在前面第二大步建的包如(example)。点击完成。

f.弹出的画面中 选择properties的add按钮。在Property中加入show_sql,Value中加入true。点确定

保存设置。在mappings中点add加入前面建立的Cat.hbm.xml。最后生成的hibernate.cfg.xml文件如下
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

<session-factory>
 <property name="connection.username">root</property>
 <property name="connection.url">
  jdbc:mysql://localhost:3306/testhibernate
 </property>
 <property name="dialect">
  org.hibernate.dialect.MySQLDialect
 </property>
 <property name="connection.password">123456</property>
 <property name="connection.driver_class">
  org.gjt.mm.mysql.Driver
 </property>
 <property name="show_sql">true</property>
 <mapping resource="example/Cat.hbm.xml" />

</session-factory>

</hibernate-configuration>


3.测试 新建包test 在其中建立测试文件TestHibernate.java
package test;

import java.util.Iterator;
import java.util.List;
import example.*;
import example.util.*;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class TestHibernate {
 Session session=null;
 Transaction tx=null;
public static void main(String[] args) {
 TestHibernate th=new TestHibernate(); 
 List cl=th.getAllCats();
 if(cl!=null){
  Iterator it=cl.iterator();
  while(it.hasNext()){
   Cat cat=(Cat)it.next();
   System.out.println("catID:"+cat.getCatId()+"name:"+cat.getName()+"sex:"+cat.getSex());
  }
 }
  
  

 }
public List getAllCats(){
 session=HibernateSessionFactory.getSession();
 List catlist=null;
 try{
  tx=session.beginTransaction();
  catlist=session.createQuery("from Cat").list();
  return catlist;
 }catch(Exception ex){
  System.err.println(ex.getMessage());
  return null;
 }finally{
  HibernateSessionFactory.closeSession();
 }
}

}

 

 

posted @ 2007-04-19 15:45 flustar 阅读(5315) | 评论 (2)编辑 收藏

1)启动Tomcat服务器,打开浏览器,输入http://localhost:8080/admin(其中localhost是名称服务器或称为主机),
进入管理界面的登陆页面,这时候请输入原来安装时要求输入的用户名和密码,登陆到管理界面,

2)选择Resources-Data sources进入配置数据源界面,选择
 Data Source Actions ->选择Create New Data Source,进入配置详细信息界面
主要内容例如下:
JNDI Name:   ->jdbc/mysql
Data Source URL  ->jdbc:mysql://localhost:3306/test
JDBC Driver Class-> org.gjt.mm.mysql.Driver
3)修改\conf\Catalina\localhost目录下建立一个xml文件,名称为你所发布的web应用的名称.xml,(如testpool.xml)打开添加内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
 <Resource
      name="jdbc/mysql"
      type="javax.sql.DataSource"
      password="123456"
      driverClassName="org.gjt.mm.mysql.Driver"
      maxIdle="2"
      maxWait="50"
      username="root"
      url="jdbc:mysql://localhost:3306/test"
      maxActive="4"/>

</Context>
内容同conf/server.xml中<GlobalNamingResources>
 <Resource
      name="jdbc/mysql"
      type="javax.sql.DataSource"
      password="123456"
      driverClassName="org.gjt.mm.mysql.Driver"
      maxIdle="2"
      maxWait="50"
      username="root"
      url="jdbc:mysql://localhost:3306/test"
      maxActive="4"/>
  </GlobalNamingResources>

少了这一步会报错:Cannot create JDBC driver of class '' for connect URL 'null'
4)修改web.xml

打开%TOMCAT_HOME%\conf\web.xml或yourwebapp/web-inf/web.xml,添加以下内容:
    <resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/mysql</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    </resource-ref>

    注意res-ref-name填写的内容要与在上文提到的JNDI Name名称一致。
 到这里,配置工作就基本完成了!

5)引用JNDI时用"java:comp/env/jdbc/mysql";
建立文件测试 test.jsp:
<%@page contentType="text/html;charset=utf-8" %>
<%@page import="java.sql.*" %>
<%@page import="javax.sql.*" %>
<%@page import="javax.naming.*" %>
<html>
<head>
<title>Tomcat连接池测试</title>
</head>
<body>
<%
  Context ctx=new InitialContext();
  Connection conn=null;
  DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/mysql");
  conn=ds.getConnection();
  Statement stmt=conn.createStatement(ResultSet.CONCUR_READ_ONLY,ResultSet.CONCUR_UPDATABLE);
  ResultSet rs=stmt.executeQuery("select * from testexample");
  while(rs.next()){
  out.println(rs.getInt(1));
  out.println(rs.getString(2));
  out.println(rs.getString(3));
  }
  out.println("数据库操作成功!");
  rs.close();
  stmt.close();
  conn.close();
   
 %>
</body>
</html>




 

posted @ 2007-04-17 17:27 flustar 阅读(50410) | 评论 (28)编辑 收藏

运行环境配置

1、工具下载与安装 
      1>下载安装JDK5.0(www.java.sun.com)
      2>下载安装eclipse3.2.x(http://www.eclipse.org
      3>下载eclispse3.2多国语言包(http://download.eclipse.org/eclipse/downloads/drops/L-3.2.1_Language_Packs-200609210945/index.php
      4>下载和安装jboss-4.0.X.GA 服务器(www.jboss.org)
      5>下载插件Lomboz3.2all in one for eclipse(http://forge.objectweb.org/projects/lomboz)
      6>下载xdoclet1.2.3(http://xdoclet.sourceforge.net/)
2.插件安装
   分别解压lomboz 和多国语言包到Eclipse目录中并把它们的文件名分别命名为lomboz 和language
     在Eclipse目录中,建立links文件夹,在该文件夹下建立两个.link文件,内容分别为:
   path=lomboz 和path=langage,lin文件名分别为lomboz.link和language.link.
3、直接解压jboss到某一目录(如c:\jboss4.0.4GA)
设置环境变量:
  假如 J2SDK安装在c:\j2sdk,JBoss安装在c:\jboss,环境变量的设置如下:
   JAVA_HOME=C:\j2sdk
   CLASSPATH=%CLASSPATH%;%JAVA_HOME%\lib\*.jar;%JAVA_HOME%\jre\lib\*.jar
   JBOSS_HOME=C:\jboss
   PATH=%PATH%;%JAVA_HOME%\bin;%JBOSS_HOME%\bin
4、xdoclet安装
window—>preferences—>Xdoclet—>Xdoclet目录
5、服务器
window —>preferences—>server—>jboss—>jboss4.0安装目录
  

posted @ 2006-12-23 20:03 flustar 阅读(1209) | 评论 (0)编辑 收藏

运行环境配置

1、工具下载与安装 
      1>下载安装JDK5.0(www.java.sun.com)
      2>下载安装eclipse3.2.x(www.eclipse.org)(如果你下载了JBOSS IDE2.0(内含eclipse3.2.x,这个可以不要)
      3>下载和安装jboss-4.0.5.GA 服务器(记住一定要下载安装版,内含EJB3.0Container,地址:http://sourceforge.net/project/downloading.php?groupname=jboss&filename=jems-installer-1.2.0.CR1.jar&use_mirror=jaist
      4>下载插件JBOSS IDE 2.0(http://sourceforge.net/project/downloading.php?groupname=jboss&filename=JBossIDE-2.0.0.ALPHA-Bundle-win32.zip&use_mirror=nchc)
      安装JBOSS是要注意几点:
       1>议不要安装在Program Files 目录,否则一些应用会导致莫名的错。
      2>选择带集群功能的安装选项“ejb3-clustered”
      3>在输入配置名称时,输入“all”
      4>在配置JMX时,把所有选择荐都勾上,并输入jmx-console的用户名和密码!
      5》运行JBOSS,进行JBOSS安装目录下,进入BIN目录下,运行 run -c all,如果直接运行run,会报错!(因为你run.bat不知道你运行的是那种配置all,default,还是min)
2、设置环境变量
    JAVA_HOME=JAVA安装目录
   JBOSS_HOME=JBOSS安装目录

3、认识JBOSS目录用途

目录 描述
bin 启 动 和关闭JBoss的脚本
client 客户端与JBoss通信所需的Java 库(JARs)
docs 配置的样本文件(数据库配置等)
docs/dtd 在JBoss中使用的各种XML文件的DTD。
lib  一些JAR,JBoss启动时加载,且被所有JBoss配置共享。(不要把你的库放在这里)
server 各种JBoss配置。每个配置必须放在不同的子目录。子目录的名字表示配置的名字。JBoss
包含3 个默认的配置:minimial,default和all,在你安装时可以进行选择
server/all JBoss的完全配置,启动所有服务,包括集群和IIOP。(本教程就采用此配置)
server/default  JBoss 的默认配置。在没有在JBoss 命令航中指定配置名称时使用。(本教程没有安装此
配置,如果不指定配置名称,启动将会出错)
server/all/conf JBoss的配置文件。
server/all/data JBoss的数据库文件。比如,嵌入的数据库,或者JBossMQ。
server/all/deploy JBoss的热部署目录。放到这里的任何文件或目录会被JBoss自动部署。EJB、WAR、EAR,甚至服务。
server/all/lib 一些JAR,JBoss在启动特定配置时加载他们。(default和minimial配置也包含这个和下面两个目录。)
server/all/log JBoss的日志文件
server/all/tmp JBoss的临时文件

4、EJB部署
   JBoss中的部署过程非常的简单、直接。在每一个配置中,JBoss不断的扫描一个特殊目录的变化:
[jboss安装目录]/server/config-name/deploy。

posted @ 2006-12-23 18:56 flustar 阅读(3223) | 评论 (2)编辑 收藏

如今Linux不仅在服务器领域的应用取得较大进展,而且在桌面应用领域也有越来越多的人选择使用。下面就以Red Hat Linux 9.0为例,介绍如何与Windows XP组成双系统。

  给Linux划分领地

  由于Linux无法安装在Windows的分区上,所以必须在硬盘中分割出一块领地专供Linux使用,这里推荐用分区魔术师进行无损分区。为了方便讲述,这里先举一个实例来说明:装有Windows XP计算机有一个30GB的硬盘,共分三个区(C盘、D盘、和E盘),其中E盘有16.6GB(有约7GB可用空间)。我们的目标是将7GB的可用空间剥离出来专供Red Hat使用。

  1.首先在Windows XP里启动分区魔术师,从主窗口可以看到磁盘分区的详细信息。单击右侧详细窗格里的分区E以选中它。

  2.单击左侧任务列表里的“调整一个分区的容量”命令,即可弹出一个“调整容量/移动分区”对话框。

  3.在该对话框的顶部有一个条状图表示分区E的使用情况,其中左侧的黑色条部分表示已用空间,右侧的绿色条部分表示可用空间。可以用鼠标直接拖曳绿色条部分对E盘容量进行调整。很显然,E盘的最小容量就是已用空间的容量(在小就要破坏原有数据了),减小的容量就成了自有空间。

  4.单击“确定”按钮,回到主界面,此时我们可以看到新划分出的7GB自由空间。接下来的步骤非常重要。尽管这7GB的磁盘空间已经是“自由身”,但是它还是属于Windows的扩展分区,所以要将这7GB的自由空间从Windows扩展分区里划分出去。

  5.单击扩展分区以选中它,如图1所示。用类似的方法将这7GB自由空间从Windows扩展DOS分区里划分出去。现在我们已经从Windows XP的领地里割出一块7GB的自由空间供Linux专用。



图1 将自由空间从扩展分区里划分出去


  注意,一定要将自由空间从Windows扩展分区里划分出去,这是因为Linux的分区格式和Windows并不完全兼容。如果Red Hat所使用的磁盘空间属于Windows扩展分区,就会导致“水土不服”。很多朋友反映装上了Red Hat以后,发现Windows速度变得奇慢,就会归咎于Red Hat,其实根本原因在于分区的时候没有将自由空间从扩展分区里剥离出去。

  实现Windows与Linux双重引导有多种方法:

  ◆ 对于具有双硬盘的用户,可以将Linux安装在第二个硬盘上(Windows自然是安装在第一个硬盘上),并且确保将GRUB(LILO)安装在第二个硬盘的主引导扇区,然后每次开机时在BIOS里指定从哪个硬盘引导即可。

  ◆ 最常用的方法是借助Linux的引导装载管理器GRUB(LILO),自动接管双重系统的启动选单。

  ◆ 可以借助Windows XP的NT引导程序ntldr、boot.ini来实现双重启动。这种方法的优点是今后删除Linux比较方便,而且符合我们的使用习惯;缺点是实现起来相对比较复杂,需要获取Linux系统的引导映像文件。

  ◆ 可以选择不安装Linux的引导装载管理器(或者不要安装在主引导扇区),但是要记住在安装过程中一定要创建Linux启动盘。今后需要时,用这张启动盘引导系统进入Linux。

  这里介绍了四种双重系统的实现方案,本文将分别介绍比较常见的第二和第三种方法。

posted @ 2006-12-20 16:45 flustar 阅读(242) | 评论 (1)编辑 收藏

在我们学习Java的过程中,掌握其中的基本概念对我们的学习无论是J2SE,J2EE,J2ME都是很重要的,J2SE是Java的基础,所以有必要对其中的基本概念做以归纳,以便大家在以后的学习过程中更好的理解java的精髓,在此我总结了30条基本的概念.

   Java概述:

   目前Java主要应用于中间件的开发(middleware)---处理客户机于服务器之间的通信技术,早期的实践证明,Java不适合pc应用程序的开发,其发展逐渐变成在开发手持设备,互联网信息站,及车载计算机的开发.Java于其他语言所不同的是程序运行时提供了平台的独立性,称许可以在windows,solaris,linux其他操作系统上使用完全相同的代码.Java的语法与C++语法类似,C++/C程序员很容易掌握,而且Java是完全的彻底的面向对象的,其中提出了很好的GC(Garbage Collector)垃圾处理机制,防止内存溢出.

   Java的白皮书为我们提出了Java语言的11个关键特性.

   (1)Easy:Java的语法比C++的相对简单,另一个方面就是Java能使软件在很小的机器上运行,基础解释其和类库的支持的大小约为40kb,增加基本的标准库和线程支持的内存需要增加125kb.

   (2)分布式:Java带有很强大的TCP/IP协议族的例程库,Java应用程序能够通过URL来穿过网络来访问远程对象,由于servlet机制的出现,使Java编程非常的高效,现在许多的大的web server都支持servlet.

   (3)OO:面向对象设计是把重点放在对象及对象的接口上的一个编程技术.其面向对象和C++有很多不同,在与多重继承的处理及Java的原类模型.

   (4)健壮特性:Java采取了一个安全指针模型,能减小重写内存和数据崩溃的可能性。

   (5)安全:Java用来设计网路和分布系统,这带来了新的安全问题,Java可以用来构建防病毒和防攻击的System.事实证明Java在防毒这一方面做的比较好.

   (6)中立体系结构:Java编译其生成体系结构中立的目标文件格式可以在很多处理器上执行,编译器产生的指令字节码(Javabytecode)实现此特性,此字节码可以在任何机器上解释执行.

   (7)可移植性:Java中对基本数据结构类型的大小和算法都有严格的规定所以可移植性很好.

   (8)多线程:Java处理多线程的过程很简单,Java把多线程实现交给底下操作系统或线程程序完成.所以多线程是Java作为服务器端开发语言的流行原因之一

   (9)Applet和servlet:能够在网页上执行的程序叫Applet,需要支持Java的浏览器很多,而applet支持动态的网页,这是很多其他语言所不能做到的.

   基本概念:

   1.OOP中唯一关系的是对象的接口是什么,就像计算机的销售商她不管电源内部结构是怎样的,他只关系能否给你提供电就行了,也就是只要知道can or not而不是how and why.所有的程序是由一定的属性和行为对象组成的,不同的对象的访问通过函数调用来完成,对象间所有的交流都是通过方法调用,通过对封装对象数据,很大限度上提高复用率.

   2.OOP中最重要的思想是类,类是模板是蓝图,从类中构造一个对象,即创建了这个类的一个实例(instance)

   3.封装:就是把数据和行为结合起在一个包中)并对对象使用者隐藏数据的实现过程,一个对象中的数据叫他的实例字段(instance field)

   4.通过扩展一个类来获得一个新类叫继承(inheritance),而所有的类都是由Object根超类扩展而得,根超类下文会做介绍.

   5.对象的3个主要特性
   behavior---说明这个对象能做什么.
   state---当对象施加方法时对象的反映.
   identity---与其他相似行为对象的区分标志.
   每个对象有唯一的indentity 而这3者之间相互影响.

   6.类之间的关系:
   use-a :依赖关系
   has-a :聚合关系
   is-a :继承关系--例:A类继承了B类,此时A类不仅有了B类的方法,还有其自己的方法.(个性存在于共性中)

   7.构造对象使用构造器:构造器的提出,构造器是一种特殊的方法,构造对象并对其初始化.
   例:Data类的构造器叫Data
   new Data()---构造一个新对象,且初始化当前时间.
   Data happyday=new
   Data()---把一个对象赋值给一个变量happyday,从而使该对象能够多次使用,此处要声明的使变量与对象变量二者是不同的.new返回的值是一个引用.
   构造器特点:构造器可以有0个,一个或多个参数
   构造器和类有相同的名字
   一个类可以有多个构造器
   构造器没有返回值
   构造器总是和new运算符一起使用.

   8.重载:当多个方法具有相同的名字而含有不同的参数时,便发生重载.编译器必须挑选出调用哪个方法.

   9.包(package)Java允许把一个或多个类收集在一起成为一组,称作包,以便于组织任务,标准Java库分为许多包.java.lang java.util java,net等,包是分层次的所有的java包都在java和javax包层次内.

   10.继承思想:允许在已经存在的类的基础上构建新的类,当你继承一个已经存在的类时,那么你就复用了这个类的方法和字段,同时你可以在新类中添加新的方法和字段.

   11.扩展类:扩展类充分体现了is-a的继承关系. 形式为:class (子类) extends (基类).

   12.多态:在java中,对象变量是多态的.而java中不支持多重继承.

   13.动态绑定:调用对象方法的机制.
   (1)编译器检查对象声明的类型和方法名.
   (2)编译器检查方法调用的参数类型.
   (3)静态绑定:若方法类型为priavte static final 编译器会准确知道该调用哪个方法.
   (4)当程序运行并且使用动态绑定来调用一个方法时,那么虚拟机必须调用x所指向的对象的实际类型相匹配的方法版本.
   (5)动态绑定:是很重要的特性,它能使程序变得可扩展而不需要重编译已存代码.

   14.final类:为防止他人从你的类上派生新类,此类是不可扩展的.

   15.动态调用比静态调用花费的时间要长,

   16.抽象类:规定一个或多个抽象方法的类本身必须定义为abstract例: public abstract string getDescripition

   17.Java中的每一个类都是从Object类扩展而来的.

   18.object类中的equal和toString方法.equal用于测试一个对象是否同另一个对象相等.toString返回一个代表该对象的字符串,几乎每一个类都会重载该方法,以便返回当前状态的正确表示.(toString 方法是一个很重要的方法)

   19.通用编程:任何类类型的所有值都可以同object类性的变量来代替.

   20.数组列表:ArrayList动态数组列表,是一个类库,定义在java.uitl包中,可自动调节数组的大小.

   21.class类 object类中的getclass方法返回ckass类型的一个实例,程序启动时包含在main方法的类会被加载,虚拟机要加载他需要的所有类,每一个加载的类都要加载它需要的类.

   22.class类为编写可动态操纵java代码的程序提供了强大的功能反射,这项功能为JavaBeans特别有用,使用反射Java能支持VB程序员习惯使用的工具.能够分析类能力的程序叫反射器,Java中提供此功能的包叫Java.lang.reflect反射机制十分强大.
   1.在运行时分析类的能力.
   2.在运行时探察类的对象.
   3.实现通用数组操纵代码.
   4.提供方法对象.
   而此机制主要针对是工具者而不是应用及程序.
   反射机制中的最重要的部分是允许你检查类的结构.用到的API有:
   java.lang.reflect.Field 返回字段.
   java.reflect.Method 返回方法.
   java.lang.reflect.Constructor 返回参数.
   方法指针:java没有方法指针,把一个方法的地址传给另一个方法,可以在后面调用它,而接口是更好的解决方案.

   23.接口(Interface)说明类该做什么而不指定如何去做,一个类可以实现一个或多个interface.

   24.接口不是一个类,而是对符合接口要求的类的一套规范.若实现一个接口需要2个步骤:
   1.声明类需要实现的指定接口.
   2.提供接口中的所有方法的定义.
   声明一个类实现一个接口需要使用implements 关键字class actionB implements Comparable 其actionb需要提供CompareTo方法,接口不是类,不能用new实例化一个接口.

   25.一个类只有一个超类,但一个类能实现多个接口.Java中的一个重要接口Cloneable

   26.接口和回调.编程一个常用的模式是回调模式,在这种模式中你可以指定当一个特定时间发生时回调对象上的方法.例:ActionListener 接口监听.
   类似的API有:java.swing.JOptionPane
         java.swing.Timer
         java.awt.Tookit

   27.对象clone:clone方法是object一个保护方法,这意味着你的代码不能简单的调用它.

   28.内部类:一个内部类的定义是定义在另一个内部的类
   原因是:1.一个内部类的对象能够访问创建它的对象的实现,包括私有数据
   2.对于同一个包中的其他类来说,内部类能够隐藏起来.
   3.匿名内部类可以很方便的定义回调.
   4.使用内部类可以非常方便的编写事件驱动程序.

   29.代理类(proxy):1.指定接口要求所有代码 2.object类定义的所有的方法(toString equals)

   30.数据类型:Java是强调类型的语言,每个变量都必须先申明它都类型,java中总共有8个基本类型.4种是整型,2种是浮点型,一种是字符型,被用于Unicode编码中的字符,布尔型.
以上内容摘自:http://java.ccidnet.com/art/3737/20060911/896379_1.html

posted @ 2006-12-20 16:39 flustar 阅读(423) | 评论 (0)编辑 收藏

对于这个系列里的问题,每个学Java的人都应该搞懂。当然,如果只是学Java玩玩就无所谓了。如果你认为自己已经超越初学者了,却不很懂这些问题,请将你自己重归初学者行列。内容均来自于CSDN的经典老贴。

问题一:我声明了什么!

String s = "Hello world!";

许多人都做过这样的事情,但是,我们到底声明了什么?回答通常是:一个String,内容是“Hello world!”。这样模糊的回答通常是概念不清的根源。如果要准确的回答,一半的人大概会回答错误。
这个语句声明的是一个指向对象的引用,名为“s”,可以指向类型为String的任何对象,目前指向"Hello world!"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象,我们只是声明了一个只能指向String对象的引用变量。所以,如果在刚才那句语句后面,如果再运行一句:

String string = s;

我们是声明了另外一个只能指向String对象的引用,名为string,并没有第二个对象产生,string还是指向原来那个对象,也就是,和s指向同一个对象。

问题二:"=="和equals方法究竟有什么区别?

==操作符专门用来比较变量的值是否相等。比较好理解的一点是:
int a=10;
int b=10;
则a==b将是true。
但不好理解的地方是:
String a=new String("foo");
String b=new String("foo");
则a==b将返回false。

根据前一帖说过,对象变量其实是一个引用,它们的值是指向对象所在的内存地址,而不是对象本身。a和b都使用了new操作符,意味着将在内存中产生两个内容为"foo"的字符串,既然是“两个”,它们自然位于不同的内存地址。a和b的值其实是两个不同的内存地址的值,所以使用"=="操作符,结果会是false。诚然,a和b所指的对象,它们的内容都是"foo",应该是“相等”,但是==操作符并不涉及到对象内容的比较。
对象内容的比较,正是equals方法做的事。

看一下Object对象的equals方法是如何实现的:
boolean equals(Object o){

return this==o;

}
Object对象默认使用了==操作符。所以如果你自创的类没有覆盖equals方法,那你的类使用equals和使用==会得到同样的结果。同样也可以看出,Object的equals方法没有达到equals方法应该达到的目标:比较两个对象内容是否相等。因为答案应该由类的创建者决定,所以Object把这个任务留给了类的创建者。

看一下一个极端的类:
Class Monster{
private String content;
...
boolean equals(Object another){ return true;}

}
我覆盖了equals方法。这个实现会导致无论Monster实例内容如何,它们之间的比较永远返回true。

所以当你是用equals方法判断对象的内容是否相等,请不要想当然。因为可能你认为相等,而这个类的作者不这样认为,而类的equals方法的实现是由他掌握的。如果你需要使用equals方法,或者使用任何基于散列码的集合(HashSet,HashMap,HashTable),请察看一下java doc以确认这个类的equals逻辑是如何实现的。

问题三:String到底变了没有?

没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。请看下列代码:

String s = "Hello";
s = s + " world!";

s所指向的对象是否改变了呢?从本系列第一篇的结论很容易导出这个结论。我们来看看发生了什么事情。在这段代码中,s原先指向一个String对象,内容是"Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。
通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。
同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:
public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
而非
s = new String("Initial Value");
后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。
上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。
至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即StringBuffer。

问题四:final关键字到底修饰了什么?

final使得被修饰的变量"不变",但是由于对象型变量的本质是“引用”,使得“不变”也有了两种含义:引用本身的不变,和引用指向的对象不变。

引用本身的不变:
final StringBuffer a=new StringBuffer("immutable");
final StringBuffer b=new StringBuffer("not immutable");
a=b;//编译期错误

引用指向的对象不变:
final StringBuffer a=new StringBuffer("immutable");
a.append(" broken!"); //编译通过

可见,final只对引用的“值”(也即它所指向的那个对象的内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象的变化,final是不负责的。这很类似==操作符:==操作符只负责引用的“值”相等,至于这个地址所指向的对象内容是否相等,==操作符是不管的。

理解final问题有很重要的含义。许多程序漏洞都基于此----final只能保证引用永远指向固定对象,不能保证那个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享或修改,一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解决方法就是在此对象新建的时候把它声明为final,意图使得它“永远不变”。其实那是徒劳的。

问题五:到底要怎么样初始化!

本问题讨论变量的初始化,所以先来看一下Java中有哪些种类的变量。
1. 类的属性,或者叫值域
2. 方法里的局部变量
3. 方法的参数

对于第一种变量,Java虚拟机会自动进行初始化。如果给出了初始值,则初始化为该初始值。如果没有给出,则把它初始化为该类型变量的默认初始值。

int类型变量默认初始值为0
float类型变量默认初始值为0.0f
double类型变量默认初始值为0.0
boolean类型变量默认初始值为false
char类型变量默认初始值为0(ASCII码)
long类型变量默认初始值为0
所有对象引用类型变量默认初始值为null,即不指向任何对象。注意数组本身也是对象,所以没有初始化的数组引用在自动初始化后其值也是null。

对于两种不同的类属性,static属性与instance属性,初始化的时机是不同的。instance属性在创建实例的时候初始化,static属性在类加载,也就是第一次用到这个类的时候初始化,对于后来的实例的创建,不再次进行初始化。这个问题会在以后的系列中进行详细讨论。

对于第二种变量,必须明确地进行初始化。如果再没有初始化之前就试图使用它,编译器会抗议。如果初始化的语句在try块中或if块中,也必须要让它在第一次使用前一定能够得到赋值。也就是说,把初始化语句放在只有if块的条件判断语句中编译器也会抗议,因为执行的时候可能不符合if后面的判断条件,如此一来初始化语句就不会被执行了,这就违反了局部变量使用前必须初始化的规定。但如果在else块中也有初始化语句,就可以通过编译,因为无论如何,总有至少一条初始化语句会被执行,不会发生使用前未被初始化的事情。对于try-catch也是一样,如果只有在try块里才有初始化语句,编译部通过。如果在catch或finally里也有,则可以通过编译。总之,要保证局部变量在使用之前一定被初始化了。所以,一个好的做法是在声明他们的时候就初始化他们,如果不知道要出事化成什么值好,就用上面的默认值吧!

其实第三种变量和第二种本质上是一样的,都是方法中的局部变量。只不过作为参数,肯定是被初始化过的,传入的值就是初始值,所以不需要初始化。

问题六:instanceof是什么东东?

instanceof是Java的一个二元操作符,和==,>,<是同一类东东。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。举个例子:

String s = "I AM an Object!";
boolean isObject = s instanceof Object;

我们声明了一个String对象引用,指向一个String对象,然后用instancof来测试它所指向的对象是否是Object类的一个实例,显然,这是真的,所以返回true,也就是isObject的值为True。
instanceof有一些用处。比如我们写了一个处理账单的系统,其中有这样三个类:

public class Bill {//省略细节}
public class PhoneBill extends Bill {//省略细节}
public class GasBill extends Bill {//省略细节}

在处理程序里有一个方法,接受一个Bill类型的对象,计算金额。假设两种账单计算方法不同,而传入的Bill对象可能是两种中的任何一种,所以要用instanceof来判断:

public double calculate(Bill bill) {
if (bill instanceof PhoneBill) {
//计算电话账单
}
if (bill instanceof GasBill) {
//计算燃气账单
}
...
}
这样就可以用一个方法处理两种子类。

然而,这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现,这是面向对象变成应有的做法,避免回到结构化编程模式。只要提供两个名字和返回值都相同,接受参数类型不同的方法就可以了:

public double calculate(PhoneBill bill) {
//计算电话账单
}

public double calculate(GasBill bill) {
//计算燃气账单
}

所以,使用instanceof在绝大多数情况下并不是推荐的做法,应当好好利用多态。

posted @ 2006-12-20 16:28 flustar 阅读(339) | 评论 (1)编辑 收藏

仅列出标题
共6页: 上一页 1 2 3 4 5 6 下一页 

posts - 54, comments - 143, trackbacks - 0, articles - 0

Copyright © flustar