0

JsonUtilsデータをシリアル化および逆シリアル化するためのさまざまな関数を含むクラスを作成しています。

 public class JsonUtils {

        private static final ObjectMapper JSON_MAPPER = new ObjectMapper();

        public static String toJsonString(Object obj)  {

            String json = null;

            JSON_MAPPER.setPropertyNamingStrategy(new CustomNamingStrategy());
            JSON_MAPPER.setSerializationInclusion(Inclusion.NON_NULL);

            try {
                System.out.print("OBJECT MAPPER:---> JSON STRING:\n" + JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj));
                json = JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
            } catch (JsonGenerationException e) {
                e.printStackTrace();
            } catch (JsonMappingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return json;
        }

        public static <T> T toPOJO(String json, Class<T> type){

            JSON_MAPPER.setPropertyNamingStrategy(new CustomNameNamingStrategy());
            System.out.println("TO POJO: Json string " + json);
            try {

                return JSON_MAPPER.readValue(json, type);

            } catch (JsonParseException e) {
                e.printStackTrace();
            } catch (JsonMappingException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

今、私は関数を一般的に使用したいと考えています。例: 誰かがメソッドを呼び出しtoJsonStringたいが、別の命名戦略を使用して json に変換したい場合。またはObjectMapper、モジュールを登録するなどの他のプロパティを追加することもできます。

Currently, the ObjectMapper properties are being set inside the function, thus a new naming strategy or a different property for ObjectMapper can't be used.

Is there a way that every user for JsonUtils initially sets it's own properties for ObjectMapper ? Or a efficient and generic way to write my Utility class ?

4

2 に答える 2

1

次のようなものを使用できます。

ObjectMapperProperties.java

package example;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;

        public class ObjectMapperProperties {

            private PropertyNamingStrategy propertyNamingStrategy;

            private ObjectMapperProperties(final PropertyNamingStrategy propertyNamingStrategy) {
                this.propertyNamingStrategy = propertyNamingStrategy;
            }

            public PropertyNamingStrategy getPropertyNamingStrategy() {
                return propertyNamingStrategy;
            }

            public static class ObjectMapperPropertiesBuilder {

                private PropertyNamingStrategy builderPropertyNamingStrategy;

                public ObjectMapperPropertiesBuilder() {

                }

                public ObjectMapperPropertiesBuilder setPropertyNamingStrategy(final PropertyNamingStrategy builderPropertyNamingStrategy) {
                    this.builderPropertyNamingStrategy = builderPropertyNamingStrategy; 
                    return this;
                }

                public ObjectMapperProperties build() {
                    return new ObjectMapperProperties(builderPropertyNamingStrategy);
                }

            }
    }

ObjectMapperFactory.java

package example;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ObjectMapperFactory {

    public static ObjectMapper getObjectMapper(final ObjectMapperProperties objectMapperProperties) {
        final ObjectMapper result = new ObjectMapper();
        result.setPropertyNamingStrategy(objectMapperProperties.getPropertyNamingStrategy());
        return result;
    }

}

Client.class

package example;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;

import example.ObjectMapperProperties.ObjectMapperPropertiesBuilder;

public class Client {

    public static void main(String[] args) {
        ObjectMapperPropertiesBuilder objectMapperPropertiesBuilder = new ObjectMapperPropertiesBuilder();
        objectMapperPropertiesBuilder.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
        ObjectMapperFactory factory = new ObjectMapperFactory();
        ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(objectMapperPropertiesBuilder.build());

    }

}

必要に応じて設定して ObjectMapper を作成するよりも。意味がなく、既に作成されたインスタンスでプロパティを 2 回設定するとエラーが発生しやすくなります。

private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
JSON_MAPPER.setSerializationInclusion(Inclusion.NON_NULL);

たとえば、次回このプロパティをリセットする必要がありますが、いくつかのファクトリを介して新しい ObjectMapper() を作成することは貴重であり、エラーが発生しにくくなります

答え:

いいえ、呼び出しごとに ObjectMapperFactory を介して ObjectMapper の新しいインスタンスを作成し、ObjectMapperProperties を渡すだけです。

public static String toJsonString(Object obj,final ObjectMapperProperties objectMapperProperties)  {

ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper(objectMapperProperties);
}

新しい ObjectMapper インスタンスを作成したくなく、プロパティが最終的な場合 (常に同じプロパティで ObjectMapper を作成することを意味します)、メソッドを作成します。

public static String toJsonString(Object obj, ObjectMapper objMapper)  {}

2 番目の質問はビルダー パターンを参照してください

Factory をインターフェイスとして使用してバリエーションをより適切にテストするには、次のようにすると便利です。

ObjectMapperFactory.class

public interface ObjectMapperFactory {

    public ObjectMapper getObjectMapper(final ObjectMapperProperties objectMapperProperties) {
}

ObjectMapperFactory の実装

ObjectMapperFactoryImpl.class

package example;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ObjectMapperFactoryImpl implements ObjectMapperFactory {

    public ObjectMapper getObjectMapper(final ObjectMapperProperties objectMapperProperties) {
        final ObjectMapper result = new ObjectMapper();
        result.setPropertyNamingStrategy(objectMapperProperties.getPropertyNamingStrategy());
        return result;
    }

}

そしてあなたのクラスで

 public class JsonUtils {

      private final ObjectMapperFactory objectMapperFactory;

      public JsonUtils(final ObjectMapperFactory objectMapperFactory) {
              this.objectMapperFactory = objectMapperFactory;
      }
}

しかし、それは単なる変形です。あなたの目的のためには、上記の回答で十分です。

于 2016-01-11T10:37:48.893 に答える
0

ハッシュマップを使用して、呼び出しの前に、呼び出し元の関数から最初に次のような設定値を入力できます

Map <String, String>settings = new HashMap<String, String>();
        settings.put("CUSTOM_NAMING_PROPERTY", "CAMEL_CASE");

関数内toJsonStringで値を確認します。

    public static String toJsonString(Object obj,Map settings )  {

                String json = null;
                if(settings.get("CUSTOM_NAMING_PROPERTY")!=null){
                    //put your settings here.......
                }
                /////....... contd.....

                JSON_MAPPER.setSerializationInclusion(Inclusion.NON_NULL);

                try {
                    System.out.print("OBJECT MAPPER:---> JSON STRING:\n" + JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj));
                    json = JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
                } catch (JsonGenerationException e) {
                    e.printStackTrace();
                } catch (JsonMappingException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return json;
            }
于 2016-01-11T08:32:10.290 に答える