Spring Boot应用程序的任务是每隔这么多分钟更新一次远程集成API。此应用程序可以部署到测试或prod环境中,通过“application.properties”标志通知应用程序应该查看的endpoint。POJO被Jackson序列化并推送到endpoint,JsonProperty注释包含它被推送到的API的字段ID。
ie
@JsonProperty("field_001)
private String name;
@JsonProperty("field_002)
private String address;
这些值的字段标签在测试endpoint上不同。因此,测试endpoint可能期望属性映射为
@JsonProperty("field_005)
private String name;
@JsonProperty("field_006)
private String address;
我希望能够利用Spring Boot对基于概要文件的属性文件的本机支持。在运行时从外部属性文件中读取JsonProperty注释值。
比如说,
应用程序中可能有三个文件。属性,应用测试。属性和application-prod.properties。Spring Boot可以根据“Spring.profiles.active”设置读取除vanilla属性文件之外的测试或产品属性。
...-测验属性将包含测试服务器字段的常量值。而且-properties将包含prod server字段的常量值。
嵌套注释,如Spring的@Value标记,如下所示:
@JsonProperty(@Value("${property.file.reference.here}))
似乎不管用。
这是马蒂斯的补充答案。
解决方案使用扩展的JacksonAnNotationINBERCOTOR
,允许在@JsonProperty
注释中使用${environment.properties}
public class DynamicJacksonAnnotationIntrospector extends JacksonAnnotationIntrospector {
private final Environment environment;
public DynamicJacksonAnnotationIntrospector(Environment environment) {
this.environment = environment;
}
@Override
public PropertyName findNameForSerialization(Annotated a) {
return injectEnvironmentInJsonProperty(super.findNameForSerialization(a));
}
@Override
public PropertyName findNameForDeserialization(Annotated a){
return injectEnvironmentInJsonProperty(super.findNameForDeserialization(a));
}
@Override
public PropertyName findRootName(AnnotatedClass ac) {
return injectEnvironmentInJsonProperty(super.findNameForDeserialization(ac));
}
private PropertyName injectEnvironmentInJsonProperty(PropertyName name){
if (name == null) {
return null;
}
String simpleName = name.getSimpleName();
log.info(environment.resolvePlaceholders(simpleName));
return PropertyName.construct(environment.resolvePlaceholders(simpleName), name.getNamespace());
}
}
为控制器中的实体识别创建webconfig类。
@EnableWebMvc
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
private final ApplicationContext context;
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//JSON
AnnotationIntrospector pairedIntrospectors = AnnotationIntrospector.pair(introspector(context.getEnvironment()),
new JacksonAnnotationIntrospector());
converters.add(new MappingJackson2HttpMessageConverter(
Jackson2ObjectMapperBuilder.json()
.annotationIntrospector(pairedIntrospectors)
.build()));
}
@Bean
public DynamicJacksonAnnotationIntrospector introspector(Environment environment) {
return new DynamicJacksonAnnotationIntrospector(environment);
}
@Bean
@Primary
public ObjectMapper getObjectMapper(DynamicJacksonAnnotationIntrospector introspector) {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SerializationConfig serializationConfig = mapper.getSerializationConfig()
.withInsertedAnnotationIntrospector(introspector);
mapper.setConfig(serializationConfig);
DeserializationConfig deserializationConfig = mapper.getDeserializationConfig()
.withInsertedAnnotationIntrospector(introspector);
mapper.setConfig(deserializationConfig);
return mapper;
}
}
并在spring boot的自动配置中禁用类
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
例子
@Getter
@Setter
public class DynamicTestClass {
@JsonProperty("${dynamic.property.name}")
private String dynamicPropertyName;
}
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = JiraSmCoreApplication.class)
@TestPropertySource("classpath:application-test.yml")
public class DynamicJacksonAnnotationIntrospectorTest {
@Autowired
MappingJackson2HttpMessageConverter mapper;
@Test
public void shouldFindNameForSerializationFromProperties() throws JsonProcessingException {
DynamicTestClass bean = new DynamicTestClass();
bean.setDynamicPropertyName("qwerty");
log.info(mapper.getObjectMapper().writeValueAsString(bean));
}
}
应用测试。yml
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
dynamic:
property:
name: overriddenName
我怀疑您能否在Jackson注释中使用Spring Expression Language(SpEL)实现这一点,因为您正在尝试(使用或不使用@Value
注释)。
我将通过创建一个JsonSerializer来实现这一点
//make me a spring managed bean!
public class PojoSerializer extends JsonSerializer<YourPojo> {
@Value("${property.file.reference.name")
private String nameField;
@Value("${property.file.reference.address")
private String addrField;
@Override
public void serialize(YourPojo pojo, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeStringField(nameField, pojo.getName());
jgen.writeStringField(addrField, pojo.getAddress());
jgen.writeEndObject();
}
}
由于这是一个Spring管理的bean,所以需要将其插入Spring管理的
ObjectMapper
。
ObjectMapper mapper = //my ObjectMapper from spring
PojoSerializer pojoSerializer = //my PojoSerializer from spring
SimpleModule module = new SimpleModule("MyModule", new Version(1, 0, 0, null));
module.addSerializer(YourPojo.class, pojoSerializer);
mapper.registerModule(module);
SpringBoot的自动配置可能不需要这样做。我通常不知道SpringBoot将为其Jackson自动配置选择什么,但是如果
JsonSerializer
和JsonDeserializer
位于ApplicationContext
中,它们可能会自动注册。
很抱歉,我又提了一个老问题,但我仍然找不到满意的答案。
下面是我使用扩展的JacksonAnnotationIntrospector
的解决方案,它允许在@JsonProperty
注释中使用${environment.properties}
首先扩展内省者
public class DynamicJacksonAnnotationIntrospector extends JacksonAnnotationIntrospector {
private final Environment environment;
public DynamicJacksonAnnotationIntrospector(Environment environment) {
this.environment = environment;
}
@Override
public PropertyName findNameForSerialization(Annotated a) {
PropertyName name = super.findNameForSerialization(a);
if (name == null) {
return null;
}
String simpleName = name.getSimpleName();
return PropertyName.construct(environment.resolvePlaceholders(simpleName), name.getNamespace());
}
//For deserialization I think the same mechanism could be used,
//just override `findNameForDeserialization`, although I haven't tested it
}
然后使用它与ObjectMapper
配置
@Configuration
public class ObjectMapperConfiguration {
@Bean
public ObjectMapper getObjectMapper(DynamicJacksonAnnotationIntrospector introspector) {
ObjectMapper mapper = new ObjectMapper();
SerializationConfig config = mapper.getSerializationConfig().withInsertedAnnotationIntrospector(introspector);
mapper.setConfig(config);
return mapper;
}
@Bean
public DynamicJacksonAnnotationIntrospector introspector(Environment environment) {
return new DynamicJacksonAnnotationIntrospector(environment);
}
}
例子:
public class DynamicTestClass {
@JsonProperty("${dynamic.property.name}")
private String dynamicPropertyName;
//getters/setters
}
@ContextConfiguration(classes = [
ObjectMapperConfiguration
])
@TestPropertySource("classpath:test.properties")
class DynamicJacksonAnnotationIntrospectorTest extends Specification {
@Autowired
ObjectMapper mapper
def "should find name for serialization from properties"() {
def bean = new DynamicTestClass()
bean.dynamicPropertyName = "qwerty"
when:
def result = mapper.writeValueAsString(bean)
then:
result == "{\"overriddenName\":\"qwerty\"}"
}
}
测验属性
dynamic.property.name=overriddenName
该解决方案是反向兼容的,因此您仍然可以在@JsonProperty
我正在使用与类似 我有在我的主应用程序类上 但是,不起作用。如果我的属性是false,并且我注释掉yaml文件中的CloudBucket对象,它在启动时失败,因为它不能绑定云桶属性。如果属性是false,那么该对象不应该是必需的,然后bean应该是null。我如何使这个工作?
我想启用或禁用具有外部配置的SSL/TLS,这些配置可以在应用程序启动期间提供。应用程序应该支持http和HTTPS的所有crud操作。 既然上面的属性是不推荐使用的,那么我如何在不使用配置文件的情况下实现它。
我可以有条件地使用@JsonUnwrapped吗?我不想在序列化期间使用它,但希望在反序列化对象时使用它。 一种方法是创建两个不同的类,或者创建一个子类覆盖那个属性,这个属性在序列化和反序列化时需要表现得不同。这听起来不太对。还有其他替代方法吗?或者杰克逊解决这个问题的方法吗?
我试图上传多个文件使用Spring mvc 4,Spring引导和thymeleaf作为模板引擎,但我无法访问上传的文件,文件被处理为一个多部分文件与内容类型的应用程序/octet-stream. 以及控制器代码: sysout的输出: 上传图像长度:1(即使我上传了多个文件) 文件原始名称(使用getOrialFileName): 文件名(使用getName):文件[] 文件大小: 0 文件内容
问题内容: 使用样本数据: df 我试图弄清楚如何按key1分组数据并仅对key2等于“ one”的data1值求和。 这是我尝试过的 但这给了我一个数值为“无”的数据框 这里有什么想法吗?我正在寻找与以下SQL等效的Pandas: 提前致谢 问题答案: 首先按key1列分组: 然后为每个组取subDataFrame,其中key2等于“ one”并求和data1列: 为了解释发生了什么,让我们看一
问题内容: 希望您能帮到我。我有一个DF,如下所示: 我很乐意做一个groupBy prodId并汇总“值”,以将其汇总为由“ dateIns”和“ dateTrans”列之间的差异所定义的日期范围。特别是,我希望有一种方法来定义一个条件总和,该总和将上述各列之间的预定义最大差之内的所有值相加。即从dateIns开始的10、20、30天之间发生的所有值(’dateTrans’-‘dateIns’<