实战 Groovy: 构建和解析 XML

原贴地址:http://www.ibm.com/developerworks/cn/java/j-pg05199/

 

 

通过本文,您将了解使用 Groovy 分解 XML 是多么地容易。在本期的 实战 Groovy 中,作者 Scott Davis 演示了无论您是使用 MarkupBuilder  StreamingMarkupBuilder 创建 XML,还是使用 XmlParser  XmlSlurper 解析 XML,Groovy 都提供了一系列用于处理这类流行数据格式的工具。

XML 似乎已经由来已久。实际上,XML 在 2008 年迎来了它的 10 年庆典(参见 参考资料)。由于 Java™ 语言只比 XML 早几年出现,因此有人认为对于 Java 开发人员来说,XML  始终存在的。

关于本系列

Groovy 是在 Java 平台上运行的一种现代编程语言。它提供与已有 Java 代码的无缝集成,同时引入了各种生动的新特性,比如说闭包和元编程。简单来讲,Groovy 是 Java 语言的 21 世纪版本。

将任何新工具整合到开发工具包中的关键是知道何时使用它以及何时将它留在工具包中。Groovy 的功能可以非常强大,但惟一的条件是正确应用于适当的场景。因此, 实战 Groovy 系列将探究 Groovy 的实际应用,以便帮助您了解何时以及如何成功使用它们。

Java 语言创始人 Sun Microsystems 一直是 XML 的积极支持者。毕竟,XML 的平台独立性承诺能与 Java 语言的 “编写一次,随处运行” 的口号完美契合。由于这两种技术具备一些相同的特性,您可能会认为 Java 语言和 XML 能很好地相处。事实上,在 Java 语言中解析和生成 XML 不但奇特而且还复杂。

幸运的是,Groovy 引入了一些全新的、更加合理的方法来创建和处理 XML。在一些示例的帮助下(均可通过 下载 获取),本文向您展示了如何通过 Groovy 简化 XML 的构建和解析。

比较 Java 和 Groovy XML 解析

在 “for each 剖析” 的结束部分,我提供了一个如清单 1 所示的简单 XML 文档。(这次,我添加了 type 属性,稍微增加了它的趣味性。)


清单 1. XML 文档,其中列出了我知道的语言

				

  Java
  Groovy
  JavaScript

 

在 Java 语言中解析这个简单的 XML 文档却丝毫不简单,如清单 2 所示。它使用了 30 行代码来解析 5 行 XML 文件。


清单 2. 在 Java 中解析 XML 文件

				
import org.xml.sax.SAXException;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.IOException;

public class ParseXml {
  public static void main(String[] args) {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.parse("src/languages.xml");

      //print the "type" attribute
      Element langs = doc.getDocumentElement();
      System.out.println("type = " + langs.getAttribute("type"));

      //print the "language" elements
      NodeList list = langs.getElementsByTagName("language");
      for(int i = 0 ; i < list.getLength();i++) {
        Element language = (Element) list.item(i);
        System.out.println(language.getTextContent());
      }
    }catch(ParserConfigurationException pce) {
      pce.printStackTrace();
    }catch(SAXException se) {
      se.printStackTrace();
    }catch(IOException ioe) {
      ioe.printStackTrace();
    }
  }
}

 

比较清单 2 中的 Java 代码和清单 3 中相应的 Groovy 代码:


清单 3. 在 Groovy 中解析 XML

				
def langs = new XmlParser().parse("languages.xml")
println "type = ${langs.attribute("type")}"
langs.language.each{
  println it.text()
}

//output:
type = current
Java
Groovy
JavaScript

 

Groovy 代码最出色的地方并不是它要比相应的 Java 代码简短很多 — 虽然使用 5 行 Groovy 代码解析 5 行 XML 是一个压倒性的优势。Groovy 代码最让我欣喜的一个地方就是它更具表达性。在编写 langs.language.each 时,我的感觉就像是在直接操作 XML。在 Java 版本中,您再也看不到 XML。

 




回页首


字符串变量和 XML

当您将 XML 存储在 String 变量而不是文件中时,在 Groovy 中使用 XML 的好处会变得更加明显。Groovy 的三重引号(在其他语言中通常称作 HereDoc)使得在内部存储 XML 变得非常轻松,如清单 4 所示。这与清单 3 中的 Groovy 示例之间的惟一区别就是将 XmlParser 方法调用从 parse()(它处理FileInputStreamsReader  URI)切换到 parseText()


清单 4. 将 XML 存储在 Groovy 内部

				
def xml = """

  Java
  Groovy
  JavaScript

"""

def langs = new XmlParser().parseText(xml)
println "type = ${langs.attribute("type")}"
langs.language.each{
  println it.text()
}

 

注意,三重引号可以轻松地处理多行 XML 文档。xml 变量是一个真正的普通旧式(plain-old)java.lang.String — 您可以添加 println xml.class 自己进行验证。三重引号还可以处理 type="current" 的内部引号,而不会强制您像在 Java 代码中那样使用反斜杠字符手动进行转义。

比较清单 4 中简洁的 Groovy 代码与清单 5 中相应的 Java 代码:


清单 5. 在 Java 代码内部存储 XML

				
import org.xml.sax.SAXException;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;

public class ParseXmlFromString {
  public static void main(String[] args) {
    String xml = "\n" +
            "  Java\n" +
            "  Groovy\n" +
            "  JavaScript\n" +
            "";

    byte[] xmlBytes = xml.getBytes();
    InputStream is = new ByteArrayInputStream(xmlBytes);

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.parse(is);

      //print the "type" attribute
      Element langs = doc.getDocumentElement();
      System.out.println("type = " + langs.getAttribute("type"));

      //print the "language" elements
      NodeList list = langs.getElementsByTagName("language");
      for(int i = 0 ; i < list.getLength();i++) {
        Element language = (Element) list.item(i);
        System.out.println(language.getTextContent());
      }
    }catch(ParserConfigurationException pce) {
      pce.printStackTrace();
    }catch(SAXException se) {
      se.printStackTrace();
    }catch(IOException ioe) {
      ioe.printStackTrace();
    }
  }
}

 

注意,xml 变量受到了针对内部引号和换行符的转义字符的污染。然而,更糟的是需要将 String 转换成一个 byte 数组,然后再转换成 ByteArrayInputStream才能进行解析。DocumentBuilder 未提供将简单 String 作为 XML 解析的直观方法。

 




回页首


通过 MarkupBuilder 创建 XML

Groovy 相对 Java 语言最大的优势体现于在代码中创建 XML 文档。清单 6 显示了创建 5 行 XML 代码段所需的 50 行 Java 代码:


清单 6. 使用 Java 代码创建 XML

				
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;

public class CreateXml {
  public static void main(String[] args) {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.newDocument();

      Element langs = doc.createElement("langs");
      langs.setAttribute("type", "current");
      doc.appendChild(langs);

      Element language1 = doc.createElement("language");
      Text text1 = doc.createTextNode("Java");
      language1.appendChild(text1);
      langs.appendChild(language1);

      Element language2 = doc.createElement("language");
      Text text2 = doc.createTextNode("Groovy");
      language2.appendChild(text2);
      langs.appendChild(language2);

      Element language3 = doc.createElement("language");
      Text text3 = doc.createTextNode("JavaScript");
      language3.appendChild(text3);
      langs.appendChild(language3);

      // Output the XML
      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer transformer = tf.newTransformer();
      transformer.setOutputProperty(OutputKeys.INDENT, "yes");
      StringWriter sw = new StringWriter();
      StreamResult sr = new StreamResult(sw);
      DOMSource source = new DOMSource(doc);
      transformer.transform(source, sr);
      String xmlString = sw.toString();
      System.out.println(xmlString);
    }catch(ParserConfigurationException pce) {
      pce.printStackTrace();
    } catch (TransformerConfigurationException e) {
      e.printStackTrace();
    } catch (TransformerException e) {
      e.printStackTrace();
    }
  }
}

 

