A Quick Guide to Working with Web Services in Groovy – 在Groovy中使用Web服务的快速指南

最后修改: 2019年 9月 7日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Nowadays, we see a range of ways to expose data by an application over the web.

如今,我们看到了一系列应用程序通过网络暴露数据的方式。

Often, the application uses a SOAP or REST web service to expose their APIs. However, there are streaming protocols like RSS and Atom to consider as well.

通常,应用程序使用SOAPREST web服务来公开其API。然而,还有像RSS和Atom这样的流媒体协议也需要考虑。

In this quick tutorial, we’ll explore a few handy ways to work with web services in Groovy for each of these protocols.

在这个快速教程中,我们将探讨在Groovy中使用Web服务的一些方便的方法,以适应这些协议中的每一个。

2. Execute HTTP Requests

2.执行HTTP请求

To begin with, let’s execute a simple HTTP GET request using the URL class. We’ll consume the Postman Echo APIs during our exploration.

首先,让我们使用URL类执行一个简单的 HTTP GET 请求。在我们的探索过程中,我们将消耗Postman Echo API。

First, we’ll call the openConnection method of the URL class and then set the requestMethod to GET:

首先,我们将调用URL类的openConnection方法,然后将requestMethod设为GET。

def postmanGet = new URL('https://postman-echo.com/get')
def getConnection = postmanGet.openConnection()
getConnection.requestMethod = 'GET'
assert getConnection.responseCode == 200

Similarly, we can make a POST request by setting the requestMethod to POST:

同样,我们可以通过将requestMethod 设置为POST来进行POST请求。

def postmanPost = new URL('https://postman-echo.com/post')
def postConnection = postmanPost.openConnection()
postConnection.requestMethod = 'POST'
assert postConnection.responseCode == 200

Also, we can pass the parameters to the POST request using the outputStream.withWriter:

另外,我们可以使用outputStream.withWriter将参数传递给POST请求。

def form = "param1=This is request parameter."
postConnection.doOutput = true
def text
postConnection.with {
    outputStream.withWriter { outputStreamWriter ->
        outputStreamWriter << form
    }
    text = content.text
}
assert postConnection.responseCode == 200

Here, Groovy’s with closure looks quite handy and makes the code cleaner.

在这里,Groovy的with闭包看起来相当方便,而且使代码更简洁。

Let’s use the JsonSlurper to parse the String response into JSON:

让我们使用JsonSlurper来将String响应解析为JSON。

JsonSlurper jsonSlurper = new JsonSlurper()
assert jsonSlurper.parseText(text)?.json.param1 == "This is request parameter."

3. RSS and Atom Feeds

3.RSS和Atom Feeds

RSS and Atom feed are common ways to expose the contents like news, blogs, and tech forums over the web.

RSSAtom feed是在网络上曝光新闻、博客和技术论坛等内容的常见方式。

Also, both of the feeds are XML-formatted. Therefore, we can use Groovy’s XMLParser class to parse the content.

而且,这两个feeds都是XML格式的。因此,我们可以使用Groovy的XMLParser类来解析这些内容。

Let’s read a few top stories from the Google News utilizing their RSS feed:

让我们从谷歌新闻中利用他们的RSS提要阅读一些热门故事。

def rssFeed = new XmlParser()
    .parse("https://news.google.com/rss?hl=en-US≷=US&ceid=US:en")
def stories = []
(0..4).each {
    def item = rssFeed.channel.item.get(it)
    stories << item.title.text()
}
assert stories.size() == 5

Similarly, we can read the Atom feeds. However, due to the variation in specifications of both protocols, we’ll access the content differently in Atom feeds:

同样地,我们可以阅读Atom feeds。然而,由于两种协议的规格不同,我们将以不同的方式访问Atom feeds中的内容。

def atomFeed = new XmlParser()
    .parse("https://news.google.com/atom?hl=en-US≷=US&ceid=US:en")
def stories = []
(0..4).each {
    def entry = atomFeed.entry.get(it)
    stories << entry.title.text()
}
assert stories.size() == 5

Also, we understand Groovy supports all Java libraries are encouraged in Groovy. Therefore, we can surely use the Rome API to read the RSS feeds.

另外,我们了解到Groovy支持所有的Java库,在Groovy中鼓励使用。因此,我们肯定可以使用Rome API来读取RSS源。

4. SOAP Request and Response

4.SOAP请求和响应

SOAP is one of the most popular web service protocols used by applications to expose their services over the web.

SOAP是最流行的网络服务协议之一,被应用程序用来在网络上暴露其服务。

We’ll use the groovy-wslite library to consume the SOAP APIs. Let’s add its latest dependency to our pom.xml:

我们将使用groovy-wslite库来消费SOAP API。让我们将其最新的依赖性添加到我们的pom.xml

<dependency>
    <groupId>com.github.groovy-wslite</groupId>
    <artifactId>groovy-wslite</artifactId>
    <version>1.1.3</version>
</dependency>

Alternatively, we can add the latest dependency using Gradle:

或者,我们可以使用Gradle添加最新的依赖关系。

compile group: 'com.github.groovy-wslite', name: 'groovy-wslite', version: '1.1.3'

Or if we want to write a Groovy script. We can add it directly using @Grab:

或者如果我们想写一个Groovy脚本。我们可以直接使用@Grab来添加它。

