java.io.StreamCorruptedException: недопустимый заголовок потока: 41434544

78
7

Я пытаюсь выполнить сериализацию и десериализацию LocalDateTime через джексон. Я использую hibernate + restful webservices. Это мое лицо:

@Entity
@Table(name = "USERS")
@NamedQueries(value = {
@NamedQuery(name = "getUser", query = "from User user where userId = ?")
})
public class User extends ResourceSupport implements Serializable{

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "USER_ID")
private long userId;

@Column(name = "USER_NAME")
private String userName;

@Column(name = "USER_CREATED")

@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)

private LocalDateTime userCreated;

@Column(name = "USER_PHONE")
private String userPhone;

public User(){}

@JsonCreator
public User(@JsonProperty("userId") long userId,
@JsonProperty("userName") String userName,
@JsonProperty("phone") String phone) {
super();
this.userId = userId;
this.userName = userName;
this.userPhone = phone;
this.userCreated = LocalDateTime.now();
}
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}

public LocalDateTime getUserCreated() {
return userCreated;
}

public void setUserCreated(LocalDateTime userCreated) {
this.userCreated = userCreated;
}

public String getUserPhone() {
return userPhone;
}

public void setUserPhone(String userPhone) {
this.userPhone = userPhone;
}

@Override
public boolean equals(Object user){
boolean result = false;
if((user==null)||!(user instanceof User))
result = false;
else{
User otherUser = (User)user;
result = this.getUserId() == otherUser.getUserId() &&
this.getUserName() == otherUser.getUserName() &&
this.getUserPhone() == otherUser.getUserPhone()&&
this.getUserCreated() == otherUser.getUserCreated();
}
return result;
}

@Override
public int hashCode(){
return Long.hashCode(userId) ;
}

Это мой сериализатор:

public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime>{

@Override
public void serialize(LocalDateTime arg0, JsonGenerator arg1, SerializerProvider arg2)
throws IOException, JsonProcessingException {
// TODO Auto-generated method stub
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = arg0.format(formatter);
arg1.writeString(formattedDateTime);
}

}

Это мой десериализатор:

public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {

@Override
public LocalDateTime deserialize(JsonParser arg0, DeserializationContext arg1)
throws IOException, JsonProcessingException {
// TODO Auto-generated method stub
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime localDateTime = LocalDateTime.parse(arg0.getText(), formatter);
return localDateTime;
}

}

Это мой класс DAO:

@Repository
public class UserDAOImpl implements UserDAO{

@Autowired
private SessionFactory sessionFactory;

public UserDAOImpl(){}
public UserDAOImpl(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}

@Override
public User getUser(long userId) {
//Session session = sessionFactory.getCurrentSession();
Session session = sessionFactory.openSession();
Query query = session.getNamedQuery("getUser");
query.setParameter(0, userId);

return (User)query.uniqueResult();// this string invokes error
}
@Override
public void addUser(User user) {
// TODO Auto-generated method stub
Session session = sessionFactory.openSession();
user.setUserCreated(LocalDateTime.now());
session.save(user);
session.flush();
session.close();
}

Это значение поля USER_CREATED моего сохраненного пользователя:

  ACED00057372000D6A6176612E74696D652E536572955D84BA1B2248B20C00007870770E05000007E004110F261012C684C078

Когда я добавляю пользователя в db, добавление операции выполняется успешно, но когда я пытаюсь получить пользователя из БД, я получаю ошибку:

java.io.StreamCorruptedException: invalid stream header: 41434544
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:806) ~[na:1.8.0_73]
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299) ~[na:1.8.0_73]
at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:309) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:299) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:218) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:287) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:138) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:113) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:27) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:53) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:238) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:234) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:224) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:300) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2727) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1728) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1654) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.getRow(Loader.java:1543) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:727) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.processResultSet(Loader.java:972) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.doQuery(Loader.java:930) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2611) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2594) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2423) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.Loader.list(Loader.java:2418) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1326) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:87) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.hibernate.internal.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:960) ~[hibernate-core-5.0.5.Final.jar:5.0.5.Final]
at org.company.dao.UserDAOImpl.getUser(UserDAOImpl.java:30) ~[classes/:na]
at org.company.dao.UserDAOImpl$$FastClassBySpringCGLIB$$d4b6a590.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) ~[spring-aop-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.company.dao.UserDAOImpl$$EnhancerBySpringCGLIB$$21463096.getUser(<generated>) ~[classes/:na]
at org.company.service.UserServiceImpl.getUser(UserServiceImpl.java:39) ~[classes/:na]
at org.company.controller.UserController.getUser(UserController.java:43) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_73]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_73]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_73]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844) ~[spring-webmvc-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) [tomcat-embed-core-8.0.32.jar:8.0.32]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_73]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_73]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.0.32.jar:8.0.32]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_73]

спросил(а) 2016-04-17T16:15:00+03:00 4 года, 3 месяца назад
1
Решение
87

У меня есть идея, что здесь происходит. Вот подсказки.

    Число 41434544 (шестнадцатеричное) декодируется как буквы "A", "C", "E", "D".

    Сериализация объектов Java начинается с 16-битного магического числа, значение которого в шестнадцатеричном состоянии ACED. (Ссылка: https://docs.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html)

Похоже, вы сделали следующее:

Вы сериализовали некоторый объект в массив байтов. Вы преобразовали массив байтов в текст, содержащий шестнадцатеричное представление байтов. Вы сохранили этот текст в столбце VARCHAR (или аналогичном) некоторой таблицы. Затем вы извлекли текст. Вы использовали String.getBytes(...) для преобразования текста в байты. Вы пытались десериализовать байты.

Проблема в том, что шаг 5 неверен. Вам нужно преобразовать текст в байты, разделив строку на пары символов (шестнадцатеричные цифры) и преобразуя каждую пару в байт.

ОБНОВЛЕНИЕ - по-видимому, Hibernate делает сериализацию за кулисами, и правильное решение состоит в том, чтобы остановить ее; см. @JB Nizet ответ.

ответил(а) 2016-04-17T17:03:00+03:00 4 года, 3 месяца назад
78

Hibernate не поддерживает LocalDateTime, если вы не добавите дополнительную банку в свой путь к классам.

Это означает, что без него он обрабатывает LocalDateTime как любой сериализуемый класс и использует собственную сериализацию Java для хранения значения в двоичном столбце таблицы. Ты действительно этого не хочешь.

Кроме того, не сравнивайте объекты с ==. И обратите внимание, что это не имеет ничего общего с JSON и Jackson.

ответил(а) 2016-04-17T17:01:00+03:00 4 года, 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема