একটি মানচিত্র <স্ট্রিং, স্ট্রিং> কে একটি পোজে রূপান্তর করুন


185

আমি জ্যাকসনের দিকে তাকাচ্ছি, তবে মনে হচ্ছে আমাকে মানচিত্রটি জেএসওনে রূপান্তর করতে হবে, এবং তারপরে ফলস্বরূপ জেএসওএনকে পোজোতে রূপান্তর করতে হবে।

মানচিত্রকে সরাসরি পজোতে রূপান্তর করার কোনও উপায় আছে কি?

উত্তর:


355

ঠিক আছে, আপনি জ্যাকসনের সাথে এটিও অর্জন করতে পারেন। (এবং আপনি যেহেতু জ্যাকসন ব্যবহারের বিষয়টি বিবেচনা করছেন সেহেতু এটি আরও স্বাচ্ছন্দ্যবোধক বলে মনে হচ্ছে)।

ObjectMapperএর convertValueপদ্ধতিটি ব্যবহার করুন :

final ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper
final MyPojo pojo = mapper.convertValue(map, MyPojo.class);

জেএসএন স্ট্রিং বা অন্য কিছুতে রূপান্তর করার দরকার নেই; সরাসরি রূপান্তর অনেক দ্রুত করে।


8
অবজেক্টম্যাপার ব্যবহার করতে আপনাকে এই গ্রন্থাগারটি অন্তর্ভুক্ত করতে হবেcompile 'com.fasterxml.jackson.core:jackson-databind:2.7.3'
শজিল আফজাল

5
রূপান্তরভ্যালু ব্যবহার করা সঠিক উত্তর, তবে প্রতিবার কোনও অবজেক্টম্যাপার উদাহরণ তৈরি করবেন না। এটি তৈরি এবং থ্রেড-নিরাপদ ব্যয়বহুল, সুতরাং একটি তৈরি করুন এবং এটি কোথাও ক্যাশে করুন।
গ্লেড

1
আপনি কি জানেন কীভাবে বিপরীত করতে হয় - বা কোনও মানচিত্র <স্ট্রিং, অবজেক্ট> এ কীভাবে রূপান্তর করতে হয়?
anon58192932

2
@ রাদুসিমিনেস্কু আপনি কীভাবে বুঝতে পেরেছেন যে নেস্টেড মানচিত্র / তালিকাগুলি দিয়ে কোনও Map<String, Object>উদাহরণকে কীভাবে গভীর রূপান্তর করতে হবে ?
anon58192932

@ anon58192932 আপনি যদি এই উত্তরটি অনুসরণ করেন তবে এটি কাজ করে। আমি কেবল কিছু অদ্ভুত জিনিসগুলির সাথে কাজ করছিলাম যা মানচিত্র হিসাবে তালিকার মডেলিং করছিল এবং সিরিয়ালাইজিংয়ের সময় অপ্রত্যাশিত ফলাফল পাচ্ছিল। তবে এটি অন্য ইস্যু ছিল, জ্যাকসনের সাথে কিছুই করার ছিল না
রাদু সিমিনেস্কু

60

গসনের সাথে একটি সমাধান :

Gson gson = new Gson();
JsonElement jsonElement = gson.toJsonTree(map);
MyPojo pojo = gson.fromJson(jsonElement, MyPojo.class);

1
তদ্বিপরীতটি কী হবে
প্রবস

2
@ প্র্যাবস - এর বিপরীতে gson.toJson () হবে
আলিকেলজিন-কিলাকা

মানচিত্রে জসন রূপান্তর করার দরকার নেই। map.toString () যথেষ্ট। গসন গসন = নতুন গসন (); মাইপোজো পোজো = gson.fromJson (map.toString (), মাইপোজো.ক্লাস);
এসাক্কিয়াপ্পান .E

1
@ এসাক্কিয়াপ্পান.ই, আপনি কেন ভাবেন map.toString()যে সঠিক স্ট্রিং সরবরাহ করবে? এর বাস্তবায়ন toString()একটি নির্দিষ্ট বিন্যাসের গ্যারান্টি দেয় না।
অ্যালিকেলজিন-কিলাকা

4

হ্যাঁ, জেএসএনে অন্তর্বর্তী রূপান্তর এড়ানো নিশ্চিতভাবেই সম্ভব। ডোজারের মতো গভীর-অনুলিপি সরঞ্জাম ব্যবহার করা আপনি একটি POJO সরাসরি মানচিত্র রূপান্তর করতে পারেন। এখানে সরল উদাহরণ রয়েছে:

POJO উদাহরণ:

public class MyPojo implements Serializable {
    private static final long serialVersionUID = 1L;

    private String id;
    private String name;
    private Integer age;
    private Double savings;

