本文介绍了如何配置杰克逊在Micronaut中使用SNAKE_CASE?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已尝试将杰克逊配置为在使用Micronaut时使用SNAKE_CASE接受JSON,但是,它无法识别属性jackson.property-naming-strategy: SNAKE_CASE.

I have tried to configure jackson to accept JSON using SNAKE_CASE when using Micronaut, however, it doesn't recognize the property jackson.property-naming-strategy: SNAKE_CASE.

推荐答案

来自Micronaut 1.1.1

application.yml

jackson:
    property-naming-strategy: SNAKE_CASE

在Micronaut 1.1.1之前

Micronaut使用ObjectMapper.不设置属性命名策略的Java#L82"rel =" nofollow noreferrer> ObjectMapperFactory (至少在Micronaut 1.0 GA版本中,在将来的版本中可能会更改).配置类不支持您在问题中提到的配置选项,因此使用它根本无济于事.但是,您可以将ObjectMapperFactory类替换为您自己的自定义实现,该实现以默认方式构造ObjectMapper并设置属性命名策略.考虑以下示例:

Before Micronaut 1.1.1

Micronaut constructs ObjectMapper using ObjectMapperFactory that does not set property naming strategy (at least in Micronaut 1.0 GA version, this may change in future releases). The configuration option you have mentioned in the question is not supported by the configuration class, so using it simply does nothing. However, you can replace ObjectMapperFactory class with your own custom implementation that constructs ObjectMapper in the default way + it sets property naming strategy. Consider following example:

package com.github.wololock.micronaut;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import io.micronaut.context.annotation.Factory;
import io.micronaut.context.annotation.Replaces;
import io.micronaut.jackson.JacksonConfiguration;
import io.micronaut.jackson.ObjectMapperFactory;
import io.micronaut.runtime.Micronaut;

import javax.inject.Singleton;
import java.util.Optional;

public class Application {

    public static void main(String[] args) {
        Micronaut.run(Application.class);
    }

    @Factory
    @Replaces(ObjectMapperFactory.class)
    static class CustomObjectMapperFactory extends ObjectMapperFactory {

        @Override
        @Singleton
        @Replaces(ObjectMapper.class)
        public ObjectMapper objectMapper(Optional<JacksonConfiguration> jacksonConfiguration, Optional<JsonFactory> jsonFactory) {
            final ObjectMapper mapper = super.objectMapper(jacksonConfiguration, jsonFactory);
            mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
            return mapper;
        }
    }
}

在此示例中,我向主Application类添加了静态类CustomObjectMapperFactory,并且使用了@Replaces注释来指示Micronaut使用此自定义工厂类提供的该工厂类和objectMapper()方法.我们从该工厂返回的ObjectMapper实例基于默认工厂方法+它添加了:

In this example I have added a static class CustomObjectMapperFactory to the main Application class and I have used @Replaces annotation to instruct Micronaut to use this factory class and objectMapper() method provided by this custom factory class. The ObjectMapper instance we return from this factory is based on the default factory method + it adds:

mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

设置预期的属性命名策略.

to set expected property naming strategy.

以下是示例输出,添加了此自定义工厂类后,我在响应中得到了返回:

And here is exemplary output I get back in the response after adding this custom factory class:

HTTP/1.1 200 OK
Date: Wed, 7 Nov 2018 19:15:10 GMT
connection: keep-alive
content-length: 38
content-type: application/json

{
    "first_name": "Joe",
    "last_name": "Doe"
}

默认情况下(没有此自定义工厂类),响应如下所示:

By default (without this custom factory class) the response looked like this:

HTTP/1.1 200 OK
Date: Wed, 7 Nov 2018 19:04:14 GMT
connection: keep-alive
content-length: 36
content-type: application/json

{
    "firstName": "Joe",
    "lastName": "Doe"
}


更新:改用BeanCreatedEventListener<ObjectMapper>

还有一种实现相同效果的替代方法,它需要更少的代码行数.鸣谢到 Micronaut Framework Twitter帐户:)


UPDATE: Using BeanCreatedEventListener<ObjectMapper> instead

There is an alternative way to achieve the same effect that requires even less amount of lines of code. Credits goes to Micronaut Framework Twitter account :)

我们可以使用BeanCreatedEventListener<T>来响应bean创建事件,并允许我们扩展刚刚创建的bean.在这种情况下,这意味着添加一个实现BeanCreatedEventListener<ObjectMapper>并设置属性命名策略的类:

We can use BeanCreatedEventListener<T> that reacts to bean creation event and allows us extending the bean that just got created. In this case it means adding a class that implements BeanCreatedEventListener<ObjectMapper> and sets property naming strategy:

package com.github.wololock.micronaut;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import io.micronaut.context.event.BeanCreatedEvent;
import io.micronaut.context.event.BeanCreatedEventListener;
import io.micronaut.runtime.Micronaut;

import javax.inject.Singleton;

public class Application {

    public static void main(String[] args) {
        Micronaut.run(Application.class);
    }

    @Singleton
    static class ObjectMapperBeanEventListener implements BeanCreatedEventListener<ObjectMapper> {

        @Override
        public ObjectMapper onCreated(BeanCreatedEvent<ObjectMapper> event) {
            final ObjectMapper mapper = event.getBean();
            mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
            return mapper;
        }
    }
}

此解决方案的优点:

  • 更少的代码行
  • 少一层抽象层(我们不必为ObjectMapperFactory操心,我们只关心配置现有的ObjectMapper bean).
  • less lines of code
  • one abstraction layer less (we don't have to bother with ObjectMapperFactory, we just care about configuring existing ObjectMapper bean).

这篇关于如何配置杰克逊在Micronaut中使用SNAKE_CASE?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 07:06