我有一个Spring-Boot控制器,它又对另一个服务进行REST调用。因此,控制器内部有一个RestTemplate客户端,需要Json-Root-Value-Wrap-And-Unwrap功能。
根据共同的建议,我做了一个像
这样的客户ObjectMapper@Configuration
public class CustomJsonMapper {
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.featuresToEnable(DeserializationFeature.UNWRAP_ROOT_VALUE);
return builder;
}
}
所以我可以自动连接这个类,并在控制器内的RestTemplate中使用。因此,控制器看起来有点像,
@RestController
@RequestMapping("uat")
public class UatController {
@Autowired
CustomObjectMapper customMapper;
@PostMapping(value = "startWork")
public ResponseEntity<?> startWork(@RequestBody startWorkInput startWorkInput) {
// Build the request
RestTemplate restTemp = new RestTemplate(factory);
restTemp.getMessageConverters().removeIf(m -> m.getClass().getName().equals(MappingJackson2HttpMessageConverter.class.getName()));
restTemp.getMessageConverters().add(new MappingJackson2HttpMessageConverter(customMapper));
// Proceed to make client call
}
}
但是,这会导致SpringBoot中的默认ObjectMapper被覆盖,我猜。这就是我需要将输入的根值包装到此服务的原因。
有没有办法使用自定义ObjectMapper而不会超越默认值。
答案 0 :(得分:2)
如果映射器只局限于一个bean,你可以将它声明为一个字段而不是一个单独的bean:
@RestController
@RequestMapping("uat")
public class UatController {
private final ObjectMapper customMapper = Jackson2ObjectMapperBuilder.json()
.featuresToEnable(DeserializationFeature.UNWRAP_ROOT_VALUE)
.build();
...
如果您需要重复使用,可以尝试重新定义ObjectMapper
bean并标记默认值@Primary
:
@Configuration
public class CustomJsonMapper {
@Bean
@Primary
public ObjectMapper objectMapper() {
return Jackson2ObjectMapperBuilder.json().build();
}
@Bean
public ObjectMapper customObjectMapper() {
return Jackson2ObjectMapperBuilder.json()
.featuresToEnable(DeserializationFeature.UNWRAP_ROOT_VALUE)
.build();
}
}
然而,它比仅仅对需要它的单个控制器进行本地化更复杂。而且,它违反了JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration
类中的自动配置惯例。