当我们使用RedisTemplate向我们的Redis数据库中set(“originName”)时,我们在服务端中获取该key的时候出现了乱码\xac\xed\x00\x05t\x00\noriginName` 原因:因为我们springboot中的RedisTemplate将我们的key保存的时候会将其进行序列化,此时我们在别的客户端获取的时候机会出现乱码。 解决:我们需要自己定义我们的RedisTemplate中的序列化机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@Configuration public class RedisTemplateConfig { @Bean public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory connectionFactory){ RedisTemplate<Object, Object> objectObjectRedisTemplate = new RedisTemplate<>(); objectObjectRedisTemplate.setKeySerializer(new StringRedisSerializer()); objectObjectRedisTemplate.setHashKeySerializer(new StringRedisSerializer()); objectObjectRedisTemplate.setConnectionFactory(connectionFactory); return objectObjectRedisTemplate; } } |
由于我们获取值时会将它进行反序列化,我们就无须设置value的反序列化 from:https://blog.csdn.net/ebdbbd/article/details/126266968 另一个版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@Bean public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory , GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer , StringRedisSerializer stringRedisSerializer) { RedisTemplate objectObjectRedisTemplate = new RedisTemplate(); objectObjectRedisTemplate.setConnectionFactory(redisConnectionFactory); objectObjectRedisTemplate.setKeySerializer(stringRedisSerializer); objectObjectRedisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer); objectObjectRedisTemplate.setHashKeySerializer(stringRedisSerializer); objectObjectRedisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer); return objectObjectRedisTemplate; } |
View Details
获取当前时间,需要用到 PHP Date() 函数。 PHP Date() 把时间戳格式化为更易读的日期和时间。 语法:
1 |
date(format,timestamp) |
其中参数 format 为显示格式,参数 timestamp 为时间戳,是可选择的,默认为 time() ,即如果没有给出时间戳则使用本地当前时间。 format 格式参数在这里简单介绍几个: 一些常用于日期的字符: Y – 完整表示年份(四位数字:2019) y – 表示年份(两位数字:19) F – 表示月份(完整的文本格式: January 或者 March) M – 表示月份(3个字母:Jun) m – 表示月份,有前导0(数字:04) n – 表示月份,无前导0(数字:4) d – 表示月份中的第几天,有前导0(01-31) j – 表示月份中的第几天,无前导0(1-31) D – 表示星期几(3字母:Wed) l – 表示星期几(完整英文:Wednesday) w – 表示星期中的第几天(数字,0表示星期天) W – 表示一年中的第几周 z – 表示一年中的第几天(0-366) 实例:
1 2 3 4 5 6 |
<?php echo "<p>今天是:" . date("Y/m/d") . "</p>"; echo "<p>今天是:" . date("Y.m.d") . "</p>"; echo "<p>今天是:" . date("Y-m-d") . "</p>"; echo "<p>今天是:" . date("l") . "</p>"; ?> |
运行结果: 如果想要中文的年月日,可以这样写:
1 |
echo "现在时间是:" . date("Y年m月d日"); |
运行结果: 今天是:2019年04月24日 获得简单的时间: 常用于时间的字符: H – 24小时格式,有前导0(08,18) h – 12小时格式,有前导0(06,11) G – 24小时格式,无前导0(9,17) g – 12小时格式,无前导0(6,12) i – 表示分钟,有前导0(00-59) s […]
View Details本篇文章小编给大家分享一下Html页面支持暗黑模式实现代码,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。 准备 其实,我们只是需要使用到css中的prefers-color-scheme 媒体查询。 no-preference 表示用户未制定操作系统主题。作为布尔值时,为false 输出。 light 表示用户的操作系统是浅色主题。 dark 表示用户的操作系统是深色主题。 说明 此方法只是一个简单demo,可以使用该方法拓展出其他实现方式。 prefers-color-scheme说明 DEMO地址 HTML 页面适应黑暗模式 测试文字 CSS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
.back {background: white; color: #555;text-align: center} @media (prefers-color-scheme: dark) { .back {background: #333; color: white;} .models {border:solid 1px #00ff00} } @media (prefers-color-scheme: light) { .back {background: white; color: #555;} .models {border:solid 1px #2b85e4} } |
from:https://blog.csdn.net/weixin_39610678/article/details/117835878
View Details原始图片 滤镜调节后效果: 代码中替换图片即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <img src="./tianditu.jpg" id="tiimg" style="width: 50%;"/> <br> <span>高斯模糊:blur(<span id="showblur"></span>px)</span><input id="gaosi" type="range" value="0" onchange="document.getElementById('showblur').innerHTML=value" /> <br> <span>黑白效果:grayscale(<span id="showgrayscale"></span>%)</span><input id="heiba" type="range" value="0" onchange="document.getElementById('showgrayscale').innerHTML=value" /> <br> <span>怀旧效果:sepia(<span id="showsepia"></span>%)</span><input id="huaij" type="range" value="0" onchange="document.getElementById('showsepia').innerHTML=value"/> <br> <span>反色效果:invert(<span id="showinvert"></span>%)</span><input id="fansx" type="range" value="0" onchange="document.getElementById('showinvert').innerHTML=value"/> <br> <span>透明效果:opacity(<span id="showopacity"></span>%)</span><input id="toum" type="range" value="0" onchange="document.getElementById('showopacity').innerHTML=value"/> <br> <span>图饱和度:saturate(<span id="showsaturate"></span>%)</span><input id="baof" type="range" value="0" onchange="document.getElementById('showsaturate').innerHTML=value"/> <br> <span>色相:hue-rotate(<span id="showhuerotate"></span>deg)</span><input id="sex" type="range" value="0" onchange="document.getElementById('showhuerotate').innerHTML=value" max="360"/> <script> var tup = document.getElementById("tiimg"); var blur=0;var hbxg=0;var hjxg=0;var fans=0;var tmxg=0;var baohd=0;var sex=0; // 高斯模糊 document.getElementById("gaosi").addEventListener("input",function() { blur=this.value; flisd(); }); //黑白效果 document.getElementById("heiba").addEventListener("input",function() { hbxg=this.value; flisd(); }); //怀旧效果 document.getElementById("huaij").addEventListener("input",function() { hjxg=this.value; flisd(); }); //反色效果 document.getElementById("fansx").addEventListener("input",function() { fans=this.value; flisd(); }); //透明效果 document.getElementById("toum").addEventListener("input",function() { tmxg=this.value; flisd(); }); //饱和效果 document.getElementById("baof").addEventListener("input",function() { baohd=this.value; flisd(); }); //色相 document.getElementById("sex").addEventListener("input",function() { sex=this.value; flisd(); }); function flisd(){ if(baohd==0){baohd=2;} tup.style.filter="blur("+blur+"px) grayscale("+hbxg+"%) sepia("+hjxg+"%) invert("+fans+"%) opacity("+(100-tmxg)+"%) saturate("+baohd*50+"%) hue-rotate("+sex+"deg)"; } </script> </body> </html> |
更多属性请查看官方文档尝试: from:https://blog.csdn.net/josiecici/article/details/127629212
View Details1、Java中拷贝的概念 在Java语言中,拷贝一个对象时,有浅拷贝与深拷贝两种 浅拷贝:只拷贝源对象的地址,所以新对象与老对象共用一个地址,当该地址变化时,两个对象也会随之改变。 深拷贝:拷贝对象的所有值,即使源对象发生任何改变,拷贝的值也不会变化。 在User类的基础上,介绍两种浅拷贝案列 User类:
1 2 3 4 5 |
@Data public class User { private String name; private Integer age; } |
案列①:普通对象的浅拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.shuizhu.study; //浅拷贝案例1 public class Study01 { public static void main(String[] args) { User user1 = new User(); user1.setName("张三"); user1.setAge(18); User user2 = user1; System.out.println("user1未改变前,user2的名字为:" + user2.getName()); user1.setName("李四"); System.out.println("user1未改变前,user2的名字为:" + user2.getName()); } } |
结果:改变user1后,user2的值也随之变化 案列②:List浅拷贝(这也是我们平时项目中,经常遇到的情况)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
package com.shuizhu.study; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; //Java浅拷贝案列2 public class Study02 { public static void main(String[] args) { List<User> list1 = new ArrayList<>(); User user1 = new User(); user1.setName("张三"); user1.setAge(18); User user2 = new User(); user2.setName("李四"); user2.setAge(19); list1.add(user1); list1.add(user2); //TODO 以下是开发中,经常发生的浅拷贝 //方式1:通过new ArrayList方式,把list01拷贝给list02 List<User> list2 = new ArrayList<>(list1); System.out.println("list1未改变前,list2的结果为:" + list2); //方式2:通过addAll方法,把list01拷贝给list02 List<User> list3 = new ArrayList<>(); list3.addAll(list1); System.out.println("list1未改变前,list3的结果为:" + list3); //方式3:通过stream流的方式,把list01拷贝给list02 List<User> list4 = list1.stream().collect(Collectors.toList()); System.out.println("list1未改变前,list4的结果为:" + list4); //改变list1集合中的user1对象 System.out.println("--------------------------------------------"); user1.setName("老六"); user1.setAge(78); System.out.println("list1改变后,list2的结果为:" + list2); System.out.println("list1改变后,list3的结果为:" + list3); System.out.println("list1改变后,list4的结果为:" + list4); } } |
结果:对List的3种拷贝,其实都是浅拷贝,当源集合中对象发生改变时,新的List也会随之变化 2、常见的深拷贝方式 构造函数方式(new的方式) 重写clone方法 Apache Commons Lang序列化 Gson序列化 Jackson序列化 2.1、构造函数方式 这种方式就是创建一个新的对象,然后通过源对象的get方法与新对象set方法,把源对象的值复制新对象,这里就不再演示了。 缺点:在拷贝的对象数量较少时,可以使用,但是对象数量过多时,会大大增加系统开销,开发中应避免使用。 2.2、重写clone方法 步骤: 1>需要拷贝对象的类,去实现Cloneable接口 2>重写clone方法 3>使用"对象.clone()"的方式进行拷贝 根据上面的案列,进行对应的改造: 首先是User实体类 ,如下:
1 2 3 4 5 6 7 8 9 10 |
@Data public class User implements Cloneable{ private String name; private Integer age; @Override protected User clone() throws CloneNotSupportedException { return (User) super.clone(); } } |
改造案列①:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.shuizhu.study; //Java深拷贝案列 public class Study03 { public static void main(String[] args) throws CloneNotSupportedException { User user1 = new User(); user1.setName("张三"); user1.setAge(18); User user2 = user1.clone(); System.out.println("user1未改变前,user2的名字为:" + user2.getName()); user1.setName("李四"); System.out.println("user1未改变前,user2的名字为:" + user2.getName()); } } |
结果:当user1改变后,user2的值不会改变 改造案列②:List类型深拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
package com.shuizhu.study; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; //Java深拷贝案列 public class Study04 { public static void main(String[] args) { List<User> list1 = new ArrayList<>(); User user1 = new User(); user1.setName("张三"); user1.setAge(18); User user2 = new User(); user2.setName("李四"); user2.setAge(19); list1.add(user1); list1.add(user2); / //通过clone方式,把list01拷贝给list02 List<User> list2 = new ArrayList<>(); //TODO 当数据量多时,建议使用对象的方式,把List当做属性,然后拷贝哦到一个新的对象中,从而不需要循环,可以见Apache Commons Lang序列化深拷贝方式 list1.forEach(user->{ try { list2.add(user.clone()); } catch (CloneNotSupportedException e) { e.printStackTrace(); } }); System.out.println("list1未改变前,list2的结果为:" + list2); //改变list1集合中的user1对象 System.out.println("--------------------------------------------"); user1.setName("老六"); user1.setAge(78); System.out.println("list1改变后,list2的结果为:" + list2); } } |
结果:list1中的每个对象通过clone()添加list2中,当list1中的对象改变时,list2不会改变 2.3 、Apache Commons Lang序列化 步骤: 1>导入Commons包
1 2 3 4 5 |
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3:3.5</version> </dependency> |
2>实体类实现Serializable接口
1 2 3 4 5 |
@Data public class User implements Serializable { private String name; private Integer age; } |
3>调用SerializationUtils工具类,实现深拷贝(注意:SerializationUtils不能直接拷贝List类型) 案列如下: 案列①:对象深拷贝
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.shuizhu.study2; import org.apache.commons.lang3.SerializationUtils; //Apache Commons Lang序列化实现对象的深拷贝 public class Study01 { public static void main(String[] args) { User user1 = new User(); user1.setName("张三"); user1.setAge(18); User user2 = SerializationUtils.clone(user1); System.out.println("user1未改变前,user2的名字为:" + user2.getName()); user1.setName("李四"); System.out.println("user1改变后,user2的名字为:" + user2.getName()); } } |
结果:user1的改变不会导致user2的改变,从而实现深拷贝 案列②:List类型深拷贝 (1)改造开始,我们先创建一个专门用于拷贝List<User>类型的实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.shuizhu.study2; import java.io.Serializable; import java.util.List; /** * @author 睡竹 * @date 2022/12/10 * 用于深拷贝时,不需要去遍历List<User>集合,只需要拷贝UserCopyDTO 对象就可以 * 获取到新的List<User>集合 */ @Data public class UserCopyDTO implements Serializable {//必须实现Serializable接口 private List<User> users; } |
(2)拷贝List类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
package com.shuizhu.study2; import org.apache.commons.lang3.SerializationUtils; import java.util.ArrayList; import java.util.List; //Apache Commons Lang序列化实现List的深拷贝 public class Study02 { public static void main(String[] args) { List<User> list1 = new ArrayList<>(); User user1 = new User(); user1.setName("张三"); user1.setAge(18); User user2 = new User(); user2.setName("李四"); user2.setAge(19); list1.add(user1); list1.add(user2); //使用UserCopyDTO对象,专门用于拷贝List<User>类型数据,不需要再去遍历list1 UserCopyDTO userCopyDTO = new UserCopyDTO(); userCopyDTO.setUsers(list1); //通过Apache Commons Lang序列化方式,把list01拷贝给list02 UserCopyDTO clone = SerializationUtils.clone(userCopyDTO); List<User> list2 = clone.getUsers(); System.out.println("list1未改变前,list2的结果为:" + list2); //改变list1集合中的user1对象 System.out.println("--------------------------------------------"); user1.setName("老六"); user1.setAge(78); System.out.println("list1改变后,list2的结果为:" + list2); } } |
结果: 2.4、Gson序列化 步骤: 1、导入Gson依赖
1 2 3 4 5 |
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency> |
2>创建Gson对象,使用该对象进行深拷贝(实体类不再需要实现Serializable接口) 案例如下:只演示对象的深拷贝,LIst类型的深拷贝与之前的流程是相似的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.shuizhu.study3; import com.google.gson.Gson; //Gson序列化实现对象的深拷贝 public class Study01 { public static void main(String[] args) { User user1 = new User(); user1.setName("张三"); user1.setAge(18); Gson gson = new Gson(); User user2 = gson.fromJson(gson.toJson(user1), User.class); System.out.println("user1未改变前,user2的名字为:" + user2.getName()); user1.setName("李四"); System.out.println("user1改变后,user2的名字为:" + user2.getName()); } } |
重点: 结果: 2.5、Jackson序列化 该方式与Gson原理、使用方式相似,但是Jackson序列化深拷贝,要求拷贝的对象必须有无参构造函数 步骤: 1>导入Jackson依赖
1 2 3 4 5 6 7 8 9 10 |
<dependency> <groupId>com.fasterxml.jackson</groupId> <artifactId>core</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson</groupId> <artifactId>databind</artifactId> <version>2.2.2</version> </dependency> |
2>创建ObjectMapper对象,进行深拷贝(用法与Gson一致) […]
View Details返回json 首字母大写、时间格式、空值等问题 处理 在Startup 中 public void ConfigureServices(IServiceCollection services) 函数加入以下代码
1 2 3 4 5 6 7 8 9 10 11 |
services.AddControllers().AddNewtonsoftJson(options => { // 忽略循环引用 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // 不使用驼峰 options.SerializerSettings.ContractResolver = new DefaultContractResolver(); // 设置时间格式 options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; // 如字段为null值,该字段不会返回到前端 // options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; }); |
from:https://blog.csdn.net/oopxiajun2011/article/details/104874062/
View Details