In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "what is the custom serialization method of spring-session". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Spring-session custom serialization
Spring-session defaults to the jdk serialization method, which is inefficient, memory-intensive, and requires additional code modifications. Therefore, you need to customize the serialization method.
Custom sequence methods use the jackson library
First, you need a class as a serialization tool, and you need to implement the
RedisSerializer
The interface does not provide a corresponding class object when deserializing, so when using jackson deserialization, it will be returned as an Object object.
So my solution is to get the class of the corresponding bean when serializing, return it together with the serialized result of bean, and store it in redis
When deserializing, first convert the byte array into a string, intercept the stored class string from it, and pass it into the jackson deserialization method as a parameter
Problem: for bean with generics, it cannot be converted to a truly appropriate type
Solution: for collection classes such as list,map,set, get the class of the first element and store it in redis
Disadvantages: requires that the collection class elements must be the same subclass and cannot come from the same parent class
Problem: when spring-session deletes attribute, it doesn't really delete it from redis. It just sets value to null, and this class is also called for serialization.
Solution: look at the spring-session source code and know that the way to deal with null is to directly return an array of byte with the number 0, and you can directly return null when deserializing.
Import cn.nsu.edu.web.four.config.BaseStatic;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.JavaType;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.type.TypeFactory;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.serializer.RedisSerializer;import org.springframework.data.redis.serializer.SerializationException;import org.springframework.data.redis.serializer.SerializationUtils Import java.io.IOException;import java.io.UnsupportedEncodingException;import java.util.*;import java.util.regex.Matcher;import java.util.regex.Pattern; public class SessionSerializer implements RedisSerializer {@ Autowired private ObjectMapper mapper; private Logger logger = LoggerFactory.getLogger (getClass ()); private final String separator = "="; private final String classPrefix = ""; private final String classSeparator = ","; private Pattern pattern; public SessionSerializer () {pattern = Pattern.compile ("") } / * get class, including generics of collection classes *
Only a maximum of two generics are supported, and the data in the collection must be the same implementation class, and generics cannot be declared as a parent class.
* * @ param obj the object to be serialized * @ return has no generics and is in the form of java.lang.String *
A generic type in the form of java.lang.String
*
Two generics in the form of java.lang.String
* / private String getBegin (Object obj) {StringBuilder builder = new StringBuilder (obj.getClass (). ToString (). Substring (6) + classPrefix); if (obj instanceof List) {List list = ((List) obj); if (! list.isEmpty ()) {Object temp = list.get (0); builder.append (temp.getClass (). ToString (). Substring (6)) }} else if (obj instanceof Map) {Map map = ((Map) obj); Iterator iterator = map.keySet () .iterator (); if (iterator.hasNext ()) {Object key = iterator.next (); Object value = map.get (key) Builder.append (key.getClass (). ToString (). Substring (6)) .append (classSeparator) .append (value.getClass (). ToString () .substring (6));} else if (obj instanceof Set) {Set set = ((Set) obj); Iterator iterator = set.iterator () If (iterator.hasNext ()) {Object value = iterator.next (); builder.append (value.getClass (). ToString (). Substring (6);} builder.append (classSuffix); return builder.toString () } @ Override public byte [] serialize (Object o) throws SerializationException {if (o = = null) return new byte [0]; try {String builder = getBegin (o) + separator + mapper.writeValueAsString (o); return builder.getBytes (BaseStatic.CHARSET) } catch (UnsupportedEncodingException | JsonProcessingException e) {e.printStackTrace ();} return null;} @ Override public Object deserialize (byte [] bytes) throws SerializationException {if (bytes = = null | | bytes.length = = 0) session try {String temp = new String (bytes, BaseStatic.CHARSET) where return null;// has been deleted; String cl [] = getClass (temp) If (cl = = null) {throw new RuntimeException ("incorrect serialization result =" + temp);} if (cl.length = = 1) {return mapper.readValue (temp.substring (temp.indexOf (separator) + 1), Class.forName (cl [0])) } else if (cl.length = = 2) {TypeFactory factory = mapper.getTypeFactory (); JavaType type = factory.constructParametricType (Class.forName (cl [0]), Class.forName (cl [1])); return mapper.readValue (temp.substring (temp.indexOf (separator) + 1), type) } else if (cl.length = = 3) {TypeFactory factory = mapper.getTypeFactory (); JavaType type = factory.constructParametricType (Class.forName (cl [0]), Class.forName (cl [1]), Class.forName (cl [2])); return mapper.readValue (temp.substring (temp.indexOf (separator) + 1), type) }} catch (ClassNotFoundException | IOException e) {e.printStackTrace ();} return null;} / * parse the string to get class *
One type, java.lang.String= {}
*
Two types, followed by generics, java.lang.String= {}
*
Three types, followed by generics, java.lang.String= {}
* * @ param value string containing class * @ return returns an array of all classes * / private String [] getClass (String value) {int index = value.indexOf (classPrefix); if (index! =-1) {Matcher matcher = pattern.matcher (index, value.indexOf (classSuffix) + 1)) If (matcher.find ()) {String temp = matcher.group (1); if (temp.isEmpty ()) {/ / No generic return new String [] {value.substring (0, index)};} else if (temp.contains (classSeparator)) {/ / two generic int nextIndex = temp.indexOf (classSeparator) Return new String [] {value.substring (0, index), temp.substring (0, nextIndex), temp.substring (nextIndex + 1)} } else {/ / A generic return new String [] {value.substring (0, index), temp};} return null;}} configure spring-session serialization
Make changes on the previous configuration file
Troubleshooting spring-session serialization issu
Serious: Servlet.service () for servlet [spring] in context with path [/] threw exception
Org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.mogoroom.service.vo.criteria.QueryBSPromotionListVO]
At org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize (JdkSerializationRedisSerializer.java:52)
At org.springframework.data.redis.core.AbstractOperations.rawHashValue (AbstractOperations.java:146)
At org.springframework.data.redis.core.DefaultHashOperations.putAll (DefaultHashOperations.java:128)
At org.springframework.data.redis.core.DefaultBoundHashOperations.putAll (DefaultBoundHashOperations.java:85)
At org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.saveDelta (RedisOperationsSessionRepository.java:778)
At org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.access$000 (RedisOperationsSessionRepository.java:670)
At org.springframework.session.data.redis.RedisOperationsSessionRepository.save (RedisOperationsSessionRepository.java:388)
At org.springframework.session.data.redis.RedisOperationsSessionRepository.save (RedisOperationsSessionRepository.java:245)
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.springframework.web.filter.DelegatingFilterProxy.invokeDelegate (DelegatingFilterProxy.java:344)
At org.springframework.web.filter.DelegatingFilterProxy.doFilter (DelegatingFilterProxy.java:261)
At org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:243)
At org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:210)
At org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:222)
At org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:123)
At org.apache.catalina.authenticator.AuthenticatorBase.invoke (AuthenticatorBase.java:502)
At org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:171)
At org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:100)
At org.apache.catalina.valves.AccessLogValve.invoke (AccessLogValve.java:953)
At org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:118)
At org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:408)
At org.apache.coyote.http11.AbstractHttp11Processor.process (AbstractHttp11Processor.java:1041)
At org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process (AbstractProtocol.java:603)
At org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run (JIoEndpoint.java:310)
At java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142)
At java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:617)
At java.lang.Thread.run (Thread.java:745)
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.mogoroom.service.vo.criteria.QueryBSPromotionListVO]
At org.springframework.core.serializer.support.SerializingConverter.convert (SerializingConverter.java:67)
At org.springframework.core.serializer.support.SerializingConverter.convert (SerializingConverter.java:34)
At org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize (JdkSerializationRedisSerializer.java:50)
... 29 more
Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.mogoroom.service.vo.criteria.QueryBSPromotionListVO]
At org.springframework.core.serializer.DefaultSerializer.serialize (DefaultSerializer.java:41)
At org.springframework.core.serializer.support.SerializingConverter.convert (SerializingConverter.java:62)
... 31 more
problem
The default jdk serialization is used when spring session exception information is not printed to the log. Because the entity does not have a sequence of words, it causes an exception, but it is not entered into the log, resulting in a problem located.
In the code, request.getSession (). SetAttribute () is an exception-free spring session that only commit when a request is returned, triggers a spring session submission.
The code is as follows: onResponseCommitted
/ * Allows ensuring that the session is saved if the response is committed. * * @ author Rob Winch * @ since 1.0 * / private final class SessionRepositoryResponseWrapper extends OnCommittedResponseWrapper {private final SessionRepositoryRequestWrapper request; / * Create a new {@ link SessionRepositoryResponseWrapper}. * @ param request the request to be wrapped * @ param response the response to be wrapped * / SessionRepositoryResponseWrapper (SessionRepositoryRequestWrapper request, HttpServletResponse response) {super (response); if (request = = null) {throw new IllegalArgumentException ("request cannot be null");} this.request = request;} @ Override protected void onResponseCommitted () {this.request.commitSession () }} OnCommittedResponseWrapper abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper {/ * * Calls onResponseCommmitted () with the current contents as long as * {@ link # disableOnResponseCommitted ()} was not invoked. * / private void doOnResponseCommitted () {if (! this.disableOnCommitted) {onResponseCommitted (); disableOnResponseCommitted ();}
DoOnResponseCommitted correlation dependency departure method
Solution method
Filter, grab the log.
Chain.doFilter (wrappedRequest, response);} catch (Exception ex) {logger.error ("xxf", ex);} "what is the custom serialization method for spring-session"? thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.