使用 Spring Boot 和 Thymeleaf 动态替换 JSON 响应中的值
Dynamically replacing values in JSON response with Spring Boot and Thymeleaf
使用 Spring 引导我想为外部 API 实施模拟服务。由于此模拟仅用于测试,因此我希望事情尽可能简单。外部APIreturns一个JSON类似这个:
{
"customer": {
"email": "foo@bar.com"
},
"result": {
"status_code": 100
},
"transaction": {
"amount": 100,
"currency": "EUR",
"order_no": "123456"
}
}
控制器:
@Value("classpath:/sample.json")
private Resource sampleResource;
@GetMapping(value = "/api")
public String mockMethod() throws IOException {
final InputStream inputStream = sampleResource.getInputStream();
final String sampleResourceString = StreamUtils.copyToString(sampleResource, StandardCharsets.UTF_8);
return sampleResourceString;
}
所以基本上,应用程序从文件中加载一个 JSON 字符串,并在响应中 returns 它。现在我想用动态值替换 amount
和 JSON 中的 order_no
,如下所示:
{
"customer": {
"email": "foo@bar.com"
},
"result": {
"status_code": 100
},
"transaction": {
"amount": ${amount},
"currency": "EUR",
"order_no": "${orderNumber}"
}
}
我的第一个想法是为此使用 Thymeleaf,因此我创建了以下配置:
@Configuration
@RequiredArgsConstructor
public class TemplateConfiguration {
private final ApplicationContext applicationContext;
@Bean
public SpringResourceTemplateResolver templateResolver() {
final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("/templates");
templateResolver.setSuffix(".json");
templateResolver.setTemplateMode(TemplateMode.TEXT);
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
}
但我不知道如何实际“运行”模板,以便 sampleResourceString
被动态值替换。
或者 Thymeleaf 可能实际上是某种“矫枉过正”?
考虑到 JSON 的结构非常简单,我会将它们映射到 类 并使用 Jackson。例如:
public class DummyResponse {
private DummyResponseCustomer customer;
private DummyResponseTransaction transaction;
private DummyResponseResult result;
// TODO: Getters + Setters + ...
}
public class DummyResponseTransaction {
private BigDecimal amount;
private String currency;
@JsonProperty("order_no")
private String orderNumber;
// TODO: Getters + Setters + ...
}
然后你可以这样写一个控制器:
@ResponseBody // You need the @ResponseBody annotation or annotate the controller with @RestController
@GetMapping(value = "/api")
public DummyResponse mockMethod() {
return new DummyResponse(
new DummyResponseCustomer("foo@bar.com"),
new DummyResponseResult(100),
new DummyResponseTransaction(new BigDecimal("100"), "EUR", "123456")
);
}
这使得想出动态值变得相当容易,而无需使用模板引擎(如 Thymeleaf)或处理 I/O。除此之外,您可能已经在某处使用了这些 类 来使用外部 API.
也许只使用 String.replace()
?
@GetMapping(value = "/api")
public String mockMethod() throws IOException {
final InputStream inputStream = sampleResource.getInputStream();
final String sampleResourceString = StreamUtils.copyToString(sampleResource, StandardCharsets.UTF_8);
String replacedString = sampleResourceString.replace("${amount}", ...)
.replace("${orderNumber}", ...);
return replacedString;
}
使用 Spring 引导我想为外部 API 实施模拟服务。由于此模拟仅用于测试,因此我希望事情尽可能简单。外部APIreturns一个JSON类似这个:
{
"customer": {
"email": "foo@bar.com"
},
"result": {
"status_code": 100
},
"transaction": {
"amount": 100,
"currency": "EUR",
"order_no": "123456"
}
}
控制器:
@Value("classpath:/sample.json")
private Resource sampleResource;
@GetMapping(value = "/api")
public String mockMethod() throws IOException {
final InputStream inputStream = sampleResource.getInputStream();
final String sampleResourceString = StreamUtils.copyToString(sampleResource, StandardCharsets.UTF_8);
return sampleResourceString;
}
所以基本上,应用程序从文件中加载一个 JSON 字符串,并在响应中 returns 它。现在我想用动态值替换 amount
和 JSON 中的 order_no
,如下所示:
{
"customer": {
"email": "foo@bar.com"
},
"result": {
"status_code": 100
},
"transaction": {
"amount": ${amount},
"currency": "EUR",
"order_no": "${orderNumber}"
}
}
我的第一个想法是为此使用 Thymeleaf,因此我创建了以下配置:
@Configuration
@RequiredArgsConstructor
public class TemplateConfiguration {
private final ApplicationContext applicationContext;
@Bean
public SpringResourceTemplateResolver templateResolver() {
final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("/templates");
templateResolver.setSuffix(".json");
templateResolver.setTemplateMode(TemplateMode.TEXT);
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
}
但我不知道如何实际“运行”模板,以便 sampleResourceString
被动态值替换。
或者 Thymeleaf 可能实际上是某种“矫枉过正”?
考虑到 JSON 的结构非常简单,我会将它们映射到 类 并使用 Jackson。例如:
public class DummyResponse {
private DummyResponseCustomer customer;
private DummyResponseTransaction transaction;
private DummyResponseResult result;
// TODO: Getters + Setters + ...
}
public class DummyResponseTransaction {
private BigDecimal amount;
private String currency;
@JsonProperty("order_no")
private String orderNumber;
// TODO: Getters + Setters + ...
}
然后你可以这样写一个控制器:
@ResponseBody // You need the @ResponseBody annotation or annotate the controller with @RestController
@GetMapping(value = "/api")
public DummyResponse mockMethod() {
return new DummyResponse(
new DummyResponseCustomer("foo@bar.com"),
new DummyResponseResult(100),
new DummyResponseTransaction(new BigDecimal("100"), "EUR", "123456")
);
}
这使得想出动态值变得相当容易,而无需使用模板引擎(如 Thymeleaf)或处理 I/O。除此之外,您可能已经在某处使用了这些 类 来使用外部 API.
也许只使用 String.replace()
?
@GetMapping(value = "/api")
public String mockMethod() throws IOException {
final InputStream inputStream = sampleResource.getInputStream();
final String sampleResourceString = StreamUtils.copyToString(sampleResource, StandardCharsets.UTF_8);
String replacedString = sampleResourceString.replace("${amount}", ...)
.replace("${orderNumber}", ...);
return replacedString;
}