Java:从数据库表反序列化对象会引发 StreamCorruptedException

问题描述 投票:0回答:2

我正在研究反序列化存储在数据库表中的对象。当尝试使用 ObjectInputStream 读取序列化数据时,我遇到 StreamCorruptedException 并显示消息“无效的流标头:EFBFBDEF”。数据存储在“OAUTH_CLIENTS”表中名为“SERIALIZATION”的列中。如何正确反序列化从数据库检索的数据?

这是我的 ClassicClientsService:

@Component
public class ClassicClientsService implements ClientDetailsService {

    private final JdbcTemplate dataTemplate;
    private final ObjectMapper objectMapper = new ObjectMapper();

    public ClassicClientsService(DataSource dataSource) {
        this.dataTemplate = new JdbcTemplate(dataSource);
    }

    @Override
    public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exception {

        try {
            ClientDetails details = dataTemplate.queryForObject("SELECT SERIALIZATION FROM OAUTH_CLIENTS WHERE CLIENTID = ?", new ClientDetailsMapper(), new Object[]{clientId});
            return details;
        } catch (EmptyResultDataAccessException ers) {
            throw new EmptyResultDataAccessException("Client " + clientId + " was not found", 1);
        }

    }

    private class ClientDetailsMapper implements RowMapper<ClientDetails> {

        @SneakyThrows
        @Override
        public ClientDetails mapRow(ResultSet rs, int rowNum) {
            byte[] temp = rs.getBytes("SERIALIZATION");
            
            return (ClientDetails) new ObjectInputStream(new ByteArrayInputStream(temp)).readObject();
        }

    }}

public boolean addClient(ClientDetails details) throws DataAccessException {
        ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
        try {
            ObjectOutputStream outObject = new ObjectOutputStream(outBytes);
            outObject.writeObject(details);
            outObject.flush();
            outObject.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] szDetails = outBytes.toByteArray();
        dataTemplate.update("INSERT INTO OAUTH_CLIENTS (CLIENTID, PROTOCOL, SERIALIZATION) VALUES(?,1,?)", new Object[]{details.getClientId(), szDetails});
        return false;
    }

当我调用方法“loadClientByCLientId”时,我收到异常

@Configuration
@ComponentScan
public class Application {

    public static void main(String[] args) {
        migrateClients(args[0]);
    }

    private static void migrateClients(String clientId) {
        if (clientId.isEmpty()) {
            throw new RuntimeException("client id should be set as program argument");
        }
        ApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
        ClassicClientsService clientDetailsService = context.getBean(ClassicClientsService.class);
        OauthClientsManager oauthClientsManager = context.getBean(OauthClientsManager.class);
        clientDetailsService.loadClientByClientId(clientId);

日志:


    NFO: Loaded JDBC driver: com.mysql.jdbc.Driver
Exception in thread "main" java.io.StreamCorruptedException: invalid stream header: EFBFBDEF
    at java.base/java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:935)
    at java.base/java.io.ObjectInputStream.<init>(ObjectInputStream.java:374)
java database serialization deserialization rowmapper
2个回答
0
投票

对于面临这个问题的任何人,我遇到了同样的问题,发现它是由表的字符集和排序规则引起的,我在 persistence.xml 选项上设置了它并解决了,在我的例子中它使用的是 utf8mb4。


0
投票

为了解决这个问题,我在一个全新的项目中创建了一个新的应用程序(这没有多大意义),并且数据在这个新环境中成功反序列化。

© www.soinside.com 2019 - 2024. All rights reserved.