जैक्सन JSON के साथ JSON स्ट्रिंग को मैप <स्ट्रिंग, स्ट्रिंग> में कैसे परिवर्तित करें


184

मैं ऐसा कुछ करने की कोशिश कर रहा हूँ, लेकिन यह काम नहीं करता है:

Map<String, String> propertyMap = new HashMap<String, String>();

propertyMap = JacksonUtils.fromJSON(properties, Map.class);

लेकिन IDE कहता है:

अनियंत्रित असाइनमेंट Map to Map<String,String>

ऐसा करने का सही तरीका क्या है? मैं केवल जैक्सन का उपयोग कर रहा हूं क्योंकि यह वही है जो परियोजना में पहले से ही उपलब्ध है, क्या JSON से / को परिवर्तित करने का एक देशी जावा तरीका है?

PHP में मैं बस json_decode($str)और मुझे एक सरणी वापस मिल जाएगी। मुझे मूल रूप से यहां वही चीज चाहिए।


क्लास जैक्सन यूटिल्स कहाँ से आ रहा है? मैं इसे किसी भी जैक्सन रिलीज़ में नहीं देखता।
रोब हेयर्स

यह जैक्सन के लिए हमारा रैपर है, कुछ JsonFactory और ObjectMapper सामान को संभालता है जो आपको करना है।
adamJLev

1
तो, समस्या यह है कि JacksonUtils.fromJSON () को मैप <स्ट्रिंग, स्ट्रिंग> को वापस करने की घोषणा नहीं की गई है, लेकिन केवल मैप।
रोब हैसर

7
Btw, नई HashMap को पहली पंक्ति में निर्दिष्ट न करें: जिसे अनदेखा किया जाता है। बस कॉल करने का आश्वासन दिया।
स्टेक्समैन

शीर्षक का आपकी वर्णित समस्या से कोई लेना-देना नहीं है, जिसका अप्रमाणित संग्रह से कोई लेना-देना नहीं है। नीचे दिया गया उत्तर सही उत्तर है जो आपने वास्तव में पूछने की कोशिश की थी।
जुक्का डाहलबॉम

जवाबों:


312

मुझे निम्नलिखित कोड मिला है:

public void testJackson() throws IOException {  
    ObjectMapper mapper = new ObjectMapper(); 
    File from = new File("albumnList.txt"); 
    TypeReference<HashMap<String,Object>> typeRef 
            = new TypeReference<HashMap<String,Object>>() {};

    HashMap<String,Object> o = mapper.readValue(from, typeRef); 
    System.out.println("Got " + o); 
}   

यह एक फ़ाइल से पढ़ रहा है, लेकिन mapper.readValue()यह भी स्वीकार करेगा InputStreamऔर आप InputStreamनिम्नलिखित का उपयोग करके एक स्ट्रिंग से प्राप्त कर सकते हैं :

new ByteArrayInputStream(astring.getBytes("UTF-8")); 

मेरे ब्लॉग पर मैपर के बारे में थोड़ा और स्पष्टीकरण है ।


2
@ सूरज, यह दस्तावेज़ीकरण के अनुसार है, और मैं मानता हूँ कि मैं पहले सिद्धांतों से सूत्रीकरण में कटौती करने में सक्षम नहीं होगा। यह इतना अजीब नहीं है जितना यह दिखाया जा सकता है कि जावा हमारे विचार से अधिक जटिल है।
djna

1
Krige: मैंने सोचा था कि कठिन बिट मैपर जा रहा था, लेकिन मैंने एक स्ट्रिंग में तकनीक को कैसे लागू किया जाए, इस पर नोट जोड़ा है
djna

2
एक मामूली टिप्पणी: बनाने की पहली पंक्ति की JsonFactoryआवश्यकता नहीं है। ObjectMapperइसे अपने आप बना सकते हैं।
स्टेक्समैन

1
@djna ने पोस्टर मांगा Map<String, String>और आपने प्रदान किया है Map<String, Object>
anon58192932

मानचित्र को एक स्ट्रिंग के रूप में लिखने के लिए आप कर सकते हैंmapper.writeValueAsString(hashmap)
ज़हीर

53

कोशिश करो TypeFactory। यहाँ जैक्सन JSON (2.8.4) के लिए कोड है।

Map<String, String> result;
ObjectMapper mapper;
TypeFactory factory;
MapType type;

factory = TypeFactory.defaultInstance();
type    = factory.constructMapType(HashMap.class, String.class, String.class);
mapper  = new ObjectMapper();
result  = mapper.readValue(data, type);

यहां जैक्सन JSON के पुराने संस्करण का कोड है।

Map<String, String> result = new ObjectMapper().readValue(
    data, TypeFactory.mapType(HashMap.class, String.class, String.class));

38
TypeFactory.mapType (...) अब पदावनत कर दिया गया है, इसे आज़माएँ: नया TypeReference <HashMap <String, String >> () {}
साइबर-भिक्षु

2
@ साइबर-भिक्षु चेतावनी से छुटकारा पा लेता है, लेकिन वास्तव में प्रकारों की जांच नहीं करता है।
डेविड मोल्स

26

आपके द्वारा प्राप्त की जाने वाली चेतावनी संकलक द्वारा की जाती है, पुस्तकालय (या उपयोगिता विधि) द्वारा नहीं।

सीधे जैक्सन का उपयोग करने का सबसे सरल तरीका होगा:

HashMap<String,Object> props;

