【SpringBoot整合Redis已解决】 Cannot serialize; nested exception is org.springframework.core.serializer.sup

迈不过友情╰ 2024-03-22 08:51 162阅读 0赞

介绍

这里是小编成长之路的历程,也是小编的学习之路。希望和各位大佬们一起成长!

以下为小编最喜欢的两句话:

要有最朴素的生活和最遥远的梦想,即使明天天寒地冻,山高水远,路远马亡。

一个人为什么要努力? 我见过最好的答案就是:因为我喜欢的东西都很贵,我想去的地方都很远,我爱的人超完美。因此,小编想说:共勉!

问题描述:

序列化错误,想要我在实体类序列化一下,但是其实redis本来就是有序列化的封装类

  1. 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.lyn.pojo.GoodsShopcar]
  2. at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:96)
  3. at org.springframework.data.redis.core.AbstractOperations.rawHashValue(AbstractOperations.java:186)
  4. at org.springframework.data.redis.core.DefaultHashOperations.put(DefaultHashOperations.java:251)
  5. at com.lyn.utlis.RedisUtil.hset(RedisUtil.java:237)
  6. at com.lyn.controller.CartTwoController.addToCart(CartTwoController.java:30)
  7. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  8. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  9. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  10. at java.lang.reflect.Method.invoke(Method.java:498)
  11. at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
  12. at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
  13. at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
  14. at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
  15. at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
  16. at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
  17. at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)
  18. at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)
  19. at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
  20. at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
  21. at javax.servlet.http.HttpServlet.service(HttpServlet.java:555)
  22. at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
  23. at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
  24. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
  25. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
  26. at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
  27. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
  28. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
  29. at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
  30. at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
  31. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
  32. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
  33. at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
  34. at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
  35. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
  36. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
  37. at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
  38. at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
  39. at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
  40. at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
  41. at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
  42. at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
  43. at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
  44. at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
  45. at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
  46. at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
  47. at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
  48. at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389)
  49. at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
  50. at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
  51. at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
  52. at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
  53. at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
  54. at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
  55. at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
  56. at java.lang.Thread.run(Thread.java:748)
  57. 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.lyn.pojo.GoodsShopcar]
  58. at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:64)
  59. at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:33)
  60. at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:94)
  61. ... 54 more
  62. Caused by: java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [com.lyn.pojo.GoodsShopcar]
  63. at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:43)
  64. at org.springframework.core.serializer.Serializer.serializeToByteArray(Serializer.java:56)
  65. at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:60)
  66. ... 56 more

解决方法:

小编是因为在util中使用到 RedisTemplate,但是并没有用到redis序列化所以才会报上述错误

9851698c40ea46b78e720faee0c5646a.png

在util中或者config中加入redisconfig,实现redis序列化

  1. @SpringBootConfiguration
  2. public class RedisConfig {
  3. @Bean
  4. public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
  5. RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
  6. redisTemplate.setConnectionFactory(redisConnectionFactory);
  7. //创建一个json的序列化对象
  8. GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
  9. //设置value的序列化方式json
  10. redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
  11. //设置key序列化方式String
  12. redisTemplate.setKeySerializer(new StringRedisSerializer());
  13. //设置hash key序列化方式String
  14. redisTemplate.setHashKeySerializer(new StringRedisSerializer());
  15. //设置hash value序列化json
  16. redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
  17. // 设置支持事务
  18. redisTemplate.setEnableTransactionSupport(true);
  19. redisTemplate.afterPropertiesSet();
  20. return redisTemplate;
  21. }
  22. @Bean
  23. public RedisSerializer<Object> redisSerializer() {
  24. //创建JSON序列化器
  25. ObjectMapper objectMapper = new ObjectMapper();
  26. objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  27. //必须设置,否则无法将JSON转化为对象,会转化成Map类型
  28. objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
  29. return new GenericJackson2JsonRedisSerializer(objectMapper);
  30. }
  31. }

再在redisutil中引入的时候就可以使用到@Autowired,不然没有序列化使用@Autowired

就会冒红

