Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Kenneth A. Kousen - Making Java Groovy - 2014.pdf
Скачиваний:
50
Добавлен:
19.03.2016
Размер:
15.36 Mб
Скачать

JSON support

323

This is the same as the DTD, except that it says that price elements have two decimal places, and isbn attributes are composed of either 10 or 13 decimal digits. Tying the XML document to this schema can be done by modifying the root element as follows:

<library xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.kousenit.com/books" xsi:schemaLocation="

http://www.kousenit.com/books books.xsd">

The rest of the library is the same as before. Here’s the code used to validate the XML document against the schema:

String file = "books.xml" String xsd = "books.xsd"

SchemaFactory factory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI)

Schema schema = factory.newSchema(new File(xsd)) Validator validator = schema.newValidator()

validator.validate(new StreamSource(new FileReader(file)))

This looks relatively simple, but here’s the interesting part: the mechanism used is Java. If I was to write this code in Java, it would look almost identical. Unlike the XmlSlurper used for DTD validation, Groovy doesn’t add anything special to do schema validation. So you fall back on the Java approach and write it in Groovy. Because Groovy didn’t add anything, these lines could be written in either language, depending on your needs. Still, Groovy normally does help, as most of the code in this appendix shows.

Whenever the issue of XML comes up these days, someone always asks about JSON support. I’ll address that issue in the next section.

B.9 JSON support

The trend in the industry has been away from XML and toward JavaScript Object Notation, known as JSON. If your client is written in JavaScript, JSON is a natural, because JSON objects are native to the language. Java doesn’t include a JSON parser, but several good libraries are available.

As of Groovy 1.8, Groovy includes a groovy.json package, which includes a JSON slurper and a JSON builder.

B.9.1 Slurping JSON

The groovy.json package includes a class called JsonSlurper. This class is not quite as versatile as the XmlSlurper class because it has fewer methods. It contains a parse method that takes a Reader as an argument, as well as a parseText method that takes

a String.

www.it-ebooks.info

324

APPENDIX B Groovy by feature

A JSON object looks like a map inside curly braces. Parsing it results in a map in Groovy:

import groovy.json.JsonSlurper;

def slurper = new JsonSlurper()

def result = slurper.parseText('{"first":"Herman","last":"Munster"}') assert result.first == 'Herman'

assert result.last == 'Munster'

Instantiate the slurper and call its parseText method, and the result is a map that can be accessed in the usual way, as shown. Lists work as well:

result = slurper.parseText( '{"first":"Herman","last":"Munster","kids":["Eddie","Marilyn"]}')

assert result.kids == ['Eddie','Marilyn']

The two children wind up in an instance of ArrayList. You can also add numbers and even contained objects:

result = slurper.parseText( '{"first":"Herman","last":"Munster","address":{"street":"1313 Mockingbird

Lane","city":"New York","state":"NY"},"wife":"Lily", "age":34,"kids":["Eddie","Marilyn"]}')

result.with {

assert wife == 'Lily' assert age == 34

assert address.street == '1313 Mockingbird Lane' assert address.city == 'New York'

assert address.state == 'NY'

}

The age becomes an integer. The address object is also parsed into a map, whose properties are also available in the standard way. Here, by the way, I used the with method, which prepends whatever value it’s invoked on to the contained expressions. wife is short for result.wife, and so on.

If parsing is easy, building is also a simple operation, much like using MarkupBuilder.

B.9.2 Building JSON

I discussed builders earlier, and I use them throughout the book. In various chapters I use MarkupBuilder (shown in this chapter), SwingBuilder, and AntBuilder. Here I’ll illustrate the builder for generating JSON, called JsonBuilder.

The JsonBuilder class can be used with lists, maps, or methods. For example, here’s a trivial list:

import groovy.json.JsonBuilder;

def builder = new JsonBuilder() def result = builder 1,2,3 assert result == [1, 2, 3]

www.it-ebooks.info

JSON support

325

This builder takes a list of numbers as an argument and builds a JSON object containing them. Here’s an example of using a map:

result = builder { first 'Fred'

last 'Flintstone'

}

assert builder.toString() == '{"first":"Fred","last":"Flintstone"}'

The result is a standard JSON object (contained in braces), whose properties are the strings provided in the builder.

In the builder syntax you can use parentheses to build a contained object, so let’s continue on with the example:

result = builder.people { person {

first 'Herman' last 'Munster'

address(street:'1313 Mockingbird Lane', city:'New York',state:'NY')

wife 'Lily' age 34

kids 'Eddie','Marilyn'

}

}

assert builder.toString() == '{"people":{"person":{"first":"Herman","last":"Munster",' + '"address":{"street":"1313 Mockingbird Lane",' + '"city":"New York","state":"NY"},"wife":"Lily","age":34,' + "kids":["Eddie","Marilyn"]}}}'

The generated JSON can get difficult to read, so the class adds a toPrettyString() method:

println builder.toPrettyString()

This results in nicely formatted output, as shown:

{

"people": { "person": {

"first": "Herman", "last": "Munster", "address": {

"street": "1313 Mockingbird Lane", "city": "New York",

"state": "NY"

},

"wife": "Lily", "age": 34, "kids": [

"Eddie",

www.it-ebooks.info

326

APPENDIX B Groovy by feature

"Marilyn"

]

}

}

}

JSON data is therefore almost as easy to manage as XML, both when creating it and when managing it.

www.it-ebooks.info

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]