SpringCloud 正则表达式

2023-12-13 09:46 更新

 本部分仅对Groovy DSL有效。请查看 “匹配器节中的动态Properties”一节,以获取类似功能的YAML示例。

您可以使用正则表达式在Contract DSL中编写请求。当您想要指示应遵循给定模式的请求提供给定响应时,这样做特别有用。另外,在测试和服务器端测试都需要使用模式而不是精确值时,可以使用正则表达式。

下面的示例演示如何使用正则表达式编写请求:

org.springframework.cloud.contract.spec.Contract.make {
	request {
		method('GET')
		url $(consumer(~/\/[0-9]{2}/), producer('/12'))
	}
	response {
		status OK()
		body(
				id: $(anyNumber()),
				surname: $(
						consumer('Kowalsky'),
						producer(regex('[a-zA-Z]+'))
				),
				name: 'Jan',
				created: $(consumer('2014-02-02 12:23:43'), producer(execute('currentDate(it)'))),
				correlationId: value(consumer('5d1f9fef-e0dc-4f3d-a7e4-72d2220dd827'),
						producer(regex('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}'))
				)
		)
		headers {
			header 'Content-Type': 'text/plain'
		}
	}
}

您也只能在通信的一侧提供正则表达式。如果这样做,那么合同引擎将自动提供与提供的正则表达式匹配的生成的字符串。以下代码显示了一个示例:

org.springframework.cloud.contract.spec.Contract.make {
	request {
		method 'PUT'
		url value(consumer(regex('/foo/[0-9]{5}')))
		body([
				requestElement: $(consumer(regex('[0-9]{5}')))
		])
		headers {
			header('header', $(consumer(regex('application\\/vnd\\.fraud\\.v1\\+json;.*'))))
		}
	}
	response {
		status OK()
		body([
				responseElement: $(producer(regex('[0-9]{7}')))
		])
		headers {
			contentType("application/vnd.fraud.v1+json")
		}
	}
}

在前面的示例中,通信的另一端具有为请求和响应而生成的相应数据。

Spring Cloud Contract带有一系列可在合同中使用的预定义正则表达式,如以下示例所示:

protected static final Pattern TRUE_OR_FALSE = Pattern.compile(/(true|false)/)
protected static final Pattern ALPHA_NUMERIC = Pattern.compile('[a-zA-Z0-9]+')
protected static final Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/)
protected static final Pattern NUMBER = Pattern.compile('-?(\\d*\\.\\d+|\\d+)')
protected static final Pattern INTEGER = Pattern.compile('-?(\\d+)')
protected static final Pattern POSITIVE_INT = Pattern.compile('([1-9]\\d*)')
protected static final Pattern DOUBLE = Pattern.compile('-?(\\d*\\.\\d+)')
protected static final Pattern HEX = Pattern.compile('[a-fA-F0-9]+')
protected static final Pattern IP_ADDRESS = Pattern.
		compile('([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])')
protected static final Pattern HOSTNAME_PATTERN = Pattern.
		compile('((http[s]?|ftp):/)/?([^:/\\s]+)(:[0-9]{1,5})?')
protected static final Pattern EMAIL = Pattern.
		compile('[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}')
protected static final Pattern URL = UrlHelper.URL
protected static final Pattern HTTPS_URL = UrlHelper.HTTPS_URL
protected static final Pattern UUID = Pattern.
		compile('[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}')
protected static final Pattern ANY_DATE = Pattern.
		compile('(\\d\\d\\d\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])')
protected static final Pattern ANY_DATE_TIME = Pattern.
		compile('([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])')
protected static final Pattern ANY_TIME = Pattern.
		compile('(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])')
