【问题标题】:Spring jdbcSession : Not able to serialize JsonNodeSpring jdbcSession:无法序列化 JsonNode
【发布时间】:2018-11-07 07:36:38
【问题描述】:

我正在尝试将 JsonNode 存储到我的 spring jdbc 会话中,
而当数据设置好并准备在春季插入数据库时​​,会抛出 ConversionFailedException。
我尝试了与下面提到的相同的方法,但是没有用。

No converter found capable of converting from type java.lang.Object to type byte[] in JdbcOperationsSessionRepository

我还查看了 JdbcHttpSessionConfiguration ,并且似乎已经存在相同的代码。

@EnableJdbcHttpSession(maxInactiveIntervalInSeconds = 1800)
public class MyConfiguration extends WebMvcConfigurerAdapter {
}

// session class
@Component
@Scope(value = SCOPE_SESSION, proxyMode = TARGET_CLASS)
public class SessionForm implements Serializable {
    private String someOtherFeild;
    private JsonNode custom;
    ....
}

org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.Object] to type [byte[]] for value 'com.rakuten.payment.step.app.step.model.session.SessionForm@e943f2d'; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: com.fasterxml.jackson.databind.node.ObjectNode
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:43)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:203)
    at org.springframework.session.jdbc.JdbcOperationsSessionRepository.serialize(JdbcOperationsSessionRepository.java:627)
    at org.springframework.session.jdbc.JdbcOperationsSessionRepository.access$400(JdbcOperationsSessionRepository.java:129)
    at org.springframework.session.jdbc.JdbcOperationsSessionRepository$1$2.setValues(JdbcOperationsSessionRepository.java:403)
    at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:960)
    at org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:950)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:662)
    at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:950)
    at org.springframework.session.jdbc.JdbcOperationsSessionRepository$1.doInTransactionWithoutResult(JdbcOperationsSessionRepository.java:395)
    at org.springframework.transaction.support.TransactionCallbackWithoutResult.doInTransaction(TransactionCallbackWithoutResult.java:34)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
    at org.springframework.session.jdbc.JdbcOperationsSessionRepository.save(JdbcOperationsSessionRepository.java:377)
    at org.springframework.session.jdbc.JdbcOperationsSessionRepository.save(JdbcOperationsSessionRepository.java:129)
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:245)
    at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:217)
    at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:170)
    at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

【问题讨论】:

    标签: spring-session


    【解决方案1】:

    尝试将您的组件更改为:

    @Component
    @Scope(value = SCOPE_SESSION, proxyMode = TARGET_CLASS)
    public class SessionForm implements Serializable {
        private String someOtherFeild;
        private JsonNode custom;
    
        private void writeObject(ObjectOutputStream out) throws IOException {
            out.defaultWriteObject();
            if(custom== null){
                out.writeBoolean(false);
            } else {
                out.writeBoolean(true);
                new ObjectMapper().configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false).writeValue(out, custom);
            }
        }
    
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
            in.defaultReadObject();
            if(in.readBoolean()){
                this.custom = new ObjectMapper().configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false).readValue(in, JsonNode.class);
            }
        }
    }
    

    这将更改默认序列化,允许您覆盖默认行为并解决此错误

    Reference

    【讨论】:

    • 对不起,但我仍然在 out.defaultWriteObject(); 处得到完全相同的异常。并且似乎 writeValue 需要 DataOutput /DataInput,它是安全的吗?
    • @brian661,是的,在最近的 Jackson 版本中,必须将 ObjectOutputStream 转换为 OutputStream,因为采用 DataOutput 的重载方法之间存在签名冲突
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2020-09-20
    相关资源
    最近更新 更多