解析包含数组字段的JSON数组

时间:2014-02-23 11:09:27

标签: java json spring jackson

我正在尝试存储我从第三方Web服务获取的JSON。问题是我得到了一个JSON数组。这些JSON也包含数组字段。我试图用Jackson和Simple Json解析JSON,但我不能。请帮忙。我可能忽略了导致这个问题的事情。

import java.io.BufferedReader;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.web.servlet.ModelAndView;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.Produces;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import org.json.JSONArray;
import org.json.JSONObject;
@Controller
public class RecommendationController {

@RequestMapping(value = "/getResult.do", method = RequestMethod.POST)
@Produces("application/json")
@ResponseBody
public ArrayList<Map<String, Object>> getResults(@RequestBody SearchQuery searchQuery) throws Exception{
    ArrayList<Map<String, Object>> response = sendPost(searchQuery);
    String email=null;
    ArrayList<Map<String, Object>> finalResult = new ArrayList<Map<String, Object>>();
    for (Map<String, Object> map : response) {
        Map<String, Object> temp = new HashMap<String, Object>();
        if(map.containsKey("TutorID"))
            temp.put("TutorID", map.get("TutorID"));
        if(map.containsKey("Name"))
            temp.put("Name", map.get("Name"));
        if(map.containsKey("City"))
            temp.put("City", map.get("City"));
        if(map.containsKey("State"))
            temp.put("State", map.get("State"));
        if(map.containsKey("TutorPictures"))
            temp.put("TutorPictures", map.get("TutorPictures[0]"));
        if(map.containsKey("FeePerHour"))
            temp.put("FeePerHour", map.get("FeePerHour"));
        if(map.containsKey("StarRatingAverage"))
            temp.put("StarRatingAverage", map.get("StarRatingAverage"));
        if(map.containsKey("TutorID") & map.containsKey("State") & map.containsKey("City"))
            email = "http://localhost:8080/TestPrecision/contactTutor.do"+"?State="+map.get("State")+"&City="+((String) map.get("City")).replaceAll(" ", "-")+"&TutorID="+map.get("TutorID");
        temp.put("Email", email);
        finalResult.add(temp);
    }
    return finalResult;
}

private ArrayList<Map<String,Object>> sendPost(SearchQuery searchQuery) throws Exception {

    ArrayList<Map<String,Object>> responseDataMap = null;
    String url = "http://data.wyzant.com/api/search";
    URL obj = new URL(url);
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();

    //add reuqest header
    con.setRequestMethod("POST");
    con.setRequestProperty("Accept", "application/json");
    String searchUrl = "";
    searchUrl = "&SearchString="+searchQuery.getMessageString()+"&Zip="+searchQuery.getMessageZip()+"&MaxResults="+searchQuery.getMessageMaxResult();
    String urlParameters = "Your_Partner_Key&"+searchUrl;

    // Send post request
    con.setDoOutput(true);
    DataOutputStream wr = new DataOutputStream(con.getOutputStream());
    wr.writeBytes(urlParameters);
    wr.flush();
    wr.close();

    int responseCode = con.getResponseCode();
    System.out.println("\nSending 'POST' request to URL : " + url);
    System.out.println("Post parameters : " + urlParameters);
    System.out.println("Response Code : " + responseCode);

    BufferedReader in = new BufferedReader(
            new InputStreamReader(con.getInputStream()));
    /*StringBuilder responseStrBuilder = new StringBuilder();

    String inputStr;
    while ((inputStr = in.readLine()) != null)
        responseStrBuilder.append(inputStr);
    System.out.println(new JSONObject(responseStrBuilder.toString()));
    */ObjectMapper objectmapper = new ObjectMapper();
    responseDataMap = objectmapper.readValue(in, new TypeReference<ArrayList<Map<String , Object>>>(){

    });
    System.out.println("JSON Map -----> /n"+responseDataMap);
    in.close(); 
    return responseDataMap;

}
}

以下是我从第三方Web服务