@Grab(group='com.github.groovy-wslite', module='groovy-wslite', version='1.1.3')

The groovy-wslite library provides the SOAPClient class to communicate with SOAP APIs. At the same time, it has the SOAPMessageBuilder class to create the request message.

groovy-wslite库提供了SOAPClient类来与SOAP APIs通信。同时,它还有SOAPMessageBuilder类来创建请求消息。

Let’s consume a Number conversion SOAP Service using the SOAPClient:

让我们使用SOAPClient来消费一个号码转换SOAP服务

def url = "http://www.dataaccess.com/webservicesserver/numberconversion.wso"
def soapClient = new SOAPClient(url)
def message = new SOAPMessageBuilder().build({
    body {
        NumberToWords(xmlns: "http://www.dataaccess.com/webservicesserver/") {
            ubiNum(123)
        }
    }
})
def response = soapClient.send(message.toString());
def words = response.NumberToWordsResponse
assert words == "one hundred and twenty three "

5. REST Request and Response

5.REST请求和响应

REST is another popular architectural style used for creating web services. Also, the APIs are exposed based on HTTP methods like GET, POST,  PUT, and DELETE.

REST是另一种用于创建网络服务的流行架构风格。另外,API是基于HTTP方法(如GET、POST、PUT和DELETE)而暴露的。

5.1. GET

5.1 GET

We’ll use the already discussed groovy-wslite library to consume the REST APIs. It provides the RESTClient class for hassle-free communication.

我们将使用已经讨论过的groovy-wslite库来消费REST APIs。它提供了RESTClient类来实现无障碍通信

Let’s make a GET request to the already discussed Postman API:

让我们向已经讨论过的Postman API发出一个GET请求。

RESTClient client = new RESTClient("https://postman-echo.com")
def path = "/get"
def response
try {
    response = client.get(path: path)
    assert response.statusCode = 200
    assert response.json?.headers?.host == "postman-echo.com"
} catch (RESTClientException e) {
    assert e?.response?.statusCode != 200
}

5.2. POST

5.2 邮政

Now, let’s make a POST request to the Postman API. At the same time, we’ll pass the form parameters as JSON:

现在,让我们向Postman API发出一个POST请求。同时,我们将把表单参数以JSON格式传递。

client.defaultAcceptHeader = ContentType.JSON
def path = "/post"
def params = ["foo":1,"bar":2]
def response = client.post(path: path) {
    type ContentType.JSON
    json params
}
assert response.json?.data == params

Here, we’ve set the JSON as the default accept header.

在这里,我们将JSON设置为默认的接受头。

6. Authentication for Web Service

6.网络服务的认证

With the growing amount of web services and applications communicating one with another, it’s recommended to have a secure web service.

随着越来越多的网络服务和应用程序相互通信,我们建议拥有一个安全的网络服务。

As a result, a combination of HTTPS and an authentication mechanism like Basic Auth and OAuth is important.

因此,HTTPS与Basic Auth和OAuth等认证机制的结合很重要

Therefore, an application must authenticate itself while consuming a web service API.

因此,一个应用程序在消费网络服务API时必须对自己进行认证。

6.1. Basic Auth

6.1.基本授权

We can use the already discussed RESTClient class. Let’s use the HTTPBasicAuthorization class with credentials to perform a basic authentication:

我们可以使用已经讨论过的RESTClient类。让我们使用带有证书的HTTPBasicAuthorization类来进行基本认证。

def path = "/basic-auth"
client.authorization = new HTTPBasicAuthorization("postman", "password")
response = client.get(path: path)
assert response.statusCode == 200
assert response.json?.authenticated == true

Alternatively, we can directly pass the credentials (Base64 encoded) in the headers parameter:

另外,我们可以直接在headers参数中传递凭证(Base64编码)。

def response = client
.get(path: path, headers: ["Authorization": "Basic cG9zdG1hbjpwYXNzd29yZA=="])

6.2. OAuth 1.0

6.2.OAuth 1.0

Similarly, we can make an OAuth 1.0 request passing the auth parameters like consumer key and consumer secret.

同样地,我们可以通过消费者密钥和消费者秘密等授权参数,发出OAuth 1.0请求。

However, since we don’t have inbuilt support for OAuth 1.0 as we do for the other mechanisms, we’ll have to do the work ourselves:

然而,由于我们没有像其他机制那样对OAuth 1.0的内置支持,我们必须自己做这项工作。

def path = "/oauth1"
def params = [oauth_consumer_key: "RKCGzna7bv9YD57c", 
    oauth_signature_method: "HMAC-SHA1", 
    oauth_timestamp:1567089944, oauth_nonce: "URT7v4", oauth_version: 1.0, 
    oauth_signature: 'RGgR/ktDmclkM0ISWaFzebtlO0A=']
def response = new RESTClient("https://postman-echo.com")
    .get(path: path, query: params)
assert response.statusCode == 200
assert response.statusMessage == "OK"
assert response.json.status == "pass"

7. Conclusion

7.结语

In this tutorial, we’ve explored a few handy ways to work with web services in Groovy.

在本教程中,我们探讨了在Groovy中使用Web服务的几种便捷方法

At the same time, we’ve seen an easy way to read an RSS or Atom feed.

同时,我们已经看到了一种阅读RSS或Atom feed的简单方法。

As usual, the code implementations are available over on GitHub.

像往常一样,代码的实现可以在GitHub上获得