Jackson JSON을 사용하여 JSON 문자열을 Map <String, String>으로 변환하는 방법


184

나는 이런 식으로하려고하지만 작동하지 않습니다 :

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

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

그러나 IDE는 말합니다 :

확인되지 않은 과제 Map to Map<String,String>

이것을하는 올바른 방법은 무엇입니까? 잭슨 만 사용하고 있습니다. 프로젝트에서 이미 사용 가능한 것이므로 JSON으로 /에서 변환하는 기본 Java 방법이 있습니까?

PHP에서는 간단하게 json_decode($str)배열을 얻습니다. 나는 기본적으로 같은 것이 필요합니다.


JacksonUtils 클래스는 어디에서 왔습니까? 나는 Jackson의 어떤 릴리스에서도 그것을 보지 못했다.
Rob Heiser

Jackson의 래퍼이며 JsonFactory 및 ObjectMapper 작업을 처리합니다.
adamJLev

1
따라서 문제는 JacksonUtils.fromJSON ()이 Map <String, String>을 반환하도록 선언되지 않고 Map 만 반환한다는 것입니다.
Rob Heiser

7
Btw, 첫 번째 줄에 새 HashMap을 할당하지 마십시오. 무시됩니다. 전화 만하면됩니다.
StaxMan

제목은 설명되지 않은 컬렉션과 관련이있는 설명 된 문제와 관련이 없습니다. 아래 답변은 귀하가 실제로 요청한 것에 대한 정답입니다.
Jukka Dahlbom

답변:


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); 
}   

파일에서 읽는 중이지만 a mapper.readValue()도 허용하며 다음을 사용하여 문자열 InputStream에서을 얻을 수 있습니다 InputStream.

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

내 블로그 의 매퍼에 대한 설명이 조금 더 있습니다.


2
@Suraj, 그것은 문서에 따르면, 나는 첫 번째 원칙에서 공식을 추론 할 수 없었을 것에 동의합니다. Java가 생각보다 복잡하다는 것을 보여주는 것은 그리 이상하지 않습니다.
djna

1
Krige : 하드 비트가 맵퍼를 사용하고 있다고 생각했지만이 기법을 문자열에 적용하는 방법에 대한 메모를 추가했습니다.
djna

2
하나의 사소한 의견 : 첫 줄을 만들 JsonFactory필요는 없습니다. ObjectMapper자체적으로 자동 생성 할 수 있습니다.
StaxMan

1
포스터에 @djna가 요청했으며 Map<String, String>제공했습니다 Map<String, Object>.
anon58192932

지도를 문자열로 쓰려면mapper.writeValueAsString(hashmap)
Zaheer

53

시도하십시오 TypeFactory. 다음은 Jackson 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);

다음은 Jackson JSON의 이전 버전에 대한 코드입니다.

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

38
TypeFactory.mapType (...)은 더 이상 사용되지 않습니다. 다음을 시도해보십시오. new TypeReference <HashMap <String, String >> () {}
cyber-monk

2
@ cyber-monk 경고를 없애지 만 실제로 유형을 확인하지는 않습니다.
David Moles

26

경고는 라이브러리 (또는 유틸리티 메소드)가 아닌 컴파일러에 의해 수행됩니다.

Jackson을 직접 사용하는 가장 간단한 방법은 다음과 같습니다.

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);

당신이 호출하는 유틸리티 메소드는 아마도 이것과 비슷한 것을 할 것입니다.


OP가 요청 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 OP가 요청했으며을 (를) Map<String, String>제공했습니다 Map<String, Object>.
anon58192932

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주석, 내가 사용하는 것이 좋습니다 것 TypeReferenceStaxman에서 언급 한 바와 같이 첫 번째 또는 다음 주조
Karthic Raghupathi

1
유형 안전 경고를 없애려면 map = mapper.readValue(string, map.getClass());여기에서와 같이 맵을 인스턴스화 한 경우 사용할 수 있습니다.
MJV

var의 유형이 Map <Integer, String>이면 객체 클래스가 올바르지 않습니다.
Jiayu Wang

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

나는 이것이 당신의 문제를 해결할 것이라고 생각합니다.


1
자바 문서에서 : @since 2.5 -하지만 아마도 2.7 또는 2.8 (2.7 필요하지)에서 사용되지 않는 것
알 - Mothafar

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);
    }
}

이 점에 유의 한다 당신이 당신의 JSON에서 하위 개체가있는 경우 실패 (그들이하지이기 때문에 String, 그들은 또 다른이야 HashMap)하지만 JSON 지금과 같은 속성의 키 값 목록이있는 경우 작동합니다 :

{
    "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);
    }
  }

누군가 언젠가 누군가가 Key / Value 유형의 Map으로 변환하는 util 메소드를 만들 것이라고 생각하기를 바랍니다.


-1

Kotlin에게 답변을주고 싶었습니다.

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

흠, 왜 이것이 다운 보트인지 확실하지 않습니다. 이 라인은 저에게 효과적 일뿐만 아니라 올바른 방식으로 수행 할 수있는 열쇠를 제공합니다. Map <String, String>을 원하는 다른 유형으로 바꾸면 매퍼는 문자열을 List <MyObject> 또는 List <Map <String, MyObject >>와 같은 복잡한 컬렉션으로 변환합니다.
Dustin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.