我想在Spring Boot应用程序(1.5.6)中加载application.yml
中配置的时区。春天是5.0.4。
我看到它已加载到我的测试课程中:
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest // to load test application.yml
public class KafkaUserPurchaseDTOTest {
private static String jsonDataUpdate = "";
@Value("${time-zone.name}")
private String timezone; // <---------- the value is loaded here
private ObjectMapper mapper;
@BeforeClass
public static void prepare() throws IOException {
InputStream in = KafkaUserPurchaseDTOTest.class.getResourceAsStream("/fixture/kafka-data-user-purchase-update.json");
jsonDataUpdate = IOUtils.toString(in, Charset.defaultCharset());
}
@Test
public void testConvertJsonToPurchaseDTO() throws IOException {
// given
assert !jsonDataUpdate.isEmpty() : "Must load the json file";
mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // just take the fields we need
mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
mapper.setTimeZone(TimeZone.getTimeZone("Europe/Budapest"));
mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, true);
// when
UserPurchaseDTO dto = mapper.readValue(jsonDataUpdate, UserPurchaseDTO.class); // <------------ here we enter serializer....
// then
Assert.assertNotNull(dto);
Assert.assertNotNull(dto.getMemberId());
Assert.assertNotNull(dto.getLastBuyDate());
// See the example JSON for exact values
Assert.assertEquals("2018-03-19 09:16:11", DateTimeUtil.formatDateWithMilliPart(dto.getLastBuyDate(), false));
Assert.assertEquals(790849L, dto.getMemberId().longValue());
}
//@Test TODO more test on empty/null values
}
但是在序列化程序中,即使使用@Component
进行注释,也不会加载相同的值。
@Slf4j
@Component
public class KafkaUserPurchaseDeserializer extends StdDeserializer<UserPurchaseDTO> {
@Value("${time-zone.name}")
private String timezone;
public KafkaUserPurchaseDeserializer() {
this(null);
}
public KafkaUserPurchaseDeserializer(Class<?> c) {
super(c);
}
@Override
public UserPurchaseDTO deserialize(JsonParser parser, DeserializationContext context) throws IOException {
JsonNode root = parser.getCodec().readTree(parser);
UserPurchaseDTO dto = new UserPurchaseDTO();
String Id = root.get(UserPurchaseDTO.JSON_PROP_KAFKA_FK_MEMBER_PK).asText();
if (StringUtils.hasText(Id)) {
try {
dto.setMemberId(Long.parseLong(Id));
} catch (NumberFormatException e) {
log.error("Cannot format {} to number", Id, e);
return null;
}
} else {
log.error("Cannot find user id for this message: {}", root.toString());
return null;
}
String lastBuy = root.get(UserPurchaseDTO.JSON_PROP_KAFKA_LAST_DATE).textValue();
if (StringUtils.hasText(lastBuy)) {
try {
dto.setLastBuyDate(DateTimeUtil.convertDateToAppConfigTimeZone(timezone, lastBuy, false)); // <----------------- here: timezone = null
} catch (DateTimeParseException e) {
log.error("Cannot parse {} to date", lastBuy, e);
return null;
}
} else {
log.info("User Purchase comes without last buy date. The node has content: {}", lastBuy);
}
return dto;
}
}
为什么?他们不在同一上下文中吗?
答案 0 :(得分:0)
尝试在您的配置中定义此bean:
@Bean
public PropertySourcesPlaceholderConfigurer configurer(){
return new PropertySourcesPlaceholderConfigurer();
}
答案 1 :(得分:0)
现在问了一下,我发现我正在创建另一个ObjectMapper
而不是使用Spring上下文。我不再实例化它,而只是使用@Autowired
,它开始起作用。
@Autowired
private ObjectMapper mapper;
我还删除了配置mapper
的部分,因为如果从上下文中加载它,则应在application.yml
中完成。