Spring 4.1 instanziiert eine Jackson ObjectMapper
-Instanz. Ich habe Grund, diese Instanz in einen meiner Controller @Autowire
einbauen zu wollen: Der Controller führt mit Jackson einige geringfügige JSON-Analysen durch, aber die verwendete ObjectMapper
sollte die gleiche Instanz sein, die Spring selbst verwendet. Wie mache ich das?
Beachten Sie, dass ich nicht frage, wie Sie die von Spring verwendete ObjectMapper
benutzerdefiniert konfigurieren. Ich bin mit den Standardeinstellungen zufrieden. Ich möchte nur die von Spring out verwendete Instanz fischen, sodass ich die vorhandene Instanz in meinem eigenen Code wiederverwenden kann.
Wenn Sie Spring Boot mit Jackson für Ihren Klassenpfad und die Standardimplementierung für JSON-Analyse in Ihrem REST -Controller verwenden, sollte dies funktionieren:
@Autowired
private ObjectMapper jacksonObjectMapper;
Wenn Sie sich MappingJackson2HttpMessageConverter
ansehen, werden Sie feststellen, dass eine neue ObjectMapper
erstellt wird, diese jedoch nicht als Bean verfügbar gemacht wird. Es gibt einen Getter, aber der einzige Weg, wie ich ihn in der Vergangenheit herausgefischt habe, ist, als ich den MappingJackson2HttpMessageConverter
selbst erstellt habe, z.
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter jacksonMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = jacksonMessageConverter.getObjectMapper();
objectMapper.registerModule(new JodaModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
converters.add(jacksonMessageConverter);
}
}
Wenn Sie mit Spring Boot arbeiten, gibt es im Handbuch einen section für die Arbeit mit der ObjectMapper
. Wenn Sie einen Standardcode Jackson2ObjectMapperBuilder
@Bean
erstellen, sollten Sie dieselbe ObjectMapper
-Instanz in Ihrem Controller automatisch aktivieren können.
Wie von anderen schon gesagt, können Sie es nicht direkt in Ihren Controller @Autowired
eingeben.
@Emerson Farrugias Vorschlag, eine neue Instanz mit zu erstellen
Jackson2ObjectMapperBuilder.json().build()
funktionierte auch nicht für mich, da die erhaltene Instanz nicht den spring.jackson.*
-Konfigurationseigenschaften folgte, für die ich sie brauchte.
Die Lösung, die ich fand, bestand darin, den ObjectMapper von Spring's MappingJackson2HttpMessageConverter
zu erhalten, der injizierbar ist.
Also habe ich es autowired:
@Autowired
private MappingJackson2HttpMessageConverter springMvcJacksonConverter;
und dann den ObjectMapper so abrufen:
ObjectMapper objectMapper = springMvcJacksonConverter.getObjectMapper();
Diese Instanz verhält sich genau wie Spring MVCs eigene Nachrichtenkonvertierung - wahrscheinlich ist ist dieselbe Instanz.
Fügen Sie in Ihrer @SpringBootApplication
-Klasse Folgendes hinzu:
@Bean
public ObjectMapper mapper() {
return new ObjectMapper();
}
Überall, wo Sie ObjectMapper
verwenden möchten:
@Autowired
ObjectMapper mapper;
Frieden!
Die Variable ObjectMapper
wird von Jackson2ObjectMapperBuilder
erstellt. Sie können den Builder mit folgendem Befehl einfügen:
@Autowired
private Jackson2ObjectMapperBuilder mapperBuilder;
Verwenden Sie dann mapperBuilder.build()
, um eine ObjectMapper
-Instanz zu erstellen. Diese Instanz kann Konfigurationen in application.properties
verwenden. Offizielles Dokument hier.
Ich habe im Quellcode von Spring Boot debuggt und festgestellt, dass nur wenn wir den gesamten Kontext starten Jackson2ObjectMapperBuilder
Die Konfiguration enthält, die wir in application.yml
Eingeben.
Das bedeutet, wenn wir einen ObjectMapper in einem Spring Boot-Test mit JUnit 5 generieren möchten, müssen wir:
@ExtendWith(SpringExtension.class)
@SpringBootTest
class SomeTest {
@Autowired
private Jackson2ObjectMapperBuilder builder;
...
@Test
void testObjectMapper() {
ObjectMapper mapper = builder.build();
}
Wir können nicht nur @SpringBootTest(classes = Jackson2ObjectMapperBuilder.class)
erzeugen, um diesen Builder zu erzeugen.
Wenn wir bootRun
haben wir dieses Problem nicht.
Die Konfiguration wird in der Jackson2ObjectMapperBuilderCustomizerConfiguration#customize(Jackson2ObjectMapperBuilder builder)
-Methode festgelegt.
Wenn Sie versuchen, den MappingJackson2HttpMessageConverter @Autowire auszuführen, erhalten Sie Folgendes: No qualifying bean of type 'org.springframework.http.converter.json.MappingJackson2HttpMessageConverter' available: expected single matching bean but found 4: mappingJackson2HttpMessageConverter,jacksonHttpMessageConverter,halJacksonHttpMessageConverter,alpsJsonHttpMessageConverter
.
Dies ist kein großes Problem. Sie können den Variablennamen einfach in einen der obigen Werte ändern, um diese Instanz zu erhalten: @Autowired
private MappingJackson2HttpMessageConverter halJacksonHttpMessageConverter;