// src is a File, InputStream, String or such
props = new ObjectMapper().readValue(src, new TypeReference<HashMap<String,Object>>() {});
// or:
props = (HashMap<String,Object>) new ObjectMapper().readValue(src, HashMap.class);
// or even just:
@SuppressWarnings("unchecked") // suppresses typed/untype mismatch warnings, which is harmless
props = new ObjectMapper().readValue(src, HashMap.class);

यूटिलिटी मेथड जिसे आप कहते हैं, शायद ऐसा ही कुछ करता है।


ओपी ने पूछा Map<String, String>और आपने प्रदान किया है Map<String, Object>
anon58192932

18
ObjectReader reader = new ObjectMapper().readerFor(Map.class);

Map<String, String> map = reader.readValue("{\"foo\":\"val\"}");

ध्यान दें कि readerउदाहरण थ्रेड सुरक्षित है।


@dpetruha ओपी ने पूछा Map<String, String>और आपने प्रदान किया है Map<String, Object>
अनोन 58192932

10

स्ट्रिंग से JSON मैप में परिवर्तित करना:

Map<String,String> map = new HashMap<String,String>();

ObjectMapper mapper = new ObjectMapper();

map = mapper.readValue(string, HashMap.class);

4
ऊपर अभी भी परिणाम है Type safety: The expression of type HashMap needs unchecked conversion to conform to Map<String,String>। हालांकि यह @SuppressWarningsएनोटेशन के साथ दबाया जा सकता है , मैं TypeReferenceपहले या कास्टिंग का उपयोग करने की सलाह दूंगा जैसा कि स्टैक्मैन ने उल्लेख किया है
कार्तिक रघुपति

1
प्रकार की सुरक्षा चेतावनी से छुटकारा पाने के लिए, आप उपयोग कर सकते हैं map = mapper.readValue(string, map.getClass());- यह देखते हुए कि आपने नक्शे को तुरंत बदल दिया है, जैसा कि यहां है।
एमजेवी

यदि var का प्रकार मैप है <Integer, String>, बस प्राप्त करें ऑब्जेक्ट क्लास सही नहीं है।
जीयू वांग

5
JavaType javaType = objectMapper.getTypeFactory().constructParameterizedType(Map.class, Key.class, Value.class);
Map<Key, Value> map=objectMapper.readValue(jsonStr, javaType);

मुझे लगता है कि इससे आपकी समस्या दूर हो जाएगी।


1
जावा में डॉक्टर: @ २.५ - लेकिन संभवत: २. or या २.c में चित्रित किया जाएगा (
२.

3

निम्नलिखित मेरे लिए काम करता है:

Map<String, String> propertyMap = getJsonAsMap(json);

ऐसा कहाँ getJsonAsMapपरिभाषित किया गया है:

public HashMap<String, String> getJsonAsMap(String json)
{
    try
    {
        ObjectMapper mapper = new ObjectMapper();
        TypeReference<Map<String,String>> typeRef = new TypeReference<Map<String,String>>() {};
        HashMap<String, String> result = mapper.readValue(json, typeRef);

        return result;
    }
    catch (Exception e)
    {
        throw new RuntimeException("Couldnt parse json:" + json, e);
    }
}

ध्यान दें कि यह विफल हो जाएगा यदि आपके पास आपके ऑब्जेक्ट में चाइल्ड ऑब्जेक्ट हैं (क्योंकि वे ए नहीं हैं String, वे एक और हैं HashMap), लेकिन काम करेंगे यदि आपका जॉन्स गुणों की एक प्रमुख मूल्य सूची है जैसे:

{
    "client_id": "my super id",
    "exp": 1481918304,
    "iat": "1450382274",
    "url": "http://www.example.com"
}

3

Google के Gson का उपयोग करना

Google के Gson का उपयोग यहां क्यों नहीं किया गया है ?

बहुत सीधे आगे और मेरे लिए काम किया:

HashMap<String,String> map = new Gson().fromJson( yourJsonString, new TypeToken<HashMap<String, String>>(){}.getType());

1
सहमत, दुनिया पर चला गया है, Gson बहुत है, का उपयोग करने के लिए बहुत आसान है।
djna

1

यहाँ इस समस्या का सामान्य समाधान है।

public static <K extends Object, V extends Object> Map<K, V> getJsonAsMap(String json, K key, V value) {
    try {
      ObjectMapper mapper = new ObjectMapper();
      TypeReference<Map<K, V>> typeRef = new TypeReference<Map<K, V>>() {
      };
      return mapper.readValue(json, typeRef);
    } catch (Exception e) {
      throw new RuntimeException("Couldnt parse json:" + json, e);
    }
  }

आशा है कि किसी दिन किसी कुंजी / मान प्रकार के मानचित्र में परिवर्तित करने के लिए एक उपयोग विधि बनाने के लिए सोचेंगे इसलिए यह उत्तर :)


-1

बस एक कोटलिन जवाब देना चाहता था

val propertyMap = objectMapper.readValue<Map<String,String>>(properties, object : TypeReference<Map<String, String>>() {})

हम्म्, यकीन नहीं हो रहा था कि यह क्यों घट गया था। न केवल यह लाइन मेरे लिए काम करती है, बल्कि इसे सही तरीके से करने की कुंजी भी देती है। एक अलग इच्छित प्रकार के साथ नक्शा <स्ट्रिंग, स्ट्रिंग> बदलकर, नक्शाकार किसी भी जटिल संग्रह में स्ट्रिंग में परिवर्तित कर देंगे, सूची <MyObject> की तरह, या सूची <नक्शा <स्ट्रिंग, MyObject >>
डस्टिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.