![](/img/trans.png)
[英]How to access Environment Variable from AWS in my spring boot application
[英]How can I access a Spring Boot environment variable from a Jackson @JsonCreator constructor
我有一个不变的模型类,可以由Jackson使用@JsonCreator
注释的构造函数实例化。 这些属性之一是可选的,我想基于application.yml
的变量创建一个动态默认值,以替换下面的固定值30。
public class DataRequest {
private final List<String> fields;
private final int sessionTimeoutSecs;
@JsonCreator
public DataRequest(@JsonProperty("fields") final List<String> fields,
@JsonProperty("sessionTimeoutSecs") final Integer sessionTimeoutSecs) {
this.fields = fields;
this.sessionTimeoutSecs = MoreObjects.firstNonNull(sessionTimeoutSecs, 30);
}
}
我尝试添加一个附加的构造函数参数@Value("${default-session-timeout-secs}") final int defaultSessionTimeout
但是在尝试映射时会导致MessageConversionException
。
您可以通过桥接属性并使用@JacksonInject
。 此注释与对象映射器配合使用良好。 我跳过了有关如何在代码中将spring桥接到jackson的部分,但是给了您一个简单的ObjectMapper
示例。 参见以下代码:
package de.pandaadb.jackson;
import java.io.IOException;
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class DataModel {
private String test;
private String optionalValue;
@JsonCreator
public DataModel(@JsonProperty("test") String test, @JacksonInject("opt") @JsonProperty(value= "opt", required=false)String opt) {
this.optionalValue = opt;
this.test = test;
}
@Override
public String toString() {
return "test=" + test + " optional=" + optionalValue;
}
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
InjectableValues.Std std = new InjectableValues.Std();
std.addValue("opt", "alternative");
String withOptional = "{\"test\" : \"hello\" , \"opt\" : \"optss\"}";
String withoutOptional = "{\"test\" : \"hello\"}";
mapper.setInjectableValues(std);
System.out.println(mapper.readValue(withOptional, DataModel.class));
System.out.println(mapper.readValue(withoutOptional, DataModel.class));
}
}
此代码打印:
test=hello optional=optss
test=hello optional=alternative
一些注意事项:
除了属性之外,构造函数还使用构造函数中的JacksonInject
批注。 这将首先注入配置的值,可选地使用来自输入的json值覆盖它。
正在向ObjectMapper
提供与我们具有的注释匹配的属性
第二部分是最重要的。
至于使用spring进行此工作,方法是在您的配置中包含以下代码:
@Configuration
public class ObjectMapperConfiguration {
ObjectMapper mapper(@Value("${my.test.string}") String test) {
ObjectMapper mapper = new ObjectMapper();
InjectableValues.Std std = new InjectableValues.Std();
std.addValue("my.test.string", "test");
mapper.setInjectableValues(std);
return mapper;
}
}
另外,您也可以注入ALL属性,并将其反馈给对象映射器,以免不必对每个新属性进行扩展。
希望对您有所帮助,
一些更多的阅读材料在这里: https : //www.concretepage.com/jackson-api/jackson-jacksoninject-example#ObjectMapper
最新编辑:如何仅使用1个构造函数参数,让jackson自己处理覆盖
-阿图尔
您可以通过使用两个帮助程序类来实现。
第一个是ContextHolder
,它使您可以从Spring托管的bean外部访问Spring的ApplicationContext:
@Component
public class ContextHolder implements ApplicationContextAware {
public static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ContextHolder.applicationContext = applicationContext;
}
}
第二个是DefaultTimeoutWrapper
,其中包含默认超时值:
@Component
public class DefaultTimeoutWrapper {
@Value("${default-session-timeout-secs}")
private int defaultTimeout;
public int getDefaultTimeout() {
return defaultTimeout;
}
}
然后,您需要更改DataRequest
类以使用它们,如下所示:
public class DataRequest {
private final List<String> fields;
private final int sessionTimeoutSecs;
@JsonCreator
public DataRequest(@JsonProperty("fields") final List<String> fields,
@JsonProperty("sessionTimeoutSecs") final Integer sessionTimeoutSecs) {
DefaultTimeoutWrapper defaultTimeoutWrapper = ContextHolder.applicationContext.getBean(DefaultTimeoutWrapper.class);
int defaultTimeout = defaultTimeoutWrapper.getDefaultTimeout();
this.fields = fields;
this.sessionTimeoutSecs = sessionTimeoutSecs != null ? sessionTimeoutSecs : defaultTimeout;
}
}
请注意,在ContextHolder
实例方法用于设置静态字段的值,通常认为这是不好的设计。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.