使用jackson时registerModule代码应该存在的位置

时间:2015-06-01 02:25:21

标签: java jackson

这是我的测试代码。

DynaBean bean1 = new LazyDynaBean();
bean1.set("p1", 1);
bean1.set("p2", 2);
ObjectMapper mapper = new ObjectMapper();
try {
    LOGGER.error(mapper.writeValueAsString(bean1));
} catch (JsonProcessingException ex) {
    LOGGER.catching(ex);
}
SimpleModule simpleModule = new SimpleModule("SimpleModule", new Version(1, 0, 0, null, "com.bolan", "oa"));
simpleModule.addSerializer(DynaBean.class, new DynaBeanSerializer());
mapper.registerModule(simpleModule);

DynaBean bean2 = new LazyDynaBean();
bean2.set("p1", 1);
bean2.set("p2", 2);
try {
    LOGGER.error(mapper.writeValueAsString(bean2));
} catch (JsonProcessingException ex) {
    LOGGER.catching(ex);
}

这是DynaBeanSerializer的来源:

public class DynaBeanSerializer extends JsonSerializer<DynaBean> {

    private final static Logger LOGGER = LogManager.getLogger(DynaBeanSerializer.class);

    @Override
    public void serialize(DynaBean value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
        LOGGER.info("serializing the byna bean!");
        gen.writeStartObject();
        DynaProperty[] dynaProperties = value.getDynaClass().getDynaProperties();
        for (DynaProperty dynaProperty : dynaProperties) {
            try {
                gen.writeObjectField(dynaProperty.getName(), PropertyUtils.getProperty(value, dynaProperty.getName()));
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) {
                LOGGER.error(ex);
            }
        }
        gen.writeEndObject();
    }

    @Override
    public Class<DynaBean> handledType() {
        LOGGER.info("get JsonSerializer type!");
        return DynaBean.class;
    }

}

输出是:

10:18:09.794 [JavaFX Application Thread] ERROR com.bolan.test.javafx.test.FXMLController - {"dynaClass":{"dynaBeanClass":"org.apache.commons.beanutils.LazyDynaBean","name":"org.apache.commons.beanutils.LazyDynaClass","restricted":false,"returnNull":false,"dynaProperties":[{"name":"p1","type":"java.lang.Integer","contentType":null,"indexed":false,"mapped":false},{"name":"p2","type":"java.lang.Integer","contentType":null,"indexed":false,"mapped":false}]},"map":{"p2":2,"p1":1}}
10:18:09.797 [JavaFX Application Thread] ERROR com.bolan.test.javafx.test.FXMLController - {"dynaClass":{"dynaBeanClass":"org.apache.commons.beanutils.LazyDynaBean","name":"org.apache.commons.beanutils.LazyDynaClass","restricted":false,"returnNull":false,"dynaProperties":[{"name":"p1","type":"java.lang.Integer","contentType":null,"indexed":false,"mapped":false},{"name":"p2","type":"java.lang.Integer","contentType":null,"indexed":false,"mapped":false}]},"map":{"p2":2,"p1":1}}

但我希望输出如下:

10:21:03.933 [JavaFX Application Thread] ERROR com.bolan.test.javafx.test.FXMLController - {"p1":1,"p2":2}

还有什么,如果我按如下方式编辑测试代码:

DynaBean bean1 = new LazyDynaBean();
bean1.set("p1", 1);
bean1.set("p2", 2);
ObjectMapper mapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule("SimpleModule", new Version(1, 0, 0, null, "com.bolan", "oa"));
simpleModule.addSerializer(DynaBean.class, new DynaBeanSerializer());
mapper.registerModule(simpleModule);

DynaBean bean2 = new LazyDynaBean();
bean2.set("p1", 1);
bean2.set("p2", 2);
try {
    LOGGER.error(mapper.writeValueAsString(bean2));
} catch (JsonProcessingException ex) {
    LOGGER.catching(ex);
}

输出是我希望〜它非常奇怪。

2 个答案:

答案 0 :(得分:0)

首次使用ObjectMapper之前,您必须注册所有要使用的模块。使用后注册可能有效,也可能无效;但是,为已经序列化/反序列化的类型添加自定义(反)序列化器将不会因序列化器和反序列化器的缓存而生效。

答案 1 :(得分:0)

这是我的resteasy代码,用于展示框架的objectmapper:

@Provider
@Produces({MediaType.APPLICATION_JSON})
public class CustomJsonProvider implements ContextResolver<ObjectMapper> {

    private final static Logger LOGGER = LogManager.getLogger(CustomJsonProvider.class);
    private final ObjectMapper mapper;

    public CustomJsonProvider() {
        LOGGER.info("Register provider CustomJsonProvider for resteasy");
        this.mapper = new CustomObjectMapper();
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        LOGGER.info("Get provider CustomJsonProvider for resteasy");
        return mapper;
    }

}

“CustomJsonProvider()”在开发期间被调用一次,每次我的对象被序列化时都会调用“getContext”。但是,我的自定义序列化程序并未被重新使用。

这是CustomObjectMapper的源代码:

public class CustomObjectMapper extends ObjectMapper {

    private static final Logger LOGGER = LogManager.getLogger(CustomObjectMapper.class);

    public CustomObjectMapper() {
        SimpleModule simpleModule = new SimpleModule("SimpleModule", new Version(1, 0, 0, null, "com.bolan", "oa"));
        simpleModule.addSerializer(DynaBean.class, new DynaBeanSerializer());
        registerModule(simpleModule);
    }

DynaBeanSerializer的源代码显示在问题中。

这是我的web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <display-name>Restful Test</display-name>
    <context-param>
        <param-name>resteasy.jndi.resources</param-name>
        <param-value>java:app/service/LocatingResourceBean,java:app/service/SimpleResourceBean</param-value>
    </context-param>
    <context-param>
        <param-name>resteasy.providers</param-name>
        <param-value>com.bolan.rest.provider.CustomJsonProvider,com.bolan.rest.provider.CustomJsonBodyWriter</param-value>
    </context-param>
    <context-param>
        <param-name>resteasy.scan.providers</param-name>
        <param-value>true</param-value>
    </context-param>
<!--    <listener>
        <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
    </listener>-->
    <servlet>
        <servlet-name>oa</servlet-name>
        <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>oa</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>