下面的代码是一位大佬写的redisutil

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.data.redis.core.RedisTemplate;
  3. import org.springframework.stereotype.Component;
  4. import org.springframework.util.CollectionUtils;
  5. import javax.annotation.Resource;
  6. import java.util.Collection;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.Set;
  10. import java.util.concurrent.TimeUnit;
  11. // 封装 RedisTemplate的一些操作 RedisUtil
  12. @Component
  13. public final class RedisUtil {
  14. @Autowired
  15. private RedisTemplate<String, Object> redisTemplate;
  16. // =============================common============================
  17. /**
  18. * 指定缓存失效时间
  19. * @param key 键
  20. * @param time 时间(秒)
  21. */
  22. public boolean expire(String key, long time) {
  23. try {
  24. if (time > 0) {
  25. redisTemplate.expire(key, time, TimeUnit.SECONDS);
  26. }
  27. return true;
  28. } catch (Exception e) {
  29. e.printStackTrace();
  30. return false;
  31. }
  32. }
  33. /**
  34. * 根据key 获取过期时间
  35. * @param key 键 不能为null
  36. * @return 时间(秒) 返回0代表为永久有效
  37. */
  38. public long getExpire(String key) {
  39. return redisTemplate.getExpire(key, TimeUnit.SECONDS);
  40. }
  41. /**
  42. * 判断key是否存在
  43. * @param key 键
  44. * @return true 存在 false不存在
  45. */
  46. public boolean hasKey(String key) {
  47. try {
  48. return redisTemplate.hasKey(key);
  49. } catch (Exception e) {
  50. e.printStackTrace();
  51. return false;
  52. }
  53. }
  54. /**
  55. * 删除缓存
  56. * @param key 可以传一个值 或多个
  57. */
  58. @SuppressWarnings("unchecked")
  59. public void del(String... key) {
  60. if (key != null && key.length > 0) {
  61. if (key.length == 1) {
  62. redisTemplate.delete(key[0]);
  63. } else {
  64. redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
  65. }
  66. }
  67. }
  68. // ============================String=============================
  69. /**
  70. * 普通缓存获取
  71. * @param key 键
  72. * @return 值
  73. */
  74. public Object get(String key) {
  75. return key == null ? null : redisTemplate.opsForValue().get(key);
  76. }
  77. /**
  78. * 普通缓存放入
  79. * @param key 键
  80. * @param value 值
  81. * @return true成功 false失败
  82. */
  83. public boolean set(String key, Object value) {
  84. try {
  85. redisTemplate.opsForValue().set(key, value);
  86. return true;
  87. } catch (Exception e) {
  88. e.printStackTrace();
  89. return false;
  90. }
  91. }
  92. /**
  93. * 普通缓存放入并设置时间
  94. * @param key 键
  95. * @param value 值
  96. * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
  97. * @return true成功 false 失败
  98. */
  99. public boolean set(String key, Object value, long time) {
  100. try {
  101. if (time > 0) {
  102. redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
  103. } else {
  104. set(key, value);
  105. }
  106. return true;
  107. } catch (Exception e) {
  108. e.printStackTrace();
  109. return false;
  110. }
  111. }
  112. /**
  113. * 递增
  114. * @param key 键
  115. * @param delta 要增加几(大于0)
  116. */
  117. public long incr(String key, long delta) {
  118. if (delta < 0) {
  119. throw new RuntimeException("递增因子必须大于0");
  120. }
  121. return redisTemplate.opsForValue().increment(key, delta);
  122. }
  123. /**
  124. * 递减
  125. * @param key 键
  126. * @param delta 要减少几(小于0)
  127. */
  128. public long decr(String key, long delta) {
  129. if (delta < 0) {
  130. throw new RuntimeException("递减因子必须大于0");
  131. }
  132. return redisTemplate.opsForValue().increment(key, -delta);
  133. }
  134. // ================================Map=================================
  135. /**
  136. * HashGet
  137. * @param key 键 不能为null
  138. * @param item 项 不能为null
  139. */
  140. public Object hget(String key, String item) {
  141. return redisTemplate.opsForHash().get(key, item);
  142. }
  143. /**
  144. * 获取所有给定字段的值
  145. * author: xu
  146. * @param key
  147. * @return
  148. */
  149. public Map<Object, Object> hgetall(String key) {
  150. return redisTemplate.opsForHash().entries(key);
  151. }
  152. /**
  153. * 获取hashKey对应的所有键值
  154. * @param key 键
  155. * @return 对应的多个键值
  156. */
  157. public Map<Object, Object> hmget(String key) {
  158. return redisTemplate.opsForHash().entries(key);
  159. }
  160. /**
  161. * HashSet
  162. * @param key 键
  163. * @param map 对应多个键值
  164. */
  165. public boolean hmset(String key, Map<String, Object> map) {
  166. try {
  167. redisTemplate.opsForHash().putAll(key, map);
  168. return true;
  169. } catch (Exception e) {
  170. e.printStackTrace();
  171. return false;
  172. }
  173. }
  174. /**
  175. * HashSet 并设置时间
  176. * @param key 键
  177. * @param map 对应多个键值
  178. * @param time 时间(秒)
  179. * @return true成功 false失败
  180. */
  181. public boolean hmset(String key, Map<String, Object> map, long time) {
  182. try {
  183. redisTemplate.opsForHash().putAll(key, map);
  184. if (time > 0) {
  185. expire(key, time);
  186. }
  187. return true;
  188. } catch (Exception e) {
  189. e.printStackTrace();
  190. return false;
  191. }
  192. }
  193. /**
  194. * 向一张hash表中放入数据,如果不存在将创建
  195. *
  196. * @param key 键
  197. * @param item 项
  198. * @param value 值
  199. * @return true 成功 false失败
  200. */
  201. public boolean hset(String key, String item, Object value) {
  202. try {
  203. redisTemplate.opsForHash().put(key, item, value);
  204. return true;
  205. } catch (Exception e) {
  206. e.printStackTrace();
  207. return false;
  208. }
  209. }
  210. /**
  211. * 向一张hash表中放入数据,如果不存在将创建
  212. *
  213. * @param key 键
  214. * @param item 项
  215. * @param value 值
  216. * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
  217. * @return true 成功 false失败
  218. */
  219. public boolean hset(String key, String item, Object value, long time) {
  220. try {
  221. redisTemplate.opsForHash().put(key, item, value);
  222. if (time > 0) {
  223. expire(key, time);
  224. }
  225. return true;
  226. } catch (Exception e) {
  227. e.printStackTrace();
  228. return false;
  229. }
  230. }
  231. /**
  232. * 删除hash表中的值
  233. *
  234. * @param key 键 不能为null
  235. * @param item 项 可以使多个 不能为null
  236. */
  237. public void hdel(String key, Object... item) {
  238. redisTemplate.opsForHash().delete(key, item);
  239. }
  240. /**
  241. * 判断hash表中是否有该项的值
  242. *
  243. * @param key 键 不能为null
  244. * @param item 项 不能为null
  245. * @return true 存在 false不存在
  246. */
  247. public boolean hHasKey(String key, String item) {
  248. return redisTemplate.opsForHash().hasKey(key, item);
  249. }
  250. /**
  251. * hash递增 如果不存在,就会创建一个 并把新增后的值返回
  252. *
  253. * @param key 键
  254. * @param item 项
  255. * @param by 要增加几(大于0)
  256. */
  257. public double hincr(String key, String item, double by) {
  258. return redisTemplate.opsForHash().increment(key, item, by);
  259. }
  260. /**
  261. * hash递减
  262. *
  263. * @param key 键
  264. * @param item 项
  265. * @param by 要减少记(小于0)
  266. */
  267. public double hdecr(String key, String item, double by) {
  268. return redisTemplate.opsForHash().increment(key, item, -by);
  269. }
  270. // ============================set=============================
  271. /**
  272. * 根据key获取Set中的所有值
  273. * @param key 键
  274. */
  275. public Set<Object> sGet(String key) {
  276. try {
  277. return redisTemplate.opsForSet().members(key);
  278. } catch (Exception e) {
  279. e.printStackTrace();
  280. return null;
  281. }
  282. }
  283. /**
  284. * 根据value从一个set中查询,是否存在
  285. *
  286. * @param key 键
  287. * @param value 值
  288. * @return true 存在 false不存在
  289. */
  290. public boolean sHasKey(String key, Object value) {
  291. try {
  292. return redisTemplate.opsForSet().isMember(key, value);
  293. } catch (Exception e) {
  294. e.printStackTrace();
  295. return false;
  296. }
  297. }
  298. /**
  299. * 将数据放入set缓存
  300. *
  301. * @param key 键
  302. * @param values 值 可以是多个
  303. * @return 成功个数
  304. */
  305. public long sSet(String key, Object... values) {
  306. try {
  307. return redisTemplate.opsForSet().add(key, values);
  308. } catch (Exception e) {
  309. e.printStackTrace();
  310. return 0;
  311. }
  312. }
  313. /**
  314. * 将set数据放入缓存
  315. *
  316. * @param key 键
  317. * @param time 时间(秒)
  318. * @param values 值 可以是多个
  319. * @return 成功个数
  320. */
  321. public long sSetAndTime(String key, long time, Object... values) {
  322. try {
  323. Long count = redisTemplate.opsForSet().add(key, values);
  324. if (time > 0)
  325. expire(key, time);
  326. return count;
  327. } catch (Exception e) {
  328. e.printStackTrace();
  329. return 0;
  330. }
  331. }
  332. /**
  333. * 获取set缓存的长度
  334. *
  335. * @param key 键
  336. */
  337. public long sGetSetSize(String key) {
  338. try {
  339. return redisTemplate.opsForSet().size(key);
  340. } catch (Exception e) {
  341. e.printStackTrace();
  342. return 0;
  343. }
  344. }
  345. /**
  346. * 移除值为value的
  347. *
  348. * @param key 键
  349. * @param values 值 可以是多个
  350. * @return 移除的个数
  351. */
  352. public long setRemove(String key, Object... values) {
  353. try {
  354. Long count = redisTemplate.opsForSet().remove(key, values);
  355. return count;
  356. } catch (Exception e) {
  357. e.printStackTrace();
  358. return 0;
  359. }
  360. }
  361. // ===============================list=================================
  362. /**
  363. * 获取list缓存的内容
  364. *
  365. * @param key 键
  366. * @param start 开始
  367. * @param end 结束 0 到 -1代表所有值
  368. */
  369. public List<Object> lGet(String key, long start, long end) {
  370. try {
  371. return redisTemplate.opsForList().range(key, start, end);
  372. } catch (Exception e) {
  373. e.printStackTrace();
  374. return null;
  375. }
  376. }
  377. /**
  378. * 获取list缓存的长度
  379. *
  380. * @param key 键
  381. */
  382. public long lGetListSize(String key) {
  383. try {
  384. return redisTemplate.opsForList().size(key);
  385. } catch (Exception e) {
  386. e.printStackTrace();
  387. return 0;
  388. }
  389. }
  390. /**
  391. * 通过索引 获取list中的值
  392. *
  393. * @param key 键
  394. * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
  395. */
  396. public Object lGetIndex(String key, long index) {
  397. try {
  398. return redisTemplate.opsForList().index(key, index);
  399. } catch (Exception e) {
  400. e.printStackTrace();
  401. return null;
  402. }
  403. }
  404. /**
  405. * 将list放入缓存
  406. *
  407. * @param key 键
  408. * @param value 值
  409. */
  410. public boolean lSet(String key, Object value) {
  411. try {
  412. redisTemplate.opsForList().rightPush(key, value);
  413. return true;
  414. } catch (Exception e) {
  415. e.printStackTrace();
  416. return false;
  417. }
  418. }
  419. /**
  420. * 将list放入缓存
  421. * @param key 键
  422. * @param value 值
  423. * @param time 时间(秒)
  424. */
  425. public boolean lSet(String key, Object value, long time) {
  426. try {
  427. redisTemplate.opsForList().rightPush(key, value);
  428. if (time > 0)
  429. expire(key, time);
  430. return true;
  431. } catch (Exception e) {
  432. e.printStackTrace();
  433. return false;
  434. }
  435. }
  436. /**
  437. * 将list放入缓存
  438. *
  439. * @param key 键
  440. * @param value 值
  441. * @return
  442. */
  443. public boolean lSet(String key, List<Object> value) {
  444. try {
  445. redisTemplate.opsForList().rightPushAll(key, value);
  446. return true;
  447. } catch (Exception e) {
  448. e.printStackTrace();
  449. return false;
  450. }
  451. }
  452. /**
  453. * 将list放入缓存
  454. *
  455. * @param key 键
  456. * @param value 值
  457. * @param time 时间(秒)
  458. * @return
  459. */
  460. public boolean lSet(String key, List<Object> value, long time) {
  461. try {
  462. redisTemplate.opsForList().rightPushAll(key, value);
  463. if (time > 0)
  464. expire(key, time);
  465. return true;
  466. } catch (Exception e) {
  467. e.printStackTrace();
  468. return false;
  469. }
  470. }
  471. /**
  472. * 根据索引修改list中的某条数据
  473. *
  474. * @param key 键
  475. * @param index 索引
  476. * @param value 值
  477. * @return
  478. */
  479. public boolean lUpdateIndex(String key, long index, Object value) {
  480. try {
  481. redisTemplate.opsForList().set(key, index, value);
  482. return true;
  483. } catch (Exception e) {
  484. e.printStackTrace();
  485. return false;
  486. }
  487. }
  488. /**
  489. * 移除N个值为value
  490. *
  491. * @param key 键
  492. * @param count 移除多少个
  493. * @param value 值
  494. * @return 移除的个数
  495. */
  496. public long lRemove(String key, long count, Object value) {
  497. try {
  498. Long remove = redisTemplate.opsForList().remove(key, count, value);
  499. return remove;
  500. } catch (Exception e) {
  501. e.printStackTrace();
  502. return 0;
  503. }
  504. }
  505. }

以上就是小编所实践的内容,希望能够帮助到大家,感谢各位大佬的观看!!!

发表评论

表情:
评论列表 (有 0 条评论,162人围观)

还没有评论,来说两句吧...

相关阅读