使用jackson解析json时遇到问题

时间:2015-06-25 06:08:42

标签: json spring-boot

我正在使用jackson解析数据,我正在使用以下代码来解析json

public Map<String, Object> savePreference(@RequestBody Map map) throws IOException{
        List preferenceDetails = (List) map.get("data");
        int preferenceIndex = 0;
        while(preferenceIndex < preferenceDetails.size()){
            final ObjectMapper mapper = new ObjectMapper();
            System.out.println(preferenceDetails.get(preferenceIndex));

            mapper.readValue(preferenceDetails.get(preferenceIndex).toString(), Preference.class);
            preferenceIndex++;
        }
        return null;
    }

我正在从客户端发送json,就像这样

{"data":[
      {
         "preferenceType":"Travelling"
      },
      {
         "preferenceType":"Shopping"
      }
   ]
}

但是当我调用

时,上面的代码会引发异常

mapper.readValue(preferenceDetails.get(preferenceIndex).toString(), Preference.class);

例外是

com.fasterxml.jackson.core.JsonParseException: Unexpected character ('p' (code 112)): was expecting double-quote to start field name

我在while循环中打印首选项详细信息

{preferenceType=Travelling}

2 个答案:

答案 0 :(得分:0)

您不需要逐行解析。直接使用对象会更容易。这是一个测试用例,演示如何直接将json解析为对象。

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Assert;
import org.junit.Test;

import java.util.Collection;

public class JacksonTest {

    @Test
    public void testName() throws Exception {
        final String test = "{\"data\":[\n" +
                "      {\n" +
                "         \"preferenceType\":\"Travelling\"\n" +
                "      },\n" +
                "      {\n" +
                "         \"preferenceType\":\"Shopping\"\n" +
                "      }\n" +
                "   ]\n" +
                "}";

        final ObjectMapper objectMapper = new ObjectMapper();
        final Data data = objectMapper.readValue(test, Data.class);
        Assert.assertNotNull(data);
        Assert.assertEquals(2, data.getData().size());

    }

    static class Data {
        private Collection<PreferenceType> data;

        public Collection<PreferenceType> getData() {
            return data;
        }

        public void setData(Collection<PreferenceType> data) {
            this.data = data;
        }
    }

    static class PreferenceType {
        private String preferenceType;

        public String getPreferenceType() {
            return preferenceType;
        }

        public void setPreferenceType(String preferenceType) {
            this.preferenceType = preferenceType;
        }
    }
}

之后,您可以随心所欲地构建自己的地图。但是您的框架可能能够处理这种请求。您无需手动解析它。您应该尝试直接获取Data对象,而不是将您的身体设为Map

更新

尝试这样的事情。但首先要正确定义Data类(至少不要作为内部类)。

public Map<String, Object> savePreference(@RequestBody Data data) throws IOException{
...
    }

更新2

此外,您的地图已经有了您的对象PreferenceDetail。它可能已经处理了json并将其映射为对象。请调试并检查map.get("data")是否返回List<PreferenceDetail>。如果它返回List,则不再需要使用jackson解析json。你可以简单地做这样的事情。

public Map<String, Object> savePreference(@RequestBody Map map) throws IOException{
        List<PreferenceDetail> preferenceDetails = (List) map.get("data");
        for (PreferenceDetail preferenceDetail : preferenceDetails) {
            System.out.println(preferenceDetail.getPreferenceType());
        }
        return null;
    }

答案 1 :(得分:0)

I solved my problem by using jackson object mapper.

 public Map<String, Object> savePreference(@RequestBody Map map) throws IOException{
            log.debug("saving preferences");
            if(preferenceService.getPreferencesByUser() != null && preferenceService.getPreferencesByUser().size() != 0)
                return ResponseHandler.generateResponse(configProp.getProperty("user.preference.exist"), HttpStatus.ACCEPTED, true, null);
            final ObjectMapper mapper = new ObjectMapper();
            List preferenceDetails = (List) map.get("data");
            int preferenceIndex = 0;
            while(preferenceIndex < preferenceDetails.size()){
                preferenceService.savePreference(mapper.readValue(mapper.writeValueAsString(preferenceDetails.get(preferenceIndex)), Preference.class));
                preferenceIndex++;
            }
            return ResponseHandler.generateResponse(configProp.getProperty("preference.added"), HttpStatus.ACCEPTED, true, null);
        }