    public MyPojo() {
        super();
    }

    // Getters/setters

    @Override
    public String toString() {
        return String.format(
                "MyPojo[id = %s, name = %s, age = %s, savings = %s]", getId(),
                getName(), getAge(), getSavings());
    }
}

নমুনা রূপান্তর কোড:

public class CopyTest {
    @Test
    public void testCopyMapToPOJO() throws Exception {
        final Map<String, String> map = new HashMap<String, String>(4);
        map.put("id", "5");
        map.put("name", "Bob");
        map.put("age", "23");
        map.put("savings", "2500.39");
        map.put("extra", "foo");

        final DozerBeanMapper mapper = new DozerBeanMapper();
        final MyPojo pojo = mapper.map(map, MyPojo.class);
        System.out.println(pojo);
    }
}

আউটপুট:

মাইপোজো [আইডি = 5, নাম = বব, বয়স = 23, সঞ্চয় = 2500.39]

দ্রষ্টব্য: আপনি যদি নিজের উত্সের মানচিত্রটিকে কোনওটিতে পরিবর্তন করেন Map<String, Object>তবে আপনি নির্বিচারে গভীর নেস্টেড বৈশিষ্ট্যগুলি অনুলিপি করতে পারেন (আপনার সাথে Map<String, String>কেবল একটি স্তর পাওয়া যায়)।


1
আপনি কীভাবে মানচিত্র থেকে পোজোতে "গভীর অনুলিপি" করতে পারেন? উদাহরণস্বরূপ বলুন আপনার কাছে একটি ইউজার.ক্লাস রয়েছে যা একটি অ্যাড্রেসক্লাসকে encapsulate করে এবং মানচিত্রে একটি "keyCress" অ্যাড্রেসসিটি "," অ্যাড্রেস.জিপ "রয়েছে এবং এগুলি ব্যবহারকারীর কাছে মানচিত্রের প্রয়োজন d অ্যাড্রেস.সিটি এবং ব্যবহারকারী। অ্যাড্রেস.জাইপ ? মানচিত্র কীতে বিন্দুটি স্বয়ংক্রিয়ভাবে গ্রাফের উপ-স্তর হিসাবে ব্যাখ্যা করবে বলে মনে হয় না।
szxnyc

3

যদি আপনি আপনার ক্লাসে জেনেরিক ধরনের আপনি ব্যবহার করা উচিত TypeReferenceসঙ্গে convertValue()

final ObjectMapper mapper = new ObjectMapper();
final MyPojo<MyGenericType> pojo = mapper.convertValue(map, new TypeReference<MyPojo<MyGenericType>>() {});

এছাড়াও আপনি এটি কোনও পোজোর java.util.Mapপিছনে রূপান্তর করতে ব্যবহার করতে পারেন ।

final ObjectMapper mapper = new ObjectMapper();
final Map<String, Object> map = mapper.convertValue(pojo, new TypeReference<Map<String, Object>>() {});

2

আমি জ্যাকসন এবং বিয়ান ইউটিল উভয়ই পরীক্ষা করে দেখেছি যে বিয়ান ইউটিসগুলি আরও দ্রুত।
আমার মেশিনে (উইন্ডোজ 8.1, জেডিকে 1.7) আমি এই ফলাফল পেয়েছি।

BeanUtils t2-t1 = 286
Jackson t2-t1 = 2203


