belogic里调用sql出现nullpointerexce

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了belogic里调用sql出现nullpointerexce相关的知识,希望对你有一定的参考价值。

参考技术A 使用了未初始化的变量,使用了未初始化的对象。
1、使用了未初始化的变量会导致belogic里调用sql出现nullpointerexce。
2、使用了未初始化的对象会导致belogic里调用sql出现nullpointerexce。

Jackson & JSONAnySetter:序列化/反序列化期间出现 NullPointer 异常

【中文标题】Jackson & JSONAnySetter:序列化/反序列化期间出现 NullPointer 异常【英文标题】:Jackson & JSONAnySetter: NullPointer Exception during Serialization/Deserialization 【发布时间】:2017-06-12 22:19:03 【问题描述】:

我在使用 Jackson 1.9.13(和 Jackson 2.5.0)进行序列化/反序列化时遇到问题,并且现在已经解决了几天但没有任何成功。

我的目标是使用@JsonAnyGetter 和@JsonAnySetter,我想动态计算一个对象是否应该写入输出。我有一个 JSON 定义,我用 ObjectMapper 序列化(并检查是否应该包含该对象),然后将对象转换回字符串。

我为此使用了“HidableSerializer”,它在序列化期间工作正常,但在将对象转换回字符串时却不行。

没有@JsonAnySetter / -getter “HidableSerializer”,一切正常,但不能同时使用。

为什么这不起作用?我该如何解决这个问题?欢迎使用更好的方法!

堆栈跟踪如下所示:

堆栈跟踪

org.codehaus.jackson.map.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: ch.hasselba.Test["[anySetter]"])
null
    at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:218)
    at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:183)
    at org.codehaus.jackson.map.ser.std.SerializerBase.wrapAndThrow(SerializerBase.java:140)
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:158)
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)
at ch.hasselba.HidableSerializer.serialize(HidableSerializer.java:29)
    at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610)
    at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256)
    at org.codehaus.jackson.map.ObjectMapper._configAndWriteValue(ObjectMapper.java:2575)
    at org.codehaus.jackson.map.ObjectMapper.writeValueAsString(ObjectMapper.java:2097)
    at ch.hasselba.Demo.main(Demo.java:54)
Caused by: java.lang.NullPointerException
    at org.codehaus.jackson.map.ser.std.MapSerializer.serializeFields(MapSerializer.java:243)
    at org.codehaus.jackson.map.ser.AnyGetterWriter.getAndSerialize(AnyGetterWriter.java:41)
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:154)
    ... 7 more

演示代码

package ch.hasselba;

import org.codehaus.jackson.Version;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.introspect.BasicBeanDescription;
import org.codehaus.jackson.map.module.SimpleModule;
import org.codehaus.jackson.map.ser.BeanSerializerModifier;

public class Demo 

    public static void main(String[] args) 

        ObjectMapper mapper = new ObjectMapper();

        // register the module
        Version version = new Version(1, 0, 0, "SNAPSHOT");
        mapper.registerModule(new SimpleModule("HidableModule", version) 
            @Override
            public void setupModule(SetupContext context) 
                super.setupModule(context);
                context.addBeanSerializerModifier(new BeanSerializerModifier() 
                    @SuppressWarnings("unchecked")
                    @Override
                    public JsonSerializer<?> modifySerializer(SerializationConfig config, BasicBeanDescription desc,
                        JsonSerializer<?> serializer) 
                        if (IHidable.class.isAssignableFrom(desc.getBeanClass())) 
                            return new HidableSerializer<Object>((JsonSerializer<Object>) serializer);
                        
                        return serializer;
                    
                );
            
        );

        // the data
        String content = " \"foo\": \"bar\" ";

        // build the Object
        Test test = null;
        try 
            test =  mapper.readValue(content, Test.class);
         catch (Exception e) 
            e.printStackTrace();
        

        // and now convert it back to a String
        String data = null;
        try 
             data = mapper.writeValueAsString(test);
         catch (Exception e) 
            e.printStackTrace();
        

        System.out.println( data );

    


