如何使用Jackson ObjectMapper序列化替换JSON响应中的空字段(嵌套在所有级别)?

如何使用Jackson ObjectMapper序列化替换JSON响应中的空字段(嵌套在所有级别)?,json,serialization,jackson,twitter4j,pojo,Json,Serialization,Jackson,Twitter4j,Pojo,我使用下面的代码以JSON响应的形式从Twitter4j搜索API接收推文。我收到了Twitter4j搜索API中指定的列表形式的结果 List<Status> tweets = result.getTweets(); 但是,当我试图从Status获取geoLocation字段时,使用下面标有** List<Status> tweets = result.getTweets(); 输出应该是 我想要的是替换JSONArray中的所有空元素和JSONObject中的所有

我使用下面的代码以JSON响应的形式从Twitter4j搜索API接收推文。我收到了Twitter4j搜索API中指定的列表形式的结果

List<Status> tweets = result.getTweets();
但是,当我试图从Status获取geoLocation字段时,使用下面标有**

List<Status> tweets = result.getTweets();
输出应该是 我想要的是替换JSONArray中的所有空元素和JSONObject中的所有空键值对,无论它们嵌套在我的JSON响应中的级别如何。 对象与树模型方法 我尝试了对象模型解析机制,这是一种基于javax.json.stream.JsonParser.Event的方法,但需要多次访问json字符串并替换对象,这取决于null嵌套的级别,这使得这种方法非常复杂。同时,如果我使用树模型机制,整个JSON响应必须存储为一棵树,这可能会溢出JVM堆内存,因为根据我的查询参数,JSON大小可能相当大。我需要找到一个可行的解决办法来克服这个问题。如有任何关于解决上述问题的建议,我们将不胜感激

代码如下:

[Mon Apr 20 11:32:47 IST 2015]{"statuses":[{"retweeted_status":{"contributors":null,"text":"<my text>",**"geo":null**,"retweeted":false,"in_reply_to_screen_name":null,"truncated":false,"lang":"en","entities":{"symbols":[],"urls":[],"hashtags": ... &include_entities=1","since_id_str":"0","completed_in":0.029}}

    **Exception in thread "main" java.lang.NullPointerException
        at analytics.search.twitter.SearchFieldsTweetsJSON_2.main(SearchFieldsTweetsJSON_2.java:78)**
public class SearchFieldsTweetsJSON_2 {
    /* Searches specific fields from Tweets in JSON format */

    public static void main(String[] args) throws FileNotFoundException, IOException {
        if (args.length < 2) {
            System.out.println("java twitter4j.examples.search.SearchTweets [query][outputJSONFile]");
            System.exit(-1);
        }
        ConfigurationBuilder cb = new ConfigurationBuilder();
        cb.setDebugEnabled(true)
        .setOAuthConsumerKey("XXXXXXXXXXXXXXXXXXXXXXXXXX")
        .setOAuthConsumerSecret("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
        .setOAuthAccessToken("NNNNNNNNN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
        .setOAuthAccessTokenSecret("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
        .setJSONStoreEnabled(true);
        Twitter twitter = new TwitterFactory(cb.build()).getInstance(); 
        try {
            Query query = new Query(args[0]);
            QueryResult result;
            File jsonFile = new File(args[1]);
            System.out.println("File Path : " + jsonFile.getAbsolutePath());
            OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(jsonFile));

            JsonGenerator generator = new JsonFactory().createGenerator(os);
            generator.setPrettyPrinter(new DefaultPrettyPrinter());
            TweetJSON_2 rawJSON; 

            ObjectMapper mapper = new ObjectMapper();
            //mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
            mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
            mapper.setSerializationInclusion(Include.NON_NULL);

            do {
                result = twitter.search(query);
                List<Status> tweets = result.getTweets();
                for (Status tweet : tweets) {
                    rawJSON = new TweetJSON_2();
                    rawJSON.setStatusId(Long.toString(tweet.getId()));
                    rawJSON.setUserId(Long.toString(tweet.getUser().getId()));
                    rawJSON.setUserName(tweet.getUser().getScreenName());
                    rawJSON.setStatusText(tweet.getText());
                    rawJSON.setGeoLocation(tweet.getGeoLocation().toString()); **<< Giving error at tweet.getGeoLocation() since GeoLocation is null**
                    mapper.writeValue(generator, rawJSON);
                    System.out.println(rawJSON.toString());
                }
            } while ((query = result.nextQuery()) != null); 
            generator.close();
            System.out.println(os.toString());
        } catch (TwitterException te) {
            te.printStackTrace();
            System.out.println("Failed to search tweets : " + te.getMessage());
            System.exit(-1);
        } 
    }

}
public class TweetJSON_2 {

    public  String statusId;
    public  String statusText;
    public  String userId;
    public  String userName;
    public  String geoLocation;

    public String getStatusId() {
        return statusId;
    }
    public void setStatusId(String statusId) {
        this.statusId = statusId;
    }
    public String getStatusText() {
        return statusText;
    }
    public void setStatusText(String statusText) {
        this.statusText = statusText;
    }
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getGeoLocation() {
        return geoLocation;
    }
    public void setGeoLocation(String geoLocation) {
        this.geoLocation = geoLocation;
    }
    @Override
    public String toString() {
        return "TweetJSON_2 [ statusId = " + statusId + ", statusText = " + statusText + "]";
    }
}

我尝试过用下面的方法重新配置POJO,它成功地替换了setter方法中指定的所有空值。不需要遵循JSON字符串的树或基于事件的模型解析。嗯

修改后的TweetJSON_2 POJO:

public class TweetJSON_2 {
    public  Long statusId = null;
    public  String statusText = null;
    public  Long userId = null;
    public  String userName = null;
    public  GeoLocation geoLocation = null;

    public Long getStatusId() {
        if (this.statusId==null)
            return new Long(0L);
        return statusId;
    }
    public void setStatusId(Long statusId) {
        if (statusId==null)
            this.statusId = new Long(0L);
        else
            this.statusId = statusId;
    }
    public String getStatusText() {
        if (this.statusText==null)
            return new String("");
        return statusText;
    }
    public void setStatusText(String statusText) {
        if (statusText==null)
            this.statusText = new String("");
        else
            this.statusText = statusText;
    }
    public Long getUserId() {
        if (this.userId==null)
            return new Long(0L);
        return userId;
    }
    public void setUserId(Long userId) {
        if (userId==null)
            this.userId = new Long(0L);
        else
            this.userId = userId;
    }
    public String getUserName() {
        if (this.userName==null)
            return new String("");
        return userName;
    }
    public void setUserName(String userName) {
        if (userName==null)
            this.userName = new String("");
        else
            this.userName = userName;
    }
    public GeoLocation getGeoLocation() {
        if (this.geoLocation==null)
            return new GeoLocation(0.0,0.0);
        return geoLocation;
    }
    public void setGeoLocation(GeoLocation geoLocation) {
        if (geoLocation==null)
            this.geoLocation = new GeoLocation(0.0,0.0);
        else
            this.geoLocation = geoLocation;
    }
    @Override
    public String toString() {
        return "TweetJSON_2 [ statusId = " + statusId + ", statusText = " + statusText + "]";
    }
}
public class SearchFieldsTweetsJSON_2 {
    /* Searches specific fields from Tweets in JSON format */

    public static void main(String[] args) throws FileNotFoundException, IOException {
        if (args.length < 2) {
            System.out.println("java twitter4j.examples.search.SearchTweets [query][outputJSONFile]");
            System.exit(-1);
        }
        ConfigurationBuilder cb = new ConfigurationBuilder();
        cb.setDebugEnabled(true)
        .setOAuthConsumerKey("XXXXXXXXXXXXXXXXXXXXXXXXXX")
        .setOAuthConsumerSecret("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
        .setOAuthAccessToken("NNNNNNNNN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
        .setOAuthAccessTokenSecret("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
        .setJSONStoreEnabled(true);
        Twitter twitter = new TwitterFactory(cb.build()).getInstance(); 
        try {
            Query query = new Query(args[0]);
            QueryResult result;
            File jsonFile = new File(args[1]);
            System.out.println("File Path : " + jsonFile.getAbsolutePath());
            OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(jsonFile));

            JsonGenerator generator = new JsonFactory().createGenerator(os);
            generator.setPrettyPrinter(new DefaultPrettyPrinter());
            TweetJSON_2 rawJSON; 

            ObjectMapper mapper = new ObjectMapper();
            //mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
            mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
            mapper.setSerializationInclusion(Include.NON_NULL);

            do {
                result = twitter.search(query);
                List<Status> tweets = result.getTweets();
                for (Status tweet : tweets) {
                    rawJSON = new TweetJSON_2();
                    rawJSON.setStatusId(Long.toString(tweet.getId()));
                    rawJSON.setUserId(Long.toString(tweet.getUser().getId()));
                    rawJSON.setUserName(tweet.getUser().getScreenName());
                    rawJSON.setStatusText(tweet.getText());
                    rawJSON.setGeoLocation(tweet.getGeoLocation().toString()); **<< Giving error at tweet.getGeoLocation() since GeoLocation is null**
                    mapper.writeValue(generator, rawJSON);
                    System.out.println(rawJSON.toString());
                }
            } while ((query = result.nextQuery()) != null); 
            generator.close();
            System.out.println(os.toString());
        } catch (TwitterException te) {
            te.printStackTrace();
            System.out.println("Failed to search tweets : " + te.getMessage());
            System.exit(-1);
        } 
    }

}
public class TweetJSON_2 {

    public  String statusId;
    public  String statusText;
    public  String userId;
    public  String userName;
    public  String geoLocation;

    public String getStatusId() {
        return statusId;
    }
    public void setStatusId(String statusId) {
        this.statusId = statusId;
    }
    public String getStatusText() {
        return statusText;
    }
    public void setStatusText(String statusText) {
        this.statusText = statusText;
    }
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getGeoLocation() {
        return geoLocation;
    }
    public void setGeoLocation(String geoLocation) {
        this.geoLocation = geoLocation;
    }
    @Override
    public String toString() {
        return "TweetJSON_2 [ statusId = " + statusId + ", statusText = " + statusText + "]";
    }
}
public class TweetJSON_2 {
    public  Long statusId = null;
    public  String statusText = null;
    public  Long userId = null;
    public  String userName = null;
    public  GeoLocation geoLocation = null;

    public Long getStatusId() {
        if (this.statusId==null)
            return new Long(0L);
        return statusId;
    }
    public void setStatusId(Long statusId) {
        if (statusId==null)
            this.statusId = new Long(0L);
        else
            this.statusId = statusId;
    }
    public String getStatusText() {
        if (this.statusText==null)
            return new String("");
        return statusText;
    }
    public void setStatusText(String statusText) {
        if (statusText==null)
            this.statusText = new String("");
        else
            this.statusText = statusText;
    }
    public Long getUserId() {
        if (this.userId==null)
            return new Long(0L);
        return userId;
    }
    public void setUserId(Long userId) {
        if (userId==null)
            this.userId = new Long(0L);
        else
            this.userId = userId;
    }
    public String getUserName() {
        if (this.userName==null)
            return new String("");
        return userName;
    }
    public void setUserName(String userName) {
        if (userName==null)
            this.userName = new String("");
        else
            this.userName = userName;
    }
    public GeoLocation getGeoLocation() {
        if (this.geoLocation==null)
            return new GeoLocation(0.0,0.0);
        return geoLocation;
    }
    public void setGeoLocation(GeoLocation geoLocation) {
        if (geoLocation==null)
            this.geoLocation = new GeoLocation(0.0,0.0);
        else
            this.geoLocation = geoLocation;
    }
    @Override
    public String toString() {
        return "TweetJSON_2 [ statusId = " + statusId + ", statusText = " + statusText + "]";
    }
}