获得的JSON
[
   {
      "TutorID":8304029,
      "Name":"Matthew B.",
      "City":"Fremont",
      "State":"CA",
      "Zip":"94538",
      "Title":null,
      "FeePerHour":60,
      "FreeResponse":"...",
      "TravelDistance":15,
      "TutorPictures":[
         "http://dj1hlxw0wr920.cloudfront.net/userfiles/wyzfiles/be0c64e4-be09-4b38-bbd8-            72f3843cadde.jpg"
      ],
      "ProfileLink":"http://www.wyzant.com/Tutors/CA/Fremont/8304029/?    utm_source=partners\u0026utm_medium=api\u0026utm_term=1229\u0026utm_campaign=407\u0026g=3SEQ",
      "EmailLink":"http://www.wyzant.com/Tutors/CA/Fremont/8304029/Contact.aspx?utm_source=partners\u0026utm_medium=api\u0026utm_term=1229\u0026utm_campaign=407\u0026g=3SEQ",
      "Subjects":[
         {
            "Name":"American history",
            "Description":null
         },
         {
            "Name":"vocabulary",
            "Description":null
         },
         {
            "Name":"reading",
            "Description":null
         },
         {
            "Name":"writing",
            "Description":null
         },
         {
            "Name":"English",
            "Description":null
         }
      ],
      "Reviews":null,
      "StarRatingAverage":null,
      "StarRatingCount":null,
      "TutorRank":0.55803185701370239,
      "College":null
   },
   {
      "TutorID":8347645,
      "Name":"Taner O.",
      "City":"Fremont",
      "State":"CA",
      "Zip":"94538",
      "Title":null,
      "FeePerHour":65,
      "FreeResponse":"...",
      "TravelDistance":5,
      "TutorPictures":[

      ],
      "ProfileLink":"http://www.wyzant.com/Tutors/CA/Fremont/8347645/?utm_source=partners\u0026utm_medium=api\u0026utm_term=1229\u0026utm_campaign=407\u0026g=3SEQ",
      "EmailLink":"http://www.wyzant.com/Tutors/CA/Fremont/8347645/Contact.aspx?utm_source=partners\u0026utm_medium=api\u0026utm_term=1229\u0026utm_campaign=407\u0026g=3SEQ",
      "Subjects":[
         {
            "Name":"calculus",
            "Description":null
         },
         {
            "Name":"chemistry",
            "Description":null
         },
         {
            "Name":"geometry",
            "Description":null
         },
         {
            "Name":"physics",
            "Description":null
         },
         {
            "Name":"SAT math",
            "Description":null
         }
      ],
      "Reviews":null,
      "StarRatingAverage":null,
      "StarRatingCount":null,
      "TutorRank":-0.39533111453056335,
      "College":null
   }

我打算从这个JSON获得Tutor Image,Tutor Name,Subjects,FeeperHour,StarRating。我已经成功获得了Tutor Name,FeesperHour和StarRatings,虽然无法检索Tutor Image和Subjects,因为它们进入阵列并且我无法解析它。请帮忙。下面是我设法获得的JSON。

[
  {
    "Name":"Courtney D.",
    "FeePerHour":60,
     "State":"NY",
    "TutorPictures":null,
    "StarRatingAverage":null,
    "TutorID":7874994,
    "City":"Milford"
  }
]

2 个答案:

答案 0 :(得分:2)

如果您不想使用类并反序列化到类,请不要尝试反序列化为Java类型,而是反序列化为JsonNode

final JsonNode data = mapper.readTree(yourURLObject);

请参阅JsonNode的javadoc。您可以使用它轻松导航JSON。

例如,以下是如何从每个数组元素中打印出TutorID对象成员:

// This cycles through a JSON array's elements or a JSON Object's member values;
// empty iterator for all other JSON value types
for (final JsonNode element: data)
    System.out.println(data.path("TutorID"));

答案 1 :(得分:1)

伪代码:

Class Tutor {
    String tutorName;
    String[] tutorPictures;
    Subject[] subjects;
    Number feePerHour;
    Number starRating;  // Not clear if this is number or string
}

Class Subject {
    String name;
    String description;
}


List mainList = parseJson(jsonBytes);
Tutor[] tutors = new Tutor[mainList.count()];
int tutorCount = 0;
for each Map tutorMap in tutors {
    Tutor tutor = new tutor();
    List tutorPicturesList = tutorMap.get("TutorPictures");
    tutor.tutorPictures = tutorPicturesList.toStringArray();  // Or copy logic for subjects below
    tutor.tutorName = tutorMap.get("Name");
    List subjectsList = tutorMap.get("Subjects");
    tutor.subjects = new Subjects[subjectsList.count()];
    int subjectCount = 0;
    for each Map subjectMap in mainList {
        Subject subject = new Subject();
        subject.name = subjectMap.get("Name");
        subject.description = subjectMap.get("Description");
        tutor.subjects[subjectCount] = subject;
        subjectCount++;
    }
    tutor.feePerHour = tutorMap["FeePerHour"];
    tutor.starRating = tutorMap["StarRating"];
    tutors[tutorCount] = tutor;
    tutorCount++;
}

根据所使用的工具集,必须将强制转换插入适当的类型或使用特定于类型的方法来提取Map元素。

对于任何可以为空的数字字段,必须将这些值作为对象进行检索,并且(如果需要)仅在非空时提取数值。