Группы разработчиков для различных проектов Groovy отлично поработали, чтобы все их фреймворки хорошо работали вместе при создании и развертывании приложений. Если вы посетите раздел «Сеть» плагинов Griffon , вы можете заметить, что все эти плагины можно использовать для создания внешних интерфейсов Griffon для ваших веб-приложений, которые могут взаимодействовать с серверной частью Grails или любой другой серверной частью, которая поддерживает эти модули. технологии. Например, плагин Wsclient может создать сервис в Grails и экспортировать его через веб-сервисы. К этому сервису можно получить доступ из внешнего интерфейса Griffon. Благодаря отличной поддержке Grails для демонстрации поведения, подобного REST, и обширной архитектуре плагинов Griffon, Groovy становится внушительным комплексным решением для веб-приложений и веб-сервисов.
Чтобы настроить службу на стороне Grails, просто создайте новое приложение Grails:
grails create-app example
Затем перейдите в каталог приложения и установите плагин Grails Xfire:
grails install-plugin xfire
Плагин Wsclient, который добавляет клиент удаленного взаимодействия, способный взаимодействовать через SOAP, совместим с плагином Xfire 0.8.1.
Затем создайте MathService:
grails create-service MathService
grails-app/services/MathService.groovy
class MathService {
boolean transactional = false
static expose = ["xfire"]
double add(double arg0, double arg1){
println "add($arg0, $arg1)" // good old println() for quick debugging
return arg0 + arg1
}
}
Наконец, запустите приложение:
grails run-app
The next step is to build the Griffon application. This one is named MathClient:
griffon create-app mathClient
And install the wsclient plugin:
griffon install-plugin wsclient
Modify the view script until it looks like this:
griffon-app/views/MathClientView.groovy
application(title: 'Wsclient Plugin Example',
pack: true,
locationByPlatform: true,
iconImage: imageIcon('/griffon-icon-48x48.png').image,
iconImages: [imageIcon('/griffon-icon-48x48.png').image,
imageIcon('/griffon-icon-32x32.png').image,
imageIcon('/griffon-icon-16x16.png').image]) {
gridLayout(cols: 2, rows: 4)
label("Num1:")
textField(columns: 20, text: bind(target: model, targetProperty: "num1"))
label("Num2:")
textField(columns: 20, text: bind(target: model, targetProperty: "num2"))
label("Result:")
label(text: bind{model.result})
button("Calculate", enabled: bind{model.enabled}, actionPerformed: controller.calculate)
}
Add required properties to the model:
griffon-app/models/MathClientModel.groovy
import groovy.beans.Bindable
class MathClientModel {
@Bindable String num1
@Bindable String num2
@Bindable String result
@Bindable boolean enabled = true
}
Here is the controller code. There is minimal error handling in place so if the user types something that is not a number, the client will break:
griffon-app/controllers/MathClientController.groovy
class MathClientController {
def model
def calculate = { evt = null ->
double a = model.num1.toDouble()
double b = model.num2.toDouble()
model.enabled = false
doOutside {
try {
def result = withWs(wsdl: "http://localhost:8080/exporter/services/math?wsdl") {
add(a, b)
}
doLater { model.result = result.toString() }
} finally {
model.enabled = true
}
}
}
}
Finally, start the application:
griffon run-app
When running, the wsclient plugin will add dynamic methods to controllers (the withWs() method at line 12). A new wsclient proxy will be created every time you call those methods unless you define an id: attribute. You can access the client via regular property access or using the id: again. Dynamic methods will be added to controllers by default, but you can change this setting by adding a config flag in Application.groovy:
griffon.wsclient.injectInto = ["controller", "service"]
Other plugins like hessian, RMI, or XML-RPC follow the same principles in this example.
Grails works well as a back-end because it’s good at outputting XML and easily ingesting it back. Scott Davis’s Mastering Grails series gives a detailed demonstration for exposing REST-like behavior with Grails. For enabling the usage of HTTPBuilder on a Griffon or Grails application, there are REST plugins available.
Here’s an example from HTTPBuilder’s Simplified GET Request using the REST plugin for Grails or Griffon:
withHttp(uri: "http://www.google.com") {
def html = get(path : '/search', query : [q:'Groovy'])
assert html.HEAD.size() == 1
assert html.BODY.size() == 1
}
The current HTTPBuilder is set as the closure’s delegate. The same is true for the other dynamic methods
Here’s an example from AsyncHTTPBuilder:
import static groovyx.net.http.ContentType.HTML
withAsyncHttp(poolSize : 4, uri : "http://hc.apache.org", contentType : HTML) {
def result = get(path:'/') { resp, html ->
println ' got async response!'
return html
}
assert result instanceof java.util.concurrent.Future
while (! result.done) {
println 'waiting...'
Thread.sleep(2000)
}
/* The Future instance contains whatever is returned from the response
closure above; in this case the parsed HTML data: */
def html = result.get()
assert html instanceof groovy.util.slurpersupport.GPathResult
}
Once again, all dynamic methods will create a new http client when invoked unless you define an id: attribute.
class FooController {
def loginAction = { evt = null ->
withRest(id: "twitter", uri: "http://twitter.com/statuses/") {
auth.basic model.username, model.password
}
}
def queryAction = { evt = null ->
doOutside {
withRest(id: "twitter") {
def response = get(path: "followers.json")
// ...
}
/* alternatively
def response twitter.get(path: "followers.json")
*/
}
}
}
For the entire Mastering Grails series, you can follow this link.