测试类

package ch.hasselba;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.codehaus.jackson.annotate.JsonAnyGetter;
import org.codehaus.jackson.annotate.JsonAnySetter;

public class Test implements IHidable 

    private Map<String, Object> others = new ConcurrentHashMap<String, Object>();

    @JsonAnyGetter
    public Map<String, Object> getOthers() 
        return this.others;
    

    @JsonAnySetter
    public void addOther(final String name, final Object value)    
        this.others.put(name, value);
    

    @Override
    public boolean isHidden() 
        return false;
    


可隐藏的序列化器

package ch.hasselba;

import java.io.IOException;

import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;

public class HidableSerializer<T> extends JsonSerializer<T> 

    private JsonSerializer<T> defaultSerializer;

    public HidableSerializer(JsonSerializer<T> serializer) 
        defaultSerializer = serializer;
    

    @Override
    public void serialize(T value, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonProcessingException 

        if( value instanceof IHidable )
            IHidable hidableValue = (IHidable) value;
            if( hidableValue.isHidden() )
                return;
        
        defaultSerializer.serialize(value, jgen, provider);

    


IHidableInterface

package ch.hasselba;


public interface IHidable 
    boolean isHidden();

【问题讨论】:

我用 Jackson 2.5.0 测试过,同样的问题。 【参考方案1】:

问题在于,您在 HidableSerializer 中使用的 defaultSerializer 实例是 ResolvableSerializer (BeanSerializer),但是当您将其包装到 JsonSerializer (HidableSerializer) 在你的 modifySerializer() 方法中,它的 resolve() 方法永远不会被调用并且它无法正确初始化。

如果您尝试将以下行添加到您的 HidableSerializer.serialize() 方法中:

...
((ResolvableSerializer)defaultSerializer).resolve(provider);
defaultSerializer.serialize(value, jgen, provider);
...

它应该可以解决问题。

如果这对你有用,一个更持久的解决方案是让你的 HidableSerializer 自己实现 ResolvableSerializer 并将 resolve() 委托给defaultSerializer,像这样:

@Override
public void resolve(SerializerProvider serializerProvider) throws JsonMappingException 
    if(defaultSerializer instanceof ResolvableSerializer) 
         ((ResolvableSerializer)defaultSerializer).resolve(serializerProvider);
    

【讨论】:

【参考方案2】:

我通过调试过程发现了一些code:

if (ser instanceof ResolvableSerializer) 
    ((ResolvableSerializer) ser).resolve(provider);

它实际上实例化了在您的情况下抛出 NPE 的密钥序列化程序。

修改你的 HidableSerializer 就可以了:

public class HidableSerializer<T> extends JsonSerializer<T> implements ResolvableSerializer 

    private JsonSerializer<T> defaultSerializer;

    public HidableSerializer(JsonSerializer<T> serializer) 
        defaultSerializer = serializer;
    

    @Override
    public void serialize(T value, JsonGenerator jgen, SerializerProvider provider)
        throws IOException, JsonProcessingException 

        if( value instanceof IHidable )
            IHidable hidableValue = (IHidable) value;
            if( hidableValue.isHidden() )
                return;
        
        defaultSerializer.serialize(value, jgen, provider);

    

    @Override
    public void resolve(SerializerProvider provider) throws JsonMappingException 
        ((ResolvableSerializer)defaultSerializer).resolve(provider);
    

【讨论】:

我在半小时前得出了完全相同的结论(请参阅下面的答案):) 谢谢,但正如@zeppelin 所写,他的解决方案提早了一点。

以上是关于belogic里调用sql出现nullpointerexce的主要内容,如果未能解决你的问题,请参考以下文章

belog博客CMS程序源码v1.4.0

NullPointer 当我调用 bindService()

Finder 功能不起作用,基本适配器调用 NullPointer [重复]

LdapUserDetailsImpl.hashCode 中的 LDAP Spring 安全 NullPointer

获取 XMPPConnection 的 Nullpointer 异常

appium测试代码nullpoint