protected static final Pattern NON_EMPTY = Pattern.compile(/[\S\s]+/)
protected static final Pattern NON_BLANK = Pattern.compile(/^\s*\S[\S\s]*/)
protected static final Pattern ISO8601_WITH_OFFSET = Pattern.
		compile(/([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\.\d{1,6})?(Z|[+-][01]\d:[0-5]\d)/)

protected static Pattern anyOf(String... values) {
	return Pattern.compile(values.collect({ "^$it\$" }).join("|"))
}

RegexProperty onlyAlphaUnicode() {
	return new RegexProperty(ONLY_ALPHA_UNICODE).asString()
}

RegexProperty alphaNumeric() {
	return new RegexProperty(ALPHA_NUMERIC).asString()
}

RegexProperty number() {
	return new RegexProperty(NUMBER).asDouble()
}

RegexProperty positiveInt() {
	return new RegexProperty(POSITIVE_INT).asInteger()
}

RegexProperty anyBoolean() {
	return new RegexProperty(TRUE_OR_FALSE).asBooleanType()
}

RegexProperty anInteger() {
	return new RegexProperty(INTEGER).asInteger()
}

RegexProperty aDouble() {
	return new RegexProperty(DOUBLE).asDouble()
}

RegexProperty ipAddress() {
	return new RegexProperty(IP_ADDRESS).asString()
}

RegexProperty hostname() {
	return new RegexProperty(HOSTNAME_PATTERN).asString()
}

RegexProperty email() {
	return new RegexProperty(EMAIL).asString()
}

RegexProperty url() {
	return new RegexProperty(URL).asString()
}

RegexProperty httpsUrl() {
	return new RegexProperty(HTTPS_URL).asString()
}

RegexProperty uuid() {
	return new RegexProperty(UUID).asString()
}

RegexProperty isoDate() {
	return new RegexProperty(ANY_DATE).asString()
}

RegexProperty isoDateTime() {
	return new RegexProperty(ANY_DATE_TIME).asString()
}

RegexProperty isoTime() {
	return new RegexProperty(ANY_TIME).asString()
}

RegexProperty iso8601WithOffset() {
	return new RegexProperty(ISO8601_WITH_OFFSET).asString()
}

RegexProperty nonEmpty() {
	return new RegexProperty(NON_EMPTY).asString()
}

RegexProperty nonBlank() {
	return new RegexProperty(NON_BLANK).asString()
}

在您的合同中,可以按以下示例所示使用它:

Contract dslWithOptionalsInString = Contract.make {
	priority 1
	request {
		method POST()
		url '/users/password'
		headers {
			contentType(applicationJson())
		}
		body(
				email: $(consumer(optional(regex(email()))), producer('abc@abc.com')),
				callback_url: $(consumer(regex(hostname())), producer('http://partners.com'))
		)
	}
	response {
		status 404
		headers {
			contentType(applicationJson())
		}
		body(
				code: value(consumer("123123"), producer(optional("123123"))),
				message: "User not found by email = [${value(producer(regex(email())), consumer('not.existing@user.com'))}]"
		)
	}
}

为了使事情变得更加简单,您可以使用一组预定义的对象,这些对象将自动假定您要传递正则表达式。所有这些方法均以any前缀开头:

T anyAlphaUnicode()

T anyAlphaNumeric()

T anyNumber()

T anyInteger()

T anyPositiveInt()

T anyDouble()

T anyHex()

T aBoolean()

T anyIpAddress()

T anyHostname()

T anyEmail()

T anyUrl()

T anyHttpsUrl()

T anyUuid()

T anyDate()

T anyDateTime()

T anyTime()

T anyIso8601WithOffset()

T anyNonBlankString()

T anyNonEmptyString()

T anyOf(String... values)

这是如何引用这些方法的示例:

Contract contractDsl = Contract.make {
	label 'trigger_event'
	input {
		triggeredBy('toString()')
	}
	outputMessage {
		sentTo 'topic.rateablequote'
		body([
				alpha            : $(anyAlphaUnicode()),
				number           : $(anyNumber()),
				anInteger        : $(anyInteger()),
				positiveInt      : $(anyPositiveInt()),
				aDouble          : $(anyDouble()),
				aBoolean         : $(aBoolean()),
				ip               : $(anyIpAddress()),
				hostname         : $(anyHostname()),
				email            : $(anyEmail()),
				url              : $(anyUrl()),
				httpsUrl         : $(anyHttpsUrl()),
				uuid             : $(anyUuid()),
				date             : $(anyDate()),
				dateTime         : $(anyDateTime()),
				time             : $(anyTime()),
				iso8601WithOffset: $(anyIso8601WithOffset()),
				nonBlankString   : $(anyNonBlankString()),
				nonEmptyString   : $(anyNonEmptyString()),
				anyOf            : $(anyOf('foo', 'bar'))
		])
	}
}


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号