我知道一些人会立刻抱怨。许多第三方库都可以简化此代码 — JDOM 和 dom4j 是其中最流行的两个。但是,任何 Java 库都无法与使用 GroovyMarkupBuilder 的简洁性相比,如清单 7 所示:


清单 7. 使用 Groovy 创建 XML

				
def xml = new groovy.xml.MarkupBuilder()
xml.langs(type:"current"){
  language("Java")
  language("Groovy")
  language("JavaScript")
}

 

注意到这与 XML 代码的比率又重新回到了将近 1:1。更加重要的是,我可以再次查看 XML。当然,尖括号已经被替换为大括号,并且属性使用冒号(Groovy 的 HashMap 符号)而不是等号,但其基本结构在 Groovy 或 XML 中都是可以辨认的。它几乎类似于一个用于构建 XML 的 DSL,您认为呢?

Groovy 能够实现这种 Builder 魔法,因为它是一种动态的语言。另一方面,Java 语言则是静态的:Java 编译器将确保所有方法在您调用它们之前都是确实存在的。(如果您尝试调用不存在的方法,Java 代码甚至不进行编译,更不用说运行了。)但是,Groovy 的 Builder 证明,某种语言中的 bug 正是另一种语言的特性。如果您查阅 API 文档中的 MarkupBuilder 相关部分,您会发现它没有 langs() 方法、language() 方法或任何其他元素名称。幸运的是,Groovy 可以捕获这些不存在的方法调用,并采取一些有效的操作。对于 MarkupBuilder 的情况,它使用 phantom 方法调用并生成格式良好的 XML。

清单 8 对我刚才给出的简单的 MarkupBuilder 示例进行了扩展。如果您希望在 String 变量中捕获 XML 输出,则可以传递一个 StringWriter MarkupBuilder 的构造函数中。如果您希望添加更多属性到 langs 中,只需要在传递时使用逗号将它们分开。注意,language 元素的主体是一个没有前置名称的值。您可以在相同的逗号分隔的列表中添加属性和主体。


清单 8. 经过扩展的 MarkupBuilder 示例

				
def sw = new StringWriter()
def xml = new groovy.xml.MarkupBuilder(sw)
xml.langs(type:"current", count:3, mainstream:true){
  language(flavor:"static", version:"1.5", "Java")
  language(flavor:"dynamic", version:"1.6.0", "Groovy")
  language(flavor:"dynamic", version:"1.9", "JavaScript")
}
println sw

//output:

  Java
  Groovy
  JavaScript

 

通过这些 MarkupBuilder 技巧,您可以实现一些有趣的功能。举例来说,您可以快速构建一个格式良好的 HTML 文档,并将它写出到文件中。清单 9 显示了相应的代码:


清单 9. 通过 MarkupBuilder 构建 HTML

				
def sw = new StringWriter()
def html = new groovy.xml.MarkupBuilder(sw)
html.html{
  head{
    title("Links")
  }
  body{
    h1("Here are my HTML bookmarks")
    table(border:1){
      tr{
        th("what")
        th("where")
      }
      tr{
        td("Groovy Articles")
        td{
          a(href:"http://ibm.com/developerworks", "DeveloperWorks")
        }
      }
    }
  }
}

def f = new File("index.html")
f.write(sw.toString())

//output:

  
    Links
  
  
    

Here are my HTML bookmarks

what where
Groovy Articles DeveloperWorks

 

图 1 显示了清单 9 所构建的 HTML 的浏览器视图:


图 1. 呈现的 HTML
呈现的 HTML 




回页首


使用 StreamingMarkupBuilder 创建 XML

MarkupBuilder 非常适合用于同步构建简单的 XML 文档。对于更加高级的 XML 创建,Groovy 提供了一个 StreamingMarkupBuilder。通过它,您可以添加各种各样的 XML 内容,比如说处理指令、名称空间和使用 mkp 帮助对象的未转义文本(非常适合 CDATA 块)。清单 10 展示了有趣的 StreamingMarkupBuilder特性:


清单 10. 使用 StreamingMarkupBuilder 创建 XML

				
def comment = "]]>"
def builder = new groovy.xml.StreamingMarkupBuilder()
builder.encoding = "UTF-8"
def person = {
  mkp.xmlDeclaration()
  mkp.pi("xml-stylesheet": "type='text/xsl' href='myfile.xslt'" )
  mkp.declareNamespace('':'http://myDefaultNamespace')
  mkp.declareNamespace('location':'http://someOtherNamespace')
  person(id:100){
    firstname("Jane")
    lastname("Doe")
    mkp.yieldUnescaped(comment)
    location.address("123 Main")
  }
}
def writer = new FileWriter("person.xml")
writer << builder.bind(person)

//output:



  Jane
  Doe
  ]]>
  123 Main

 

注意,StreamingMarkupBuilder 直到您调用 bind() 方法时才会生成最终的 XML,该方法将接受标记和所有指令。这允许您异步构建 XML 文档的各个部分,并同时输出它们。(参见 参考资料 了解更多信息。)

 




回页首


理解 XmlParser

Groovy 为您提供了两种生成 XML — MarkupBuilder  StreamingMarkupBuilder 的方式 — 它们分别具备不同的功能。解析 XML 也同样如此。您可以使用XmlParser 或者 XmlSlurper

XmlParser 提供了更加以程序员为中心的 XML 文档视图。如果您习惯于使用 List  Map(分别对应于 Element  Attribute)来思考文档,则应该能够适应XmlParser。清单 11 稍微解析了 XmlParser 的结构:


清单 11. XmlParser 详细视图

				
def xml = """

  Java
  Groovy
  JavaScript

"""

def langs = new XmlParser().parseText(xml)
println langs.getClass()
// class groovy.util.Node

println langs
/*
langs[attributes={type=current, count=3, mainstream=true};
      value=[language[attributes={flavor=static, version=1.5};
                      value=[Java]],
             language[attributes={flavor=dynamic, version=1.6.0};
                      value=[Groovy]],
             language[attributes={flavor=dynamic, version=1.9};
                      value=[JavaScript]]
            ]
]
*/

 

注意,XmlParser.parseText() 方法返回了一个 groovy.util.Node — 在本例中是 XML 文档的根 Node。当您调用 println langs 时,它会调用Node.toString() 方法,以便返回调试输出。要获取真实数据,您需要调用 Node.attribute() 或者 Node.text()

 




回页首


使用 XmlParser 获取属性

如前所述,您可以通过调用 Node.attribute("key") 来获取单独的属性。如果您调用 Node.attributes(),它会返回包含所有 Node 的属性的 HashMap。使用您在 “for each 剖析” 一文中所掌握的 each 闭包,遍历每个属性简直就是小菜一碟。清单 12 显示了一个相应的例子。(参见 参考资料,获取关于groovy.util.Node 的 API 文档。)


清单 12. XmlParser 将属性作为 HashMap 对待

				
def langs = new XmlParser().parseText(xml)

println langs.attribute("count")
// 3

langs.attributes().each{k,v->
  println "-" * 15
  println k
  println v
}

//output:
---------------
type
current
---------------
count
3
---------------
mainstream
true

 

与操作属性相类似,XmlParser 为处理元素提供了更好的支持。

 




回页首


使用 XmlParser 获取元素

XmlParser 提供了一种直观的查询元素的方法,称作 GPath。(它与 XPath 类似,仅在 Groovy 中得到了实现。)举例来说,清单 13 演示了我之前使用的langs.language 结构返回了包含查询结构的 groovy.util.NodeListNodeList 扩展了 java.util.ArrayList,因此它基本上就是一个赋予了 GPath 超级权限的 List


清单 13. 使用 GPath  XmlParser 进行查询

				
def langs = new XmlParser().parseText(xml)

// shortcut query syntax
// on an anonymous NodeList
langs.language.each{
  println it.text()
}

// separating the query
// and the each closure
// into distinct parts
def list = langs.language
list.each{
  println it.text()
}