public class MainMapToPOJO {

public static final int LOOP_MAX_COUNT = 1000;

public static void main(String[] args) {
    Map<String, Object> map = new HashMap<>();
    map.put("success", true);
    map.put("data", "testString");

    runBeanUtilsPopulate(map);

    runJacksonMapper(map);
}

private static void runBeanUtilsPopulate(Map<String, Object> map) {
    long t1 = System.currentTimeMillis();
    for (int i = 0; i < LOOP_MAX_COUNT; i++) {
        try {
            TestClass bean = new TestClass();
            BeanUtils.populate(bean, map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    long t2 = System.currentTimeMillis();
    System.out.println("BeanUtils t2-t1 = " + String.valueOf(t2 - t1));
}

private static void runJacksonMapper(Map<String, Object> map) {
    long t1 = System.currentTimeMillis();
    for (int i = 0; i < LOOP_MAX_COUNT; i++) {
        ObjectMapper mapper = new ObjectMapper();
        TestClass testClass = mapper.convertValue(map, TestClass.class);
    }
    long t2 = System.currentTimeMillis();
    System.out.println("Jackson t2-t1 = " + String.valueOf(t2 - t1));
}}

5
পার্থক্যটি হ'ল: জ্যাকসনের সাথে এটির পুরো ধরণের রূপান্তর কাঠামো রয়েছে। যেমন Mapঅন্তর্ভুক্ত রয়েছে map.put("data","2016-06-26")এবং TestClassএর একটি ক্ষেত্র রয়েছে private LocalDate data;, তখন জ্যাকসন জিনিসগুলি সম্পন্ন করতে সক্ষম হবেন, এবং বিয়ান ইউটিলস ব্যর্থ হবে।
বেনিয়ামিন এম

6
আমি শুনেছি যে ObjectMapperউদাহরণ তৈরি করা একটি সময় / সংস্থান গ্রহণকারী প্রক্রিয়া এবং এটি প্রতিবার নতুন করে তৈরি করার পরিবর্তে একটি ম্যাপার উদাহরণ পুনরায় ব্যবহার করার পরামর্শ দেওয়া হয়। আমি মনে করি এটি পরীক্ষার
লপ

3
ন্যায্য পরীক্ষা নয়, যেহেতু বিয়ান ইউটিলস প্রথম পুনরাবৃত্তির পরে ক্যাশে করতে সক্ষম হয়, তবে অবজেক্টম্যাপারকে কখনই সুযোগ দেওয়া হয় না।
লুকাস রস

1

জ্যাকসন ব্যবহার করে এখনও অবধি প্রদত্ত উত্তরগুলি খুব ভাল, তবে বিভিন্ন উপায়ে রূপান্তর করতে আপনাকে নীচের মত ব্যবহার করতে পারে তবে POJO:

    public static <T> T convert(Map<String, Object> aMap, Class<T> t) {
        try {
            return objectMapper
                    .convertValue(aMap, objectMapper.getTypeFactory().constructType(t));
        } catch (Exception e) {
            log.error("converting failed! aMap: {}, class: {}", getJsonString(aMap), t.getClass().getSimpleName(), e);
        }
        return null;
    }

0

মানচিত্রটিকে পজো উদাহরণে রূপান্তর করুন ot নোটস কীটিতে আন্ডারলাইন থাকে এবং ক্ষেত্রের ভেরিয়েবল হুম্প।

ইউজার.ক্লাস পোস্টো

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

@Data
public class User {
    @JsonProperty("user_name")
    private String userName;
    @JsonProperty("pass_word")
    private String passWord;
}

App.class উদাহরণ পরীক্ষা

import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.databind.ObjectMapper;

public class App {
    public static void main(String[] args) {
        Map<String, String> info = new HashMap<>();
        info.put("user_name", "Q10Viking");
        info.put("pass_word", "123456");

        ObjectMapper mapper = new ObjectMapper();
        User user = mapper.convertValue(info, User.class);

        System.out.println("-------------------------------");
        System.out.println(user);
    }
}
/**output
-------------------------------
User(userName=Q10Viking, passWord=123456)
 */

0

@ হামেদজ যদি প্রচুর ডেটা ব্যবহার করে, জ্যাকসনকে হালকা ডেটা রূপান্তর করতে, অ্যাপাচি ব্যবহার করুন ... টেস্টকেস:

import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import org.apache.commons.beanutils.BeanUtils; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; public class TestPerf { public static final int LOOP_MAX_COUNT = 1000; public static void main(String[] args) { Map<String, Object> map = new HashMap<>(); map.put("success", true); map.put("number", 1000); map.put("longer", 1000L); map.put("doubler", 1000D); map.put("data1", "testString"); map.put("data2", "testString"); map.put("data3", "testString"); map.put("data4", "testString"); map.put("data5", "testString"); map.put("data6", "testString"); map.put("data7", "testString"); map.put("data8", "testString"); map.put("data9", "testString"); map.put("data10", "testString"); runBeanUtilsPopulate(map); runJacksonMapper(map); } private static void runBeanUtilsPopulate(Map<String, Object> map) { long t1 = System.currentTimeMillis(); for (int i = 0; i < LOOP_MAX_COUNT; i++) { try { TestClass bean = new TestClass(); BeanUtils.populate(bean, map); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } long t2 = System.currentTimeMillis(); System.out.println("BeanUtils t2-t1 = " + String.valueOf(t2 - t1)); } private static void runJacksonMapper(Map<String, Object> map) { long t1 = System.currentTimeMillis(); for (int i = 0; i < LOOP_MAX_COUNT; i++) { ObjectMapper mapper = new ObjectMapper(); TestClass testClass = mapper.convertValue(map, TestClass.class); } long t2 = System.currentTimeMillis(); System.out.println("Jackson t2-t1 = " + String.valueOf(t2 - t1)); } @Data @AllArgsConstructor @NoArgsConstructor public static class TestClass { private Boolean success; private Integer number; private Long longer; private Double doubler; private String data1; private String data2; private String data3; private String data4; private String data5; private String data6; private String data7; private String data8; private String data9; private String data10; } }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.