Spring Data Rest:自定义 JsonDeserializer 中的 @Autowire
Posted
技术标签:
【中文标题】Spring Data Rest:自定义 JsonDeserializer 中的 @Autowire【英文标题】:Spring Data Rest: @Autowire in Custom JsonDeserializer 【发布时间】:2019-12-18 20:42:48 【问题描述】:我正在尝试将组件自动装配到自定义 JsonDeserializer 中,但即使我找到了以下建议,也无法正确完成:
Autowiring in JsonDeserializer: SpringBeanAutowiringSupport vs HandlerInstantiator Right way to write JSON deserializer in Spring or extend it How to customise the Jackson JSON mapper implicitly used by Spring Boot? Spring Boot Autowiring of JsonDeserializer in Integration test我的最终目标是接受不同微服务中资源的 URL,并仅在本地存储资源的 ID。但我不想只从 URL 中提取 ID,还要验证 URL 的其余部分是否正确。
我已经尝试了很多东西,但我对我尝试过的东西有点迷失了,但我相信我尝试了上面链接中提到的所有东西。我为 SpringHandlerInstantiator、Jackson2ObjectMapperBuilder、MappingJackson2HttpMessageConverter、RestTemplate 等创建了大量的 bean,还尝试在 RepositoryRestConfigurer#configureJacksonObjectMapper 中设置 SpringHandlerInstantiator。
我正在使用 Spring Boot 2.1.6.RELEASE,这让我觉得有些东西可能已经改变了,因为一些链接的线程已经很老了。
这是我的最后一次尝试:
@Configuration
public class JacksonConfig
@Bean
public HandlerInstantiator handlerInstantiator(ApplicationContext applicationContext)
return new SpringHandlerInstantiator(applicationContext.getAutowireCapableBeanFactory());
@Configuration
public class RestConfiguration implements RepositoryRestConfigurer
@Autowired
private Validator validator;
@Autowired
private HandlerInstantiator handlerInstantiator;
@Override
public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener)
validatingListener.addValidator("beforeCreate", validator);
validatingListener.addValidator("beforeSave", validator);
@Override
public void configureJacksonObjectMapper(ObjectMapper objectMapper)
objectMapper.setHandlerInstantiator(handlerInstantiator);
@Component
public class RestResourceURLSerializer extends JsonDeserializer<Long>
@Autowired
private MyConfig config;
@Override
public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException
ServiceConfig serviceConfig = config.getServices().get("identity");
URI serviceUri = serviceConfig.getExternalUrl();
String servicePath = serviceUri.getPath();
URL givenUrl = p.readValueAs(URL.class);
String givenPath = givenUrl.getPath();
if (servicePath.equals(givenPath))
return Long.parseLong(givenPath.substring(givenPath.lastIndexOf('/') + 1));
return null;
我不断收到 NullPointerException POST 到 API 端点的信息,该端点使用上面的 JsonDeserializer 反序列化。
【问题讨论】:
【参考方案1】:我能够通过将我的反序列化器构造函数标记为接受一个参数(并因此删除空构造函数)并将构造函数标记为@Autowired 来解决类似的问题。
public class MyDeserializer extends JsonDeserializer<MyEntity>
private final MyBean bean;
// no default constructor
@Autowired
public MyDeserializer(MyBean bean)
this.bean = bean
...
@JsonDeserialize(using = MyDeserializer.class)
public class MyEntity...
我的实体标有 @JsonDeserialize 注释,因此我不必使用 ObjectMapper 显式注册它。
【讨论】:
以上是关于Spring Data Rest:自定义 JsonDeserializer 中的 @Autowire的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data Rest - 在 Json 中禁用自我链接(HAL)
如何使用Spring Boot REST生成自定义JSON响应?
我可以让自定义控制器镜像 Spring-Data-Rest / Spring-Hateoas 生成的类的格式吗?