println list.getClass()
// groovy.util.NodeList

 

当然,GPath 是对 MarkupBuilder 的补充。它所采用的技巧与调用不存在的 phantom 方法相同,区别仅在于它用于查询已有的 XML 而不是动态地生成 XML。

知道 GPath 查询的结果是 List 之后,您可以让您的代码更加简练。Groovy 提供了一个 spread-dot 运算符。在单行代码中,它基本上能迭代整个列表并对每个项执行方法调用。结果将作为 List 返回。举例来说,如果您只关心对查询结果中的各个项调用 Node.text() 方法,那么清单 14 展示了如何在一行代码中实现它:


清单 14. 结合 spread-dot 运算符与 GPath 

				
// the long way of gathering the results
def results = []
langs.language.each{
  results << it.text()
}

// the short way using the spread-dot operator
def values = langs.language*.text()
// [Java, Groovy, JavaScript]

// quickly gathering up all of the version attributes
def versions = langs.language*.attribute("version")
// [1.5, 1.6.0, 1.9]

 

和功能强大的 XmlParser 一样,XmlSlurper 也实现了更高级别的处理。

 




回页首


使用 XmlSlurper 解析 XML

 清单 2 中,我说过 Groovy 给我的感觉是在直接操作 XML。XmlParser 的功能相当不错,但它只允许您以编程的方式来操作 XML。您可以使用由 Node 组成的 List 以及由 Attribute 组成的 HashMap,并且仍然需要调用 Node.attribute()  Node.text() 等方法才能获取核心数据。XmlSlurper 将删除方法调用的最后痕迹,让您感觉就像是在直接处理 XML。

从技术上说,XmlParser 返回 Node  NodeList,而 XmlSlurper 返回一个 groovy.util.slurpersupport.GPathResult。但既然您已经知道,因此我希望您能忘记之前提到的 XmlSlurper 的实现细节。如果您能忽略其内部原理,那么将更好地领略其魔力。

清单 15 同时展示了一个 XmlParser 和一个 XmlSlurper


清单 15. XmlParser  XmlSlurper 

				
def xml = """

  Java
  Groovy
  JavaScript

"""

def langs = new XmlParser().parseText(xml)
println langs.attribute("count")
langs.language.each{
  println it.text()
}

langs = new XmlSlurper().parseText(xml)
println langs._cnnew1@count
langs.language.each{
  println it
}

 

注意,XmlSlurper 忽略了任何方法调用的概念。您并没有调用 langs.attribute("count"),而是调用了 langs.@count@ 符号是从 XPath 借过来的,但其结果是,您感觉像是在直接操作属性(与调用 attribute() 方法相反)。您没有调用 it.text(),而仅仅调用了 it。我们假设您希望直接操作元素的内容。

 




回页首


现实中的 XmlSlurper

除了 langs  language 之外,这里还提供了实际的 XmlSlurper 示例。Yahoo! 以 RSS 提要的方式按 ZIP 码提供天气情况信息。当然,RSS 是 XML 中的一种专门术语。在 Web 浏览器中键入 http://weather.yahooapis.com/forecastrss?p=80020。可以随意将 Broomfield, Colorado 的 ZIP 码换成您自己的。清单 16 显示了最终 RSS 提要的简单版本:


清单 16. 显示最新天气情况的 Yahoo! RSS 提要

				

  
    Yahoo! Weather - Broomfield, CO
    
    

    
      Conditions for Broomfield, CO at 7:47 am MST
      Fri, 27 Feb 2009 7:47 am MST
      
    
  

 

您要做的第一件事就是通过编程来使用这个 RSS。创建一个名称为 weather.groovy 的文件,并添加如清单 17 所示的代码:


清单 17. 以编程的方式获取 RSS

				
def baseUrl = "http://weather.yahooapis.com/forecastrss"

if(args){
  def zip = args[0]
  def url = baseUrl + "?p=" + zip
  def xml = url.toURL().text
  println xml
}else{
  println "USAGE: weather zipcode"
}

 

在命令行中键入 groovy weather 80020,确定您可以看到原始 RSS。

此脚本最重要的部分是 url.toURL().texturl 变量是一个格式良好的 String。Groovy 在所有 String 中都添加了一个 toURL() 方法,用于将它们转换成java.net.URL。然后,Groovy 在所有 URL 中又添加了一个 getText() 方法,用于执行 HTTP GET 请求并将结构作为 String 返回。

现在,您已经将 RSS 存储在了 xml 变量中,并通过 XmlSlurper 实现了一些有趣的功能,如清单 18 所示:


清单 18. 使用 XmlSlurper 解析 RSS

				
def baseUrl = "http://weather.yahooapis.com/forecastrss"

if(args){
  def zip = args[0]
  def url = baseUrl + "?p=" + zip
  def xml = url.toURL().text

  def rss = new XmlSlurper().parseText(xml)
  println rss.channel.title
  println "Sunrise: ${rss.channel.astronomy.@sunrise}"
  println "Sunset: ${rss.channel.astronomy.@sunset}"
  println "Currently:"
  println "\t" + rss.channel.item.condition.@date
  println "\t" + rss.channel.item.condition.@temp
  println "\t" + rss.channel.item.condition.@text
}else{
  println "USAGE: weather zipcode"
}

//output:
Yahoo! Weather - Broomfield, CO
Sunrise: 6:36 am
Sunset: 5:50 pm
Currently:
   Fri, 27 Feb 2009 7:47 am MST
   25
   Partly Cloudy

 

