使用 apache Velocity JSON 到 JSON 的转换?有没有更好的方法来编写我在下面的一个用例中提到的模板?
JSON to JSON transformation using apache Velocity? Is there any better way of writing a template which I have mentioned below in one of my use-case?
我正在使用 apache Velocity 进行 json 转换。下面是我的 json 字符串
{
"apiCode": "Payment Execution Service",
"name": "Initiate a payment",
"description": "Initiate a payment",
"request": {
"method": "POST",
"path": "/api/v1/payments",
"headers": [
{
"Corporate-ID": "apiKey"
},
{
"Content-Type": "application/json"
}
],
"body": "{\n \"beneficiaryInformation\" : {\n \"destinationAccountIdentifier\" : \"string\",\n \"destinationBankIdentifier\" : \"DEUTDEDB237\",\n \"fullName\" : \"JASON SMITH\"\n },\n \"purposeOfPayment\" : \"Invoice Payment\",\n \"remittanceInformation\" : \"Mantainance of Fixtures\",\n \"remitterInformation\" : {\n \"sourceAccountCurrency\" : \"EUR\",\n \"sourceAccountIdentifier\" : \"string\",\n \"sourceBankIdentifier\" : \"DEUTDEDBFRA\"\n },\n \"transferAmount\" : 1.5,\n \"transferCurrency\" : \"EUR\",\n \"transferDate\" : \"2015-07-20\",\n \"transferType\" : \"SCTInst\",\n \"uniqueRequestNo\" : \"string\"\n}"
},
"response": {
"status": 200,
"headers": [
{
"Content-Type": "application/json"
}
],
"body": "{\n \"requestReferenceNo\" : \"string\",\n \"transactionStatus\" : {\n \"bankReferenceNo\" : \"string\",\n \"reasonCode\" : \"string\",\n \"statusCode\" : \"string\"\n }\n}"
},
"provider": "Payment Execution Service"
}
下面是我的 .vm 文件
{
"provider": {
"name": "$arr[0].apiCode"
},
"consumer": {
"name": "$arr[0].provider"
},
"interactions": [
#set($i = 0)
#foreach($a in $arr)
{
"description": "$a.description",
"request": {
"path": "$a.request.path",
"method": "$a.request.method",
"headers": $json.valueToString($a.request.headers),
"body": $json.valueToString($a.request.body)
},
"response": {
"headers": $json.valueToString($a.response.headers),
"body": $json.valueToString($a.response.body),
"status": $a.response.status
},
"providerStates": [{
"name": "$a.description"
}]
}
#set($i = $i + 1)
#if ($i < $arr.size()), #end
#end
],
"metadata": {
"pact-jvm": {
"version": "3.6.3"
},
"pactSpecification": {
"version": "3.0.0"
}
}
}
下面是我得到的输出
{
"provider": {
"name": "Payment Execution Service"
},
"consumer": {
"name": "Payment Execution Service"
},
"interactions": [
{
"description": "Initiate a payment",
"request": {
"path": "/api/v1/payments",
"headers": [
{
"Corporate-ID": "apiKey"
},
{
"Content-Type": "application/json"
}
],
"method": "POST",
"body": "{\n \"beneficiaryInformation\" : {\n \"destinationAccountIdentifier\" : \"string\",\n \"destinationBankIdentifier\" : \"DEUTDEDB237\",\n \"fullName\" : \"JASON SMITH\"\n },\n \"purposeOfPayment\" : \"Invoice Payment\",\n \"remittanceInformation\" : \"Mantainance of Fixtures\",\n \"remitterInformation\" : {\n \"sourceAccountCurrency\" : \"EUR\",\n \"sourceAccountIdentifier\" : \"string\",\n \"sourceBankIdentifier\" : \"DEUTDEDBFRA\"\n },\n \"transferAmount\" : 1.5,\n \"transferCurrency\" : \"EUR\",\n \"transferDate\" : \"2015-07-20\",\n \"transferType\" : \"SCTInst\",\n \"uniqueRequestNo\" : \"string\"\n}"
},
"response": {
"headers": [
{
"Content-Type": "application/json"
}
],
"body": "{\n \"requestReferenceNo\" : \"string\",\n \"transactionStatus\" : {\n \"bankReferenceNo\" : \"string\",\n \"reasonCode\" : \"string\",\n \"statusCode\" : \"string\"\n }\n}",
"status": 200
},
"providerStates": [
{
"name": "Initiate a payment"
}
]
}
],
"metadata": {
"pact-jvm": {
"version": "3.6.3"
},
"pactSpecification": {
"version": "3.0.0"
}
}
}
符合预期
下面是我试过的java代码
public String generatePACTUsingVelocity(List<ExchangeRequest> input) {
/* first, get and initialize an engine */
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
/* next, get the Template */
Template template = ve.getTemplate("spec/pact.vm");
StringWriter writer = new StringWriter();
VelocityContext context = new VelocityContext();
context.put("arr", objectToListHashMap(input));
context.put("json", JSONStringer.class);
template.merge(context, writer);
return writer.toString();
}
@SneakyThrows
private List<HashMap<String, Object>> objectToListHashMap(List<ExchangeRequest> input) {
List<HashMap<String, Object>> mapList = new ArrayList<HashMap<String, Object>>();
for (ExchangeRequest req : input) {
JSONObject obj = new JSONObject(req);
mapList.add(new ObjectMapper().readValue(obj.toString(), new TypeReference<HashMap<String, Object>>() {
}));
}
return mapList;
}
有没有其他方法可以编写 .vm 模板来实现相同的输出。我不想在我的模板中使用任何 java class,就像我使用 JSONStringer.valueToString 将 json 转换为字符串
我希望我的模板以任何测试人员都可以编写并将其传递给代码以生成输出的方式编写。
问题出在这一行:
JSONObject responseobj = new JSONObject(obj.get("response").toString());
您将 is 作为字符串放入 JSONObject,这就是它以这种方式工作的原因。
我正在使用 apache Velocity 进行 json 转换。下面是我的 json 字符串
{
"apiCode": "Payment Execution Service",
"name": "Initiate a payment",
"description": "Initiate a payment",
"request": {
"method": "POST",
"path": "/api/v1/payments",
"headers": [
{
"Corporate-ID": "apiKey"
},
{
"Content-Type": "application/json"
}
],
"body": "{\n \"beneficiaryInformation\" : {\n \"destinationAccountIdentifier\" : \"string\",\n \"destinationBankIdentifier\" : \"DEUTDEDB237\",\n \"fullName\" : \"JASON SMITH\"\n },\n \"purposeOfPayment\" : \"Invoice Payment\",\n \"remittanceInformation\" : \"Mantainance of Fixtures\",\n \"remitterInformation\" : {\n \"sourceAccountCurrency\" : \"EUR\",\n \"sourceAccountIdentifier\" : \"string\",\n \"sourceBankIdentifier\" : \"DEUTDEDBFRA\"\n },\n \"transferAmount\" : 1.5,\n \"transferCurrency\" : \"EUR\",\n \"transferDate\" : \"2015-07-20\",\n \"transferType\" : \"SCTInst\",\n \"uniqueRequestNo\" : \"string\"\n}"
},
"response": {
"status": 200,
"headers": [
{
"Content-Type": "application/json"
}
],
"body": "{\n \"requestReferenceNo\" : \"string\",\n \"transactionStatus\" : {\n \"bankReferenceNo\" : \"string\",\n \"reasonCode\" : \"string\",\n \"statusCode\" : \"string\"\n }\n}"
},
"provider": "Payment Execution Service"
}
下面是我的 .vm 文件
{
"provider": {
"name": "$arr[0].apiCode"
},
"consumer": {
"name": "$arr[0].provider"
},
"interactions": [
#set($i = 0)
#foreach($a in $arr)
{
"description": "$a.description",
"request": {
"path": "$a.request.path",
"method": "$a.request.method",
"headers": $json.valueToString($a.request.headers),
"body": $json.valueToString($a.request.body)
},
"response": {
"headers": $json.valueToString($a.response.headers),
"body": $json.valueToString($a.response.body),
"status": $a.response.status
},
"providerStates": [{
"name": "$a.description"
}]
}
#set($i = $i + 1)
#if ($i < $arr.size()), #end
#end
],
"metadata": {
"pact-jvm": {
"version": "3.6.3"
},
"pactSpecification": {
"version": "3.0.0"
}
}
}
下面是我得到的输出
{
"provider": {
"name": "Payment Execution Service"
},
"consumer": {
"name": "Payment Execution Service"
},
"interactions": [
{
"description": "Initiate a payment",
"request": {
"path": "/api/v1/payments",
"headers": [
{
"Corporate-ID": "apiKey"
},
{
"Content-Type": "application/json"
}
],
"method": "POST",
"body": "{\n \"beneficiaryInformation\" : {\n \"destinationAccountIdentifier\" : \"string\",\n \"destinationBankIdentifier\" : \"DEUTDEDB237\",\n \"fullName\" : \"JASON SMITH\"\n },\n \"purposeOfPayment\" : \"Invoice Payment\",\n \"remittanceInformation\" : \"Mantainance of Fixtures\",\n \"remitterInformation\" : {\n \"sourceAccountCurrency\" : \"EUR\",\n \"sourceAccountIdentifier\" : \"string\",\n \"sourceBankIdentifier\" : \"DEUTDEDBFRA\"\n },\n \"transferAmount\" : 1.5,\n \"transferCurrency\" : \"EUR\",\n \"transferDate\" : \"2015-07-20\",\n \"transferType\" : \"SCTInst\",\n \"uniqueRequestNo\" : \"string\"\n}"
},
"response": {
"headers": [
{
"Content-Type": "application/json"
}
],
"body": "{\n \"requestReferenceNo\" : \"string\",\n \"transactionStatus\" : {\n \"bankReferenceNo\" : \"string\",\n \"reasonCode\" : \"string\",\n \"statusCode\" : \"string\"\n }\n}",
"status": 200
},
"providerStates": [
{
"name": "Initiate a payment"
}
]
}
],
"metadata": {
"pact-jvm": {
"version": "3.6.3"
},
"pactSpecification": {
"version": "3.0.0"
}
}
}
符合预期
下面是我试过的java代码
public String generatePACTUsingVelocity(List<ExchangeRequest> input) {
/* first, get and initialize an engine */
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
/* next, get the Template */
Template template = ve.getTemplate("spec/pact.vm");
StringWriter writer = new StringWriter();
VelocityContext context = new VelocityContext();
context.put("arr", objectToListHashMap(input));
context.put("json", JSONStringer.class);
template.merge(context, writer);
return writer.toString();
}
@SneakyThrows
private List<HashMap<String, Object>> objectToListHashMap(List<ExchangeRequest> input) {
List<HashMap<String, Object>> mapList = new ArrayList<HashMap<String, Object>>();
for (ExchangeRequest req : input) {
JSONObject obj = new JSONObject(req);
mapList.add(new ObjectMapper().readValue(obj.toString(), new TypeReference<HashMap<String, Object>>() {
}));
}
return mapList;
}
有没有其他方法可以编写 .vm 模板来实现相同的输出。我不想在我的模板中使用任何 java class,就像我使用 JSONStringer.valueToString 将 json 转换为字符串 我希望我的模板以任何测试人员都可以编写并将其传递给代码以生成输出的方式编写。
问题出在这一行:
JSONObject responseobj = new JSONObject(obj.get("response").toString());
您将 is 作为字符串放入 JSONObject,这就是它以这种方式工作的原因。