处理来自 JsonReader 的空指针

Posted

技术标签:

【中文标题】处理来自 JsonReader 的空指针【英文标题】:Handling Null Pointers from JsonReader 【发布时间】:2015-07-22 14:31:41 【问题描述】:

我正在使用 JsonReader 从网站获取大量数据并保存到数据库。顺便说一句,只要阅读器没有找到对象项的值,它就会失败并停止执行。

这是我的错误;

System.err﹕ java.lang.IllegalStateException: Expected a string but was NULL at line 1 column 359337 path $[19].date

即使指定的值不可用,似乎在遇到错误之前加载的所有对象也都丢失了,并且没有保存到数据库中。有没有办法处理这些错误并保留到目前为止已加载的对象?我已将 JsonReader 设置为宽松。

这是解析数据的方法部分:

private Post read(JsonReader reader) throws Exception 
            reader.beginObject();

            while (reader.hasNext()) 
                String name = reader.nextName();

                switch (name) 
                    case TITLE:
                        mTitle = new StringBuilder();
                        mTitle.append(reader.nextString());
                        break;
                    case AUTHOR:
                        if (reader.hasNext()) 
                            JsonToken peek = reader.peek();

                            if (peek == JsonToken.NULL) 
                                reader.skipValue();
                             else 
                                reader.beginObject();

                                while (reader.hasNext()) 
                                    String enclosedName = reader.nextName();

                                    switch (enclosedName) 
                                        case NAME:
                                            mAuthor = new StringBuilder();
                                            mAuthor.append(reader.nextString());
                                            break;
                                        case AVATAR:
                                            mAvatar = new StringBuilder();
                                            mAvatar.append(reader.nextString());
                                            break;
                                        default:
                                            reader.skipValue();
                                            break;
                                    
                                

                                reader.endObject();
                            
                        
                        break;
                    case CONTENT:
                        mDescription = new StringBuilder();
                        mDescription.append(reader.nextString());
                        break;
                    case URL:
                        mEntryLink = new StringBuilder();
                        mEntryLink.append(reader.nextString());
                        break;
                    case DATE:
                        mDateStringBuilder = new StringBuilder();
                        mDateStringBuilder.append(reader.nextString());
                        break;
                    case GUID:
                        mGuid = new StringBuilder();
                        mGuid.append(reader.nextString());
                        break;
                    case FEATURED_IMAGE:
                        if (reader.hasNext()) 
                            JsonToken look = reader.peek();

                            if (look == JsonToken.NULL) 
                                reader.skipValue();
                             else 
                                mFeaturedImage = new StringBuilder();
                                reader.beginObject();

                                while (reader.hasNext()) 
                                    String itemToLookFor = reader.nextName();

                                    switch (itemToLookFor) 
                                        case SOURCE:
                                            mFeaturedImage.append(reader.nextString());
                                            break;
                                        default:
                                            reader.skipValue();
                                            break;
                                    
                                

                                reader.endObject();
                            
                        
                        break;
                    case TERMS:
                        if (reader.hasNext()) 
                            JsonToken check = reader.peek();

                            if (check == JsonToken.NULL) 
                                reader.skipValue();
                             else 
                                reader.beginObject();

                                while (reader.hasNext()) 
                                    String stuff = reader.nextName();

                                    switch (stuff) 
                                        case CATEGORIES:
                                            reader.beginArray();

                                            itemCategory = new StringBuilder();

                                            while (reader.hasNext()) 
                                                reader.beginObject();

                                                while (reader.hasNext()) 
                                                    String item = reader.nextName();

                                                    switch (item) 
                                                        case NAME:
                                                            itemCategory.append(reader.nextString()).append(",");
                                                            break;
                                                        default:
                                                            reader.skipValue();
                                                            break;
                                                    
                                                

                                                reader.endObject();
                                            
                                            reader.endArray();
                                            break;
                                        case TAGS:
                                            reader.beginArray();

                                            itemTags = new StringBuilder();

                                            while (reader.hasNext()) 
                                                reader.beginObject();

                                                while (reader.hasNext()) 
                                                    String item = reader.nextName();

                                                    switch (item) 
                                                        case NAME:
                                                            itemTags.append(reader.nextString()).append(",");
                                                            break;
                                                        default:
                                                            reader.skipValue();
                                                            break;
                                                    
                                                

                                                reader.endObject();
                                            
                                            reader.endArray();
                                            break;
                                        default:
                                            reader.skipValue();
                                            break;
                                    
                                

                                reader.endObject();
                            
                        
                        break;
                    default:
                        reader.skipValue();
                        break;
                
            

            reader.endObject();

            return new Post(mAuthor.toString(), mAvatar.toString(), mDateStringBuilder.toString(), mTitle.toString(), mEntryLink.toString(), mDescription.toString(), mGuid.toString(), mFeaturedImage.toString(), itemTags.toString(), itemCategory.toString());
        

【问题讨论】:

请提供您正在使用的代码 @Knossos 检查更新的问题 【参考方案1】:

我想你可能没有检查NULL 元素,似乎是这样。

在某一时刻你使用:

JsonToken check = reader.peek();

if (check == JsonToken.NULL) 

没错。然而,在其他地方你只需得到String

mDescription.append(reader.nextString());

在您获得String 的所有地方,您需要检查是否确实存在意外类型(例如NULL)。在这种情况下,您需要应用适当的错误包含代码。

顺便说一句,您真的不需要创建所有这些StringBuilders。由于您在每次初始化后只将一个 String 放入其中。只需使用 String 即可节省大量时间。如果您打算将每种类型的所有内容写入StringBuilder,那么您需要在开始循环之前对其进行初始化。

【讨论】:

以上是关于处理来自 JsonReader 的空指针的主要内容,如果未能解决你的问题,请参考以下文章

java中的空指针异常怎么解决

java NIO SSO 处理器中的空指针

异步任务的空指针异常

Kotlinkotlin中的空指针检查

OpenCV 和 ROS:cvMAT 中的空指针错误

Kotlin小笔记kotlin中的空指针检查