XmlSlurper 让您可以自然地处理 XML,不是吗?您通过直接引用 </code><span class="Apple-converted-space"> </span>元素来打印它 —<span class="Apple-converted-space"> </span><code>rss.channel.title</code>。您使用一个简单的<code>rss.channel.item.condition.@temp</code><span class="Apple-converted-space"> </span>来去除<span class="Apple-converted-space"> </span><code>temp</code><span class="Apple-converted-space"> </span>属性。这与编程的感觉不同。它更像是在直接操作 XML。</p> <p>您是否注意到<span class="Apple-converted-space"> </span><code>XmlSlurper</code><span class="Apple-converted-space"> </span>甚至忽略了名称空间?您在构造函数中启用名称空间感知,但我很少这样做。非常简单,<code>XmlSlurper</code><span class="Apple-converted-space"> </span>能像切黄油那样分解 XML。</p> <p> </p> <table border="0" width="100%"> <tbody> <tr> <td style="line-height:19px;"> <br></td> </tr> </tbody> </table> <table class="no-print" border="0" align="right"> <tbody> <tr align="right"> <td style="line-height:19px;"> <br> <table border="0"> <tbody> <tr> <td style="line-height:19px;" valign="middle"> <br></td> <td style="line-height:19px;" align="right" valign="top"><strong>回页首</strong></td> </tr> </tbody> </table></td> </tr> </tbody> </table> <p><br></p> <p><span class="atitle" style="font-family:Arial, sans-serif;font-size:18px;font-weight:bold;">结束语</span></p> <p>要在如今成为一名成功的开发人员,您需要一系列能简化 XML 处理的工具。Groovy 的<span class="Apple-converted-space"> </span><code>MarkupBuilder</code><span class="Apple-converted-space"> </span>和<span class="Apple-converted-space"> </span><code>StreamingMarkupBuilder</code><span class="Apple-converted-space"> </span>可以非常轻松地动态创建 XML。<code>XmlParser</code><span class="Apple-converted-space"> </span>能为您提供由<span class="Apple-converted-space"> </span><code>Element</code><span class="Apple-converted-space"> </span>组成的<span class="Apple-converted-space"> </span><code>List</code><span class="Apple-converted-space"> </span>以及由<span class="Apple-converted-space"> </span><code>Attribute</code><span class="Apple-converted-space"> </span>组成的<span class="Apple-converted-space"> </span><code>HashMap</code>,并且<span class="Apple-converted-space"> </span><code>XmlSlurper</code><span class="Apple-converted-space"> </span>可以让代码全部消失,让您感觉是在直接操作 XML。</p> <p>如果没有 Groovy 的动态功能,XML 处理的强大功能将不可能实现。在下一章文章中,</p> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1175417949897437184"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(Groovy)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1834778982680195072.htm" title="Groovy -> Groovy 流程控制语句" target="_blank">Groovy -> Groovy 流程控制语句</a> <span class="text-muted">Yang-Never</span> <a class="tag" taget="_blank" href="/search/Groovy/1.htm">Groovy</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/gradle/1.htm">gradle</a><a class="tag" taget="_blank" href="/search/idea/1.htm">idea</a> <div>判断语句defx=10if(x>0){println"xispositive"}elseif(x0)?"positive":"non-positive"printlnresult//输出"positive"//log"positive"分支语句//分支语句判断数据类型defcheckType(value){switch(value){caseInteger:println"Thevalueisan</div> </li> <li><a href="/article/1834778984429219840.htm" title="Groovy -> Groovy 集合操作" target="_blank">Groovy -> Groovy 集合操作</a> <span class="text-muted">Yang-Never</span> <a class="tag" taget="_blank" href="/search/Groovy/1.htm">Groovy</a><a class="tag" taget="_blank" href="/search/gradle/1.htm">gradle</a><a class="tag" taget="_blank" href="/search/idea/1.htm">idea</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>List的增删改查[1,2,3,4][1,2,3,4,5,6][2,3,4][3,4][1,2,3,4][3,4,10][3,4,20]Element:3Element:4Element:20contains3//log[1,2,3,4][1,2,3,4,5,6][2,3,4][3,4][1,2,3,4][3,4,10][3,4,20]Element:3Element:4Element:20con</div> </li> <li><a href="/article/1832566135942377472.htm" title="Groovy入门基础" target="_blank">Groovy入门基础</a> <span class="text-muted">winton_by</span> <a class="tag" taget="_blank" href="/search/Groovy/1.htm">Groovy</a><a class="tag" taget="_blank" href="/search/Gradle/1.htm">Gradle</a><a class="tag" taget="_blank" href="/search/Android/1.htm">Android</a> <div>文章目录基本概念环境搭建下载groovy的manSDK(Macos)安装groovy下载IDEA配置groovyHelloWorldGroovy语法精讲文件结构变量类型字符串‘xx’"xx"'''xx'''闭包(类似java8中的lambda表达式)必包的使用场景数据结构列表列表转数组列表排序数组映射(map)范围类动态添加属性&方法(很神奇)Json操作xml操作总结Android的学习过程中,</div> </li> <li><a href="/article/1832562600467066880.htm" title="IntelliJ IDEA 中安装 Groovy 插件 && 添加 Groovy SDK" target="_blank">IntelliJ IDEA 中安装 Groovy 插件 && 添加 Groovy SDK</a> <span class="text-muted">秋夫人</span> <a class="tag" taget="_blank" href="/search/intellij-idea/1.htm">intellij-idea</a><a class="tag" taget="_blank" href="/search/Groovy/1.htm">Groovy</a> <div>一、在IntelliJIDEA中安装Groovy插件可以按照以下步骤进行:打开IntelliJIDEA:启动IntelliJIDEA。打开插件市场:进入File->Settings(在macOS上是IntelliJIDEA->Preferences)。在左侧菜单中选择Plugins。搜索Groovy插件:在插件市场的右上角搜索框中输入Groovy。找到Groovy插件。安装插件:点击Install</div> </li> <li><a href="/article/1832546966773526528.htm" title="Groovy快速入门" target="_blank">Groovy快速入门</a> <span class="text-muted">小码快撩</span> <a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>Groovy是一种面向对象的、动态类型的、基于JVM的编程语言,它与Java高度兼容,同时引入了许多简洁、灵活的语法特性,使得开发更为高效。以下是Groovy的快速入门指南:一.环境准备1.安装JavaDevelopmentKit(JDK)Groovy是基于Java平台的语言,运行在Java虚拟机(JVM)之上,因此必须先确保系统中已安装了JDK。下载并安装适合您操作系统的最新稳定版JDK。可以从</div> </li> <li><a href="/article/1832544320998174720.htm" title="Groovy入门(有java基础)" target="_blank">Groovy入门(有java基础)</a> <span class="text-muted">black_dawn</span> <a class="tag" taget="_blank" href="/search/groovy/1.htm">groovy</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>一、基本概念Groovy是一种基于Java虚拟机(JVM)的动态开发语言,旨在扩展Java语法,提供更简洁、灵活和易于使用的编码方式。本文是在会一定java语言开发的基础上进行的对比入门学习记录。1.特点:动态性:Groovy支持动态类型和动态元编程,使得代码更加灵活和易于编写。简洁性:Groovy的语法相对于Java来说更加简洁,可以用更少的代码实现相同的功能。闭包:Groovy提供了强大的闭包</div> </li> <li><a href="/article/1827963886335258624.htm" title="Android开之AR增强现实技术ARCore组件的应用方法" target="_blank">Android开之AR增强现实技术ARCore组件的应用方法</a> <span class="text-muted">cdesigner</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/ar/1.htm">ar</a> <div>ARCore是Google提供的用于Android设备的AR平台,它提供了许多组件和功能,用于实现增强现实(AR)应用。以下是使用ARCore组件的应用方法和代码示例:配置ARCore环境:在项目的build.gradle文件中,添加ARCore库的依赖项:groovydependencies{  implementation'com.google.ar:core:1.24.0'}在应用启动时,需</div> </li> <li><a href="/article/1830239223190482944.htm" title="Gradle介绍和下载" target="_blank">Gradle介绍和下载</a> <span class="text-muted">上善若泪</span> <div>1Gradle1.1介绍gradle和maven一样都是用来构建java程序的,maven2004年开始兴起,gradle2012年开始诞生,既然已经有了maven这么成熟的构建工具为什么还有gradle的诞生呢,因为gradle有很多地方比maven做的更好,例如gradle采用groovy语言开发,语法更加简单,例如maven一个配置需要三行,而gradle只需要一行即可Gradle是继Mav</div> </li> <li><a href="/article/1772035760141172736.htm" title="最新版android stuido加上namespace" target="_blank">最新版android stuido加上namespace</a> <span class="text-muted">修行者对666</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/studio%E9%85%8D%E7%BD%AE%E9%97%AE%E9%A2%98/1.htm">studio配置问题</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>每个Android模块都有一个命名空间,此命名空间用作其生成的命名空间由模块的build.gradle文件中的namespace属性定义,如以下代码段所示。namespace最初会设为您在创建项目时选择的软件包名称。KotlinGroovyandroid{namespace"com.example.myapp"...}在将应用构建为最终应用软件包(APK)时,Android构建工具会将命名空间用作</div> </li> <li><a href="/article/1761141719023276032.htm" title="UE5 打包安卓报错LogPlayLevel: UAT: at org.codehaus.groovy.vmplugin.v7.Java7" target="_blank">UE5 打包安卓报错LogPlayLevel: UAT: at org.codehaus.groovy.vmplugin.v7.Java7</a> <span class="text-muted">htwzl</span> <a class="tag" taget="_blank" href="/search/ue5/1.htm">ue5</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%8D%93/1.htm">安卓</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>LogPlayLevel:UAT:atjava.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)LogPlayLevel:UAT:atorg.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.ru</div> </li> <li><a href="/article/1759827281502629888.htm" title="pipeline 语法及常见DSL" target="_blank">pipeline 语法及常见DSL</a> <span class="text-muted">wuleijack</span> <div>jenkinspipeline是jenkins实现持续集成持续部署最核心的部分,pipeline编写2种脚本式和声明式(官方推荐)声明式主要的需要的语法pipeline{agent{}options{}envirment{}stages{stage('build'){steps{script{}}}}}其实脚本式和声明可以相互转换所谓脚本式默认就是groovy脚本当然也可以把脚本写在script中</div> </li> <li><a href="/article/1759573664543633408.htm" title="【Java】电子凭证-Java生成PDF" target="_blank">【Java】电子凭证-Java生成PDF</a> <span class="text-muted">hkk666123</span> <a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/HTML/1.htm">HTML</a><a class="tag" taget="_blank" href="/search/%E8%BD%AC/1.htm">转</a><a class="tag" taget="_blank" href="/search/PDF/1.htm">PDF</a><a class="tag" taget="_blank" href="/search/htmlTOPDF/1.htm">htmlTOPDF</a> <div>文章目录背景实现思路技术方案图TemplateEngines(模板引擎)`Thymeleaf``ApacheFreemarker``GroovyTemplates``velocity``HTMLTOPDF`技术各实现对比表WKhtmlTOpdfiTextPhantomJS技术核心:HTML生成PDF背景在某些业务场景中,需要提供相关的电子凭证,比如网银/支付宝中转账的电子回单,签约的电子合同等。方</div> </li> <li><a href="/article/1759548708988481536.htm" title="Android Weekly Notes #430" target="_blank">Android Weekly Notes #430</a> <span class="text-muted">圣骑士wind</span> <div>AndroidWeeklyIssue#430SuperchargeAndroiddevwithScrcpyandADBWIFI这个工具:https://github.com/Genymobile/scrcpy#get-the-app可以把物理设备投屏到电脑上.GradlekotlinDSL把gradle脚本从groovy迁移到kotlin.20AndroidDevToolsYou’veProbab</div> </li> <li><a href="/article/1759495744919777280.htm" title="Java零基础到传奇的必经之路,你准备好了吗?" target="_blank">Java零基础到传奇的必经之路,你准备好了吗?</a> <span class="text-muted">「已注销」</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a><a class="tag" taget="_blank" href="/search/%E7%A8%8B%E5%BA%8F%E4%BA%BA%E7%94%9F/1.htm">程序人生</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a> <div>基础篇01面向对象→什么是面向对象面向对象、面向过程面向对象的三大基本特征和五大基本原则→平台无关性Java如何实现的平台无关JVM还支持哪些语言(Kotlin、Groovy、JRuby、Jython、Scala)→值传递值传递、引用传递为什么说Java中只有值传递→封装、继承、多态什么是多态、方法重写与重载Java的继承与实现构造函数与默认构造函数类变量、成员变量和局部变量成员变量和方法作用域0</div> </li> <li><a href="/article/1759418522544451584.htm" title="RapidMiner缺失数据处理——去掉数据大量缺失的变量" target="_blank">RapidMiner缺失数据处理——去掉数据大量缺失的变量</a> <span class="text-muted">carlwu</span> <a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a><a class="tag" taget="_blank" href="/search/RapidMiner/1.htm">RapidMiner</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a><a class="tag" taget="_blank" href="/search/RapidMiner/1.htm">RapidMiner</a><a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/R%E8%AF%AD%E8%A8%80/1.htm">R语言</a> <div>最近做数据挖掘,发现RapidMiner是一款数据清洗、处理和转换的好工具,尤其在数据量不大的情况下。和R语言相比,RapidMiner在数据处理方面要简单直观得多。虽然RapidMiner的功能可能不如R强大。另外,我们也可以在RapidMiner中可以直接利用Java/Groovy来编写程序,对数据进行处理和转换。现在以RapidMiner6.0为例,来说明一下如何写一段小程序,去掉那些数据缺</div> </li> <li><a href="/article/1757950552597086208.htm" title="Android 和 IOS 的 11 种最佳移动测试工具和Groovy Junit5" target="_blank">Android 和 IOS 的 11 种最佳移动测试工具和Groovy Junit5</a> <span class="text-muted">ADADACHAN</span> <div>2021年适用于Android和IOS的15种最佳移动测试工具最佳移动应用测试工具和自动化框架的列表和比较:您是否正在寻找将移动测试策略提升到新水平的方法?有无数种方法可以做到这一点,但你的时间和金钱有限。即使您认为自己是移动应用程序测试方面的专家,也总有改进的余地。您需要知道要实施哪些策略,最重要的是要知道要使用哪些工具。在这篇文章中,我们将探索最佳的移动测试工具,以提高您的Android和iO</div> </li> <li><a href="/article/1757806252462718976.htm" title="Katalon Studio - 自用tips" target="_blank">Katalon Studio - 自用tips</a> <span class="text-muted">pumpkin1111</span> <div>1.运行时用代码创建全局变量or给全局变量重新赋值:创建自定义keywords,或者testcase里的自定义方法@KeywordvoidaddGlobalVariable(Stringname,defvalue){GroovyShellshell1=newGroovyShell()MetaClassmc=shell1.evaluate("internal.GlobalVariable").met</div> </li> <li><a href="/article/1757524325381980160.htm" title="【JVM篇】什么是jvm" target="_blank">【JVM篇】什么是jvm</a> <span class="text-muted">在下小吉.</span> <a class="tag" taget="_blank" href="/search/JVM/1.htm">JVM</a><a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>文章目录什么是Java虚拟机Java虚拟机有什么用Java虚拟机的功能Java虚拟机的组成什么是Java虚拟机JVM指的是Java虚拟机,本质上是一个运行在计算机上的程序,可以运行Java字节码文件,可以运行Java,kotlin,Scala,groovy等语言任务管理器启动的Java进程,其实是一个虚拟机进程,它会执行我们编写好的代码比如我们编写并运行一个Java程序,在进程中就能够看到impo</div> </li> <li><a href="/article/1757281083059093504.htm" title="AndroidStudio build.gradle 配置" target="_blank">AndroidStudio build.gradle 配置</a> <span class="text-muted">给我一支白沙</span> <div>AndroidStudiobuild.gradle配置AndroidStudio是通过gradle来构建项目,gradle基于groovy语言。当用AndroidStudio创建工程时,会生成两个build.gradle文件,一个是工程的build.gradle文件,另一个是moduleapp的build.gradle文件,接下来进行详细的介绍工程build.gradle文件作用用于对整个工程进行</div> </li> <li><a href="/article/1756936442614923264.htm" title="Aviator——轻量级JAVA规则引擎" target="_blank">Aviator——轻量级JAVA规则引擎</a> <span class="text-muted">老鼠AI大米_Java全栈</span> <div>Aviator是一个高性能、轻量级的java语言实现的表达式求值引擎,主要用于各种表达式的动态求值。现在已经有很多开源可用的java表达式求值引擎,为什么还需要Avaitor呢?简介Aviator的设计目标是轻量级和高性能,相比于Groovy、JRuby的笨重,Aviator非常小,加上依赖包也才450K,不算依赖包的话只有70K;当然,Aviator的语法是受限的,它不是一门完整的语言,而只是语</div> </li> <li><a href="/article/1756776552105787392.htm" title="Groovy 2.5 下载安装和环境变量配置" target="_blank">Groovy 2.5 下载安装和环境变量配置</a> <span class="text-muted">U离态</span> <div>Groovy下载参考Groovy官方网站的页面页面,下载Groovy2.5版本的binary(二进制)文件。Groovy的二进制文件里是同时包含Linux/MacOS/Windows的二进制程序的,所以不用担心平台问题,下就完了:)为了方便,下载连接在这里放一份:Groovy-2.5.8关于版本这里说明一下,本文写作时(2020年1月)Groovy3.0是最新版(bleedingedge),但本着</div> </li> <li><a href="/article/1756651878994690048.htm" title="chap6 类文件结构" target="_blank">chap6 类文件结构</a> <span class="text-muted">菜鸟乱撞</span> <div>1.无关性的基石java虚拟机提供的语言无关性的基础是虚拟机和存储格式。java虚拟机不和任何语言绑定,仅与“class文件”这种特定的二进制文件格式相关联。在java虚拟上运行的其他语言,如JRuby、Groovy等都通过编译器编译为.class文件后有java虚拟机执行。2.class类文件结构class文件是一组以8位字节为基础单位的二进制流,各个数据项严格按照顺序无间隔的排列在class文</div> </li> <li><a href="/article/1756623155583008768.htm" title="SpringBoot项目" target="_blank">SpringBoot项目</a> <span class="text-muted"></span> <a class="tag" taget="_blank" href="/search/springboot/1.htm">springboot</a> <div>一、关于SpringBoot介绍1.什么是SpringBootSpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。随着动态语言的流行(Ruby、Groovy、Scala、Node.js)。java的开发显的格外的笨重,繁多的配置,低下的开发效率、复杂的部署流程以及第三方技术集成难度大。在上述环境中springboot应运而生。它使</div> </li> <li><a href="/article/1756438459087601664.htm" title="Groovy<第一篇>:Groovy 前言" target="_blank">Groovy<第一篇>:Groovy 前言</a> <span class="text-muted">NoBugException</span> <div>Groovy是一种基于Java平台的面向对象语言。[Groovy的特点][一]同时支持静态和动态类型。[二]支持运算符重载。[三]本地语法列表和关联数组。[四]对正则表达式的本地支持。[五]各种标记语言,如XML和HTML原生支持。[六]Groovy对于Java开发人员来说很简单,因为Java和Groovy的语法非常相似。[七]您可以使用现有的Java库。[八]Groovy扩展了java.lang</div> </li> <li><a href="/article/1756119988143407104.htm" title="ubuntu之制作再生龙(Clonezilla)启动盘" target="_blank">ubuntu之制作再生龙(Clonezilla)启动盘</a> <span class="text-muted">ancy_i_cv</span> <a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a> <div>1.下载再生龙(Clonezilla)镜像:下载地址:http://clonezilla.nchc.org.tw/clonezilla-live/download/下载的文件:clonezilla-live-20210127-groovy-amd64.zip。2.查看u盘的挂载信息1)插入u盘后运行:sudofdisk-lDisk/dev/sdb:7969MB,7969177600bytes255</div> </li> <li><a href="/article/1755771677867786240.htm" title="sonarqube安装" target="_blank">sonarqube安装</a> <span class="text-muted">alterem</span> <div>一.SonarQube代码质量检查工具简介Sonar(SonarQube)是一个开源平台,用于管理源代码的质量Sonar不只是一个质量数据报告工具,更是代码质量管理平台支持Java,C#,C/C++,PL/SQL,Cobol,JavaScrip,Groovy等等二十几种编程语言的代码质量管理与检测。Sonar可以从以下七个维度检测代码质量,而作为开发人员至少需要处理前5种代码质量问题。不遵循代码标</div> </li> <li><a href="/article/1755763772699459584.htm" title="Android的视图绑定" target="_blank">Android的视图绑定</a> <span class="text-muted">Procahr</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>视图绑定(ViewBinding)在开发中起到的作用是代替findViewById。初始设置ViewBinding是按模块启动的,在使用之前需要在模块中的gradle中开启ViewBinding。//kotlinandroid{...buildFeatures{viewBinding=true}}//groovyandroid{...buildFeatures{viewBindingtrue}}使</div> </li> <li><a href="/article/1755398881111195648.htm" title="IDEA实用小技巧--YYDS" target="_blank">IDEA实用小技巧--YYDS</a> <span class="text-muted">Flying_Fish_roe</span> <a class="tag" taget="_blank" href="/search/intellij-idea/1.htm">intellij-idea</a><a class="tag" taget="_blank" href="/search/pycharm/1.htm">pycharm</a><a class="tag" taget="_blank" href="/search/ide/1.htm">ide</a> <div>查看代码历史版本演示如下:调整idea的虚拟内存演示如下:idea设置快捷键演示如下:设置提示词忽略大小写演示如下:关闭代码检查演示如下:设置文档注释模板演示如下:首先建立组:我建立的是xuan模板示例/***Description:*date:$DATE$$TIME$*@author:作者名称*@sinceJDK1.8*/带参数的选择groovyScript("defresult='';defs</div> </li> <li><a href="/article/1755344843950800896.htm" title="Gradle的安装与配置" target="_blank">Gradle的安装与配置</a> <span class="text-muted">Love为何</span> <div>1.Gradle简介Gradle是源于ApacheAnt和ApacheMaven概念的项目自动化构建开源工具,它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置面向Java应用为主。当前其支持的语言暂时有Java、Groovy、Kotlin和Scala。Gradle是一个基于JVM的构建工具,是一款通用灵活的构建工具,支持maven,Ivy仓库,支持传</div> </li> <li><a href="/article/1755141263868313600.htm" title="【Android Gradle 插件】自定义 Gradle 插件模块 ⑤ ( 完整总结 )" target="_blank">【Android Gradle 插件】自定义 Gradle 插件模块 ⑤ ( 完整总结 )</a> <span class="text-muted">修行者对666</span> <a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%8D%93gradle/1.htm">安卓gradle</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>一、创建自定义插件类型模块(JavaorKotlinLibrary)选择"菜单栏/New/NewModule…"选项,在"CreateNewModule"对话框中,选择创建"JavaorKotlinLibrary"类型的依赖库;二、手动导入相关依赖(Java|Groovy|Gradle)在buildSrc目录下,会自动引入Java/Groovy/Gradle的依赖,但是在自己创建的JavaLibr</div> </li> <li><a href="/article/52.htm" title="解读Servlet原理篇二---GenericServlet与HttpServlet" target="_blank">解读Servlet原理篇二---GenericServlet与HttpServlet</a> <span class="text-muted">周凡杨</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/HttpServlet/1.htm">HttpServlet</a><a class="tag" taget="_blank" href="/search/%E6%BA%90%E7%90%86/1.htm">源理</a><a class="tag" taget="_blank" href="/search/GenericService/1.htm">GenericService</a><a class="tag" taget="_blank" href="/search/%E6%BA%90%E7%A0%81/1.htm">源码</a> <div>在上一篇《解读Servlet原理篇一》中提到,要实现javax.servlet.Servlet接口(即写自己的Servlet应用),你可以写一个继承自javax.servlet.GenericServletr的generic Servlet ,也可以写一个继承自java.servlet.http.HttpServlet的HTTP Servlet(这就是为什么我们自定义的Servlet通常是exte</div> </li> <li><a href="/article/179.htm" title="MySQL性能优化" target="_blank">MySQL性能优化</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/mysql/1.htm">mysql</a> <div>        性能优化是通过某些有效的方法来提高MySQL的运行速度,减少占用的磁盘空间。性能优化包含很多方面,例如优化查询速度,优化更新速度和优化MySQL服务器等。本文介绍方法的主要有:         a.优化查询         b.优化数据库结构   </div> </li> <li><a href="/article/306.htm" title="ThreadPool定时重试" target="_blank">ThreadPool定时重试</a> <span class="text-muted">dai_lm</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/ThreadPool/1.htm">ThreadPool</a><a class="tag" taget="_blank" href="/search/thread/1.htm">thread</a><a class="tag" taget="_blank" href="/search/timer/1.htm">timer</a><a class="tag" taget="_blank" href="/search/timertask/1.htm">timertask</a> <div>项目需要当某事件触发时,执行http请求任务,失败时需要有重试机制,并根据失败次数的增加,重试间隔也相应增加,任务可能并发。 由于是耗时任务,首先考虑的就是用线程来实现,并且为了节约资源,因而选择线程池。 为了解决不定间隔的重试,选择Timer和TimerTask来完成 package threadpool; public class ThreadPoolTest { </div> </li> <li><a href="/article/433.htm" title="Oracle 查看数据库的连接情况" target="_blank">Oracle 查看数据库的连接情况</a> <span class="text-muted">周凡杨</span> <a class="tag" taget="_blank" href="/search/sql/1.htm">sql</a><a class="tag" taget="_blank" href="/search/oracle+%E8%BF%9E%E6%8E%A5/1.htm">oracle 连接</a> <div>首先要说的是,不同版本数据库提供的系统表会有不同,你可以根据数据字典查看该版本数据库所提供的表。 select * from dict where table_name like '%SESSION%'; 就可以查出一些表,然后根据这些表就可以获得会话信息 select sid,serial#,status,username,schemaname,osuser,terminal,ma</div> </li> <li><a href="/article/560.htm" title="类的继承" target="_blank">类的继承</a> <span class="text-muted">朱辉辉33</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>类的继承可以提高代码的重用行,减少冗余代码;还能提高代码的扩展性。Java继承的关键字是extends 格式:public class 类名(子类)extends 类名(父类){ } 子类可以继承到父类所有的属性和普通方法,但不能继承构造方法。且子类可以直接使用父类的public和 protected属性,但要使用private属性仍需通过调用。 子类的方法可以重写,但必须和父类的返回值类</div> </li> <li><a href="/article/687.htm" title="android 悬浮窗特效" target="_blank">android 悬浮窗特效</a> <span class="text-muted">肆无忌惮_</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>最近在开发项目的时候需要做一个悬浮层的动画,类似于支付宝掉钱动画。但是区别在于,需求是浮出一个窗口,之后边缩放边位移至屏幕右下角标签处。效果图如下:   一开始考虑用自定义View来做。后来发现开线程让其移动很卡,ListView+动画也没法精确定位到目标点。   后来想利用Dialog的dismiss动画来完成。   自定义一个Dialog后,在styl</div> </li> <li><a href="/article/814.htm" title="hadoop伪分布式搭建" target="_blank">hadoop伪分布式搭建</a> <span class="text-muted">林鹤霄</span> <a class="tag" taget="_blank" href="/search/hadoop/1.htm">hadoop</a> <div>要修改4个文件    1: vim hadoop-env.sh  第九行    2: vim core-site.xml            <configuration>     &n</div> </li> <li><a href="/article/941.htm" title="gdb调试命令" target="_blank">gdb调试命令</a> <span class="text-muted">aigo</span> <a class="tag" taget="_blank" href="/search/gdb/1.htm">gdb</a> <div>原文:http://blog.csdn.net/hanchaoman/article/details/5517362   一、GDB常用命令简介   r run 运行.程序还没有运行前使用 c             cuntinue </div> </li> <li><a href="/article/1068.htm" title="Socket编程的HelloWorld实例" target="_blank">Socket编程的HelloWorld实例</a> <span class="text-muted">alleni123</span> <a class="tag" taget="_blank" href="/search/socket/1.htm">socket</a> <div>public class Client { public static void main(String[] args) { Client c=new Client(); c.receiveMessage(); } public void receiveMessage(){ Socket s=null; BufferedRea</div> </li> <li><a href="/article/1195.htm" title="线程同步和异步" target="_blank">线程同步和异步</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/%E7%BA%BF%E7%A8%8B%E5%90%8C%E6%AD%A5/1.htm">线程同步</a><a class="tag" taget="_blank" href="/search/%E5%BC%82%E6%AD%A5/1.htm">异步</a> <div>多线程和同步 : 如进程、线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作。 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其它线程也不能调用这个方法   多线程和异步:多线程可以做不同的事情,涉及到线程通知     &</div> </li> <li><a href="/article/1322.htm" title="JSP中文乱码分析" target="_blank">JSP中文乱码分析</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/jsp/1.htm">jsp</a><a class="tag" taget="_blank" href="/search/%E4%B8%AD%E6%96%87%E4%B9%B1%E7%A0%81/1.htm">中文乱码</a> <div>        在JSP的开发过程中,经常出现中文乱码的问题。         首先了解一下Java中文问题的由来:         Java的内核和class文件是基于unicode的,这使Java程序具有良好的跨平台性,但也带来了一些中文乱码问题的麻烦。原因主要有两方面,</div> </li> <li><a href="/article/1449.htm" title="js实现页面跳转重定向的几种方式" target="_blank">js实现页面跳转重定向的几种方式</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/%E9%87%8D%E5%AE%9A%E5%90%91/1.htm">重定向</a> <div>        js实现页面跳转重定向有如下几种方式: 一.window.location.href <script language="javascript"type="text/javascript"> window.location.href="http://www.baidu.c</div> </li> <li><a href="/article/1576.htm" title="【Struts2三】Struts2 Action转发类型" target="_blank">【Struts2三】Struts2 Action转发类型</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/struts2/1.htm">struts2</a> <div> 在【Struts2一】 Struts Hello World http://bit1129.iteye.com/blog/2109365中配置了一个简单的Action,配置如下   <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configurat</div> </li> <li><a href="/article/1703.htm" title="【HBase十一】Java API操作HBase" target="_blank">【HBase十一】Java API操作HBase</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/hbase/1.htm">hbase</a> <div>Admin类的主要方法注释:   1. 创建表 /** * Creates a new table. Synchronous operation. * * @param desc table descriptor for table * @throws IllegalArgumentException if the table name is res</div> </li> <li><a href="/article/1830.htm" title="nginx gzip" target="_blank">nginx gzip</a> <span class="text-muted">ronin47</span> <a class="tag" taget="_blank" href="/search/nginx+gzip/1.htm">nginx gzip</a> <div>Nginx GZip 压缩 Nginx GZip 模块文档详见:http://wiki.nginx.org/HttpGzipModule 常用配置片段如下: gzip on; gzip_comp_level 2; # 压缩比例,比例越大,压缩时间越长。默认是1 gzip_types text/css text/javascript; # 哪些文件可以被压缩 gzip_disable &q</div> </li> <li><a href="/article/1957.htm" title="java-7.微软亚院之编程判断俩个链表是否相交 给出俩个单向链表的头指针,比如 h1 , h2 ,判断这俩个链表是否相交" target="_blank">java-7.微软亚院之编程判断俩个链表是否相交 给出俩个单向链表的头指针,比如 h1 , h2 ,判断这俩个链表是否相交</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div> public class LinkListTest { /** * we deal with two main missions: * * A. * 1.we create two joined-List(both have no loop) * 2.whether list1 and list2 join * 3.print the join</div> </li> <li><a href="/article/2084.htm" title="Spring源码学习-JdbcTemplate batchUpdate批量操作" target="_blank">Spring源码学习-JdbcTemplate batchUpdate批量操作</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div>Spring JdbcTemplate的batch操作最后还是利用了JDBC提供的方法,Spring只是做了一下改造和封装 JDBC的batch操作: String sql = "INSERT INTO CUSTOMER " + "(CUST_ID, NAME, AGE) VALUES (?, ?, ?)"; </div> </li> <li><a href="/article/2211.htm" title="[JWFD开源工作流]大规模拓扑矩阵存储结构最新进展" target="_blank">[JWFD开源工作流]大规模拓扑矩阵存储结构最新进展</a> <span class="text-muted">comsci</span> <a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C%E6%B5%81/1.htm">工作流</a> <div>    生成和创建类已经完成,构造一个100万个元素的矩阵模型,存储空间只有11M大,请大家参考我在博客园上面的文档"构造下一代工作流存储结构的尝试",更加相信的设计和代码将陆续推出.........     竞争对手的能力也很强.......,我相信..你们一定能够先于我们推出大规模拓扑扫描和分析系统的....</div> </li> <li><a href="/article/2338.htm" title="base64编码和url编码" target="_blank">base64编码和url编码</a> <span class="text-muted">cuityang</span> <a class="tag" taget="_blank" href="/search/base64/1.htm">base64</a><a class="tag" taget="_blank" href="/search/url/1.htm">url</a> <div>import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; </div> </li> <li><a href="/article/2465.htm" title="web应用集群Session保持" target="_blank">web应用集群Session保持</a> <span class="text-muted">dalan_123</span> <a class="tag" taget="_blank" href="/search/session/1.htm">session</a> <div>关于使用 memcached 或redis 存储 session ,以及使用 terracotta 服务器共享。建议使用 redis,不仅仅因为它可以将缓存的内容持久化,还因为它支持的单个对象比较大,而且数据类型丰富,不只是缓存 session,还可以做其他用途,一举几得啊。1、使用 filter 方法存储这种方法比较推荐,因为它的服务器使用范围比较多,不仅限于tomcat ,而且实现的原理比较简</div> </li> <li><a href="/article/2719.htm" title="Yii 框架里数据库操作详解-[增加、查询、更新、删除的方法 'AR模式']" target="_blank">Yii 框架里数据库操作详解-[增加、查询、更新、删除的方法 'AR模式']</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a> <div>    public function getMinLimit () {        $sql = "...";        $result = yii::app()->db->createCo</div> </li> <li><a href="/article/2846.htm" title="solr StatsComponent(聚合统计)" target="_blank">solr StatsComponent(聚合统计)</a> <span class="text-muted">eksliang</span> <a class="tag" taget="_blank" href="/search/solr%E8%81%9A%E5%90%88%E6%9F%A5%E8%AF%A2/1.htm">solr聚合查询</a><a class="tag" taget="_blank" href="/search/solr+stats/1.htm">solr stats</a> <div>StatsComponent 转载请出自出处:http://eksliang.iteye.com/blog/2169134 http://eksliang.iteye.com/ 一、概述        Solr可以利用StatsComponent 实现数据库的聚合统计查询,也就是min、max、avg、count、sum的功能   二、参数</div> </li> <li><a href="/article/2973.htm" title="百度一道面试题" target="_blank">百度一道面试题</a> <span class="text-muted">greemranqq</span> <a class="tag" taget="_blank" href="/search/%E4%BD%8D%E8%BF%90%E7%AE%97/1.htm">位运算</a><a class="tag" taget="_blank" href="/search/%E7%99%BE%E5%BA%A6%E9%9D%A2%E8%AF%95/1.htm">百度面试</a><a class="tag" taget="_blank" href="/search/%E5%AF%BB%E6%89%BE%E5%A5%87%E6%95%B0%E7%AE%97%E6%B3%95/1.htm">寻找奇数算法</a><a class="tag" taget="_blank" href="/search/bitmap+%E7%AE%97%E6%B3%95/1.htm">bitmap 算法</a> <div>那天看朋友提了一个百度面试的题目:怎么找出{1,1,2,3,3,4,4,4,5,5,5,5}  找出出现次数为奇数的数字.   我这里复制的是原话,当然顺序是不一定的,很多拿到题目第一反应就是用map,当然可以解决,但是效率不高。   还有人觉得应该用算法xxx,我是没想到用啥算法好...!   还有觉得应该先排序...   还有觉</div> </li> <li><a href="/article/3100.htm" title="Spring之在开发中使用SpringJDBC" target="_blank">Spring之在开发中使用SpringJDBC</a> <span class="text-muted">ihuning</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div>  在实际开发中使用SpringJDBC有两种方式:   1. 在Dao中添加属性JdbcTemplate并用Spring注入;     JdbcTemplate类被设计成为线程安全的,所以可以在IOC 容器中声明它的单个实例,并将这个实例注入到所有的 DAO 实例中。JdbcTemplate也利用了Java 1.5 的特定(自动装箱,泛型,可变长度</div> </li> <li><a href="/article/3227.htm" title="JSON API 1.0 核心开发者自述 | 你所不知道的那些技术细节" target="_blank">JSON API 1.0 核心开发者自述 | 你所不知道的那些技术细节</a> <span class="text-muted">justjavac</span> <a class="tag" taget="_blank" href="/search/json/1.htm">json</a> <div>2013年5月,Yehuda Katz 完成了JSON API(英文,中文) 技术规范的初稿。事情就发生在 RailsConf 之后,在那次会议上他和 Steve Klabnik 就 JSON 雏形的技术细节相聊甚欢。在沟通单一 Rails 服务器库—— ActiveModel::Serializers 和单一 JavaScript 客户端库——&</div> </li> <li><a href="/article/3354.htm" title="网站项目建设流程概述" target="_blank">网站项目建设流程概述</a> <span class="text-muted">macroli</span> <a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C/1.htm">工作</a> <div>一.概念 网站项目管理就是根据特定的规范、在预算范围内、按时完成的网站开发任务。 二.需求分析 项目立项   我们接到客户的业务咨询,经过双方不断的接洽和了解,并通过基本的可行性讨论够,初步达成制作协议,这时就需要将项目立项。较好的做法是成立一个专门的项目小组,小组成员包括:项目经理,网页设计,程序员,测试员,编辑/文档等必须人员。项目实行项目经理制。 客户的需求说明书   第一步是需</div> </li> <li><a href="/article/3481.htm" title="AngularJs 三目运算 表达式判断" target="_blank">AngularJs 三目运算 表达式判断</a> <span class="text-muted">qiaolevip</span> <a class="tag" taget="_blank" href="/search/%E6%AF%8F%E5%A4%A9%E8%BF%9B%E6%AD%A5%E4%B8%80%E7%82%B9%E7%82%B9/1.htm">每天进步一点点</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0%E6%B0%B8%E6%97%A0%E6%AD%A2%E5%A2%83/1.htm">学习永无止境</a><a class="tag" taget="_blank" href="/search/%E4%BC%97%E8%A7%82%E5%8D%83%E8%B1%A1/1.htm">众观千象</a><a class="tag" taget="_blank" href="/search/AngularJS/1.htm">AngularJS</a> <div>事件回顾:由于需要修改同一个模板,里面包含2个不同的内容,第一个里面使用的时间差和第二个里面名称不一样,其他过滤器,内容都大同小异。希望杜绝If这样比较傻的来判断if-show or not,继续追究其源码。 var b = "{{", a = "}}"; this.startSymbol = function(a) { </div> </li> <li><a href="/article/3608.htm" title="Spark算子:统计RDD分区中的元素及数量" target="_blank">Spark算子:统计RDD分区中的元素及数量</a> <span class="text-muted">superlxw1234</span> <a class="tag" taget="_blank" href="/search/spark/1.htm">spark</a><a class="tag" taget="_blank" href="/search/spark%E7%AE%97%E5%AD%90/1.htm">spark算子</a><a class="tag" taget="_blank" href="/search/Spark+RDD%E5%88%86%E5%8C%BA%E5%85%83%E7%B4%A0/1.htm">Spark RDD分区元素</a> <div>关键字:Spark算子、Spark RDD分区、Spark RDD分区元素数量     Spark RDD是被分区的,在生成RDD时候,一般可以指定分区的数量,如果不指定分区数量,当RDD从集合创建时候,则默认为该程序所分配到的资源的CPU核数,如果是从HDFS文件创建,默认为文件的Block数。   可以利用RDD的mapPartitionsWithInd</div> </li> <li><a href="/article/3735.htm" title="Spring 3.2.x将于2016年12月31日停止支持" target="_blank">Spring 3.2.x将于2016年12月31日停止支持</a> <span class="text-muted">wiselyman</span> <a class="tag" taget="_blank" href="/search/Spring+3/1.htm">Spring 3</a> <div>              Spring 团队公布在2016年12月31日停止对Spring Framework 3.2.x(包含tomcat 6.x)的支持。在此之前spring团队将持续发布3.2.x的维护版本。          请大家及时准备及时升级到Spring </div> </li> <li><a href="/article/3862.htm" title="fis纯前端解决方案fis-pure" target="_blank">fis纯前端解决方案fis-pure</a> <span class="text-muted">zccst</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a> <div>作者:zccst FIS通过插件扩展可以完美的支持模块化的前端开发方案,我们通过FIS的二次封装能力,封装了一个功能完备的纯前端模块化方案pure。 1,fis-pure的安装 $ fis install -g fis-pure $ pure -v 0.1.4 2,下载demo到本地 git clone https://github.com/hefangshi/f</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>