4.Spring注解方式校验前端输入

例如将前端传值封装为实体类public class User { private String name; private Integer age; private String phone;}传统方式使用if判断,麻烦并且参数过多需要写很多代码,使用Spring注解public class User { @NotNull(message = "传入姓名不能为NULL") @NotEmpty(message = "传入姓名不能为空") private String name; @Min(value = 1, message = "传入年龄需大于1") private Integer age; @Length(min = 11, max = 11, message = "手机号需11位") private String phone;}于此同时,我们还需要在对象入口处,加上注解 @Valid来开启对传入 Student对象的验证˂img src=https://gitee.com/cwayteam/blog/raw/master/image/2021/01/28/64820_59b2cd740e51ac387cb5dd2c00c7786477cf4fc8.png@1320w_442h.png alt="59b2cd740e51ac387cb5dd2c00c7786477cf4fc8.png@1320w_442h"˃为项目配置全局统一异常拦截器来格式化所有数据校验的返回结果˂img src=https://gitee.com/cwayteam/blog/raw/master/image/2021/01/28/37224_2f3d31fd54e2c08944a28c9644ed37d2dee296d3.png@1320w_506h.png alt="2f3d31fd54e2c08944a28c9644ed37d2dee296d3.png@1320w_506h"˃如上面代码所示,我们全局统一拦截了参数校验异常 MethodArgumentNotValidException,并仅仅只拿到对应异常的详细 Message信息吐给前端,此时返回给前端的数据就清楚得多

4.Spring注解方式校验前端输入

Java获取本机ipv4/ipv6地址

Java获取本机ip地址/ipv6地址,非用户请求返回的IP try { String hostAddress = InetAddress.getLocalHost().getHostAddress(); System.out.println("hostAddress:" + hostAddress); String hostName = InetAddress.getLocalHost().getHostName(); System.out.println("hostName:" + hostName); if (hostName.length() > 0) { InetAddress[] addrs = InetAddress.getAllByName(hostName); if (addrs.length > 0) { for (int i = 0; i < addrs.length; i++) { InetAddress address = addrs[i]; System.out.println("**********************"); System.out.println(address.getHostAddress()); if (address instanceof Inet6Address) { System.out.println("true6"); } else if(address instanceof Inet4Address){ System.out.println("true4"); } else { System.out.println("unknown"); } System.out.println("**********************"); } } } } catch (UnknownHostException e) { e.printStackTrace(); }或者 Enumeration<NetworkInterface> interfs = NetworkInterface.getNetworkInterfaces(); while (interfs.hasMoreElements()) { NetworkInterface interf = interfs.nextElement(); Enumeration<InetAddress> addres = interf.getInetAddresses(); while (addres.hasMoreElements()) { InetAddress in = addres.nextElement(); if (in instanceof Inet4Address) { System.out.println("v4:" + in.getHostAddress()); } else if (in instanceof Inet6Address) { System.out.println("v6:" + in.getHostAddress()); } } }参考:https://blog.csdn.net/scugxl/article/details/47816117

Springboot定时任务的使用

Springboot定时任务的使用Spring提供了@Scheduled注解用于定时任务。也就是说一般需求可以无需第三方定时任务。开启定时任务启动类加@EnableScheduling开启定时任务@SpringBootApplication@EnableScheduling //开启定时任务public class MainApplication { public static void main(String[] args) { SpringApplication.run(MainApplication.class, args); }}执行方法@Componentpublic class Jobs { //表示方法执行完成后5秒 @Scheduled(fixedDelay = 5000) public void fixedDelayJob() throws InterruptedException { System.out.println("fixedDelay 每隔5秒" + new Date()); } //表示每隔3秒 @Scheduled(fixedRate = 3000) public void fixedRateJob() { System.out.println("fixedRate 每隔3秒" + new Date()); } //表示每天8时30分0秒执行 @Scheduled(cron = "0 0,30 0,8 ? * ? ") public void cronJob() { System.out.println(new Date() + " ...>>cron"); }}第三种使用cron表达式可上网搜在线cron表达式,选择时间会自动生成,cron说明* 第一位,表示秒,取值0-59* 第二位,表示分,取值0-59* 第三位,表示小时,取值0-23* 第四位,日期天/日,取值1-31* 第五位,日期月份,取值1-12* 第六位,星期,取值1-7,星期一,星期二...,注:不是第1周,第二周的意思 另外:1表示星期天,2表示星期一。* 第7为,年份,可以留空,取值1970-2099(*)星号:可以理解为每的意思,每秒,每分,每天,每月,每年...(?)问号:问号只能出现在日期和星期这两个位置。(-)减号:表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12(,)逗号:表达一个列表值,如在星期字段中使用“1,2,4”,则表示星期一,星期二,星期四(/)斜杠:如:x/y,x是开始值,y是步长,比如在第一位(秒) 0/15就是,从0秒开始,每15秒,最后就是0,15,30,45,60 另:*/y,等同于0/y举例0 0 3 * * ? 每天3点执行0 5 3 * * ? 每天3点5分执行0 5 3 ? * * 每天3点5分执行,与上面作用相同0 5/10 3 * * ? 每天3点的 5分,15分,25分,35分,45分,55分这几个时间点执行0 10 3 ? * 1 每周星期天,3点10分 执行,注:1表示星期天 0 10 3 ? * 1#3 每个月的第三个星期,星期天 执行,#号只能出现在星期的位置开启异步任务在类上加@EnableAsync注解@SpringBootApplication@EnableScheduling //开启定时任务@EnableAsync //开启异步public class MainApplication { public static void main(String[] args) { SpringApplication.run(MainApplication.class, args); }}异步执行,很简单在方法上加@Async注解即可 @Async @Scheduled(cron = "0 0,30 0,8 ? * ? ") public void cronJob() { System.out.println(new Date() + " ...>>cron"); }基于接口以上基于注解可能不灵活,有时将cron表达式存储在数据库就无法执行了,可以使用接口实现。依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.0.4.RELEASE</version> </parent> <dependencies> <dependency><!--添加Web依赖 --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><!--添加MySql依赖 --> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency><!--添加Mybatis依赖 配置mybatis的一些初始化的东西--> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency> <dependency><!-- 添加mybatis依赖 --> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> <scope>compile</scope> </dependency> </dependencies>执行本地MySQL创建表且插入一条数据DROP DATABASE IF EXISTS `socks`;CREATE DATABASE `socks`;USE `SOCKS`;DROP TABLE IF EXISTS `cron`;CREATE TABLE `cron` ( `cron_id` varchar(30) NOT NULL PRIMARY KEY, `cron` varchar(30) NOT NULL );INSERT INTO `cron` VALUES ('1', '0/5 * * * * ?');具体代码:@Component@Configuration //1.主要用于标记配置类,兼备Component的效果。@EnableScheduling // 2.开启定时任务public class DynamicScheduleTask implements SchedulingConfigurer { @Mapper public interface CronMapper { @Select("select cron from cron limit 1") public String getCron(); } @Autowired //注入mapper @SuppressWarnings("all") CronMapper cronMapper; /** * 执行定时任务. */ @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.addTriggerTask( //1.添加任务内容(Runnable) () -> System.out.println("执行动态定时任务: " + LocalDateTime.now().toLocalTime()), //2.设置执行周期(Trigger) triggerContext -> { //2.1 从数据库获取执行周期 String cron = cronMapper.getCron(); //2.2 合法性校验. if (StringUtils.isEmpty(cron)) { // Omitted Code .. } //2.3 返回执行周期(Date) return new CronTrigger(cron).nextExecutionTime(triggerContext); } ); }}参考:https://www.cnblogs.com/qdhxhz/p/9058418.htmlhttps://www.mmzsblog.cn/articles/2019/08/08/1565247960802.html

Java比较器Comparator进行排序及获取最大最小值

Java比较器Comparator使用/获取最大最小值Comparable:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法 被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序。实现 此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)进行自动排序,对象可以用作有序映射中 的键或有序集合中的元素,无需指定比较器。 Comparator:强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sort或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或 有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。Comparator使用 ArrayList<Integer> list = new ArrayList<Integer>();//采用工具类 完成 往集合中添加元素 Collections.addAll(list, 5, 222, 1, 2);//排序方法 Collections.sort(list);// 输出排序后值 第一个最小 末位最大 System.out.println(list);//[1, 2, 5, 222]//为对象排序 ArrayList<String> list1 = new ArrayList<String>(); list1.add("cba"); list1.add("abc"); list1.add("bca"); Collections.sort(list1, new Comparator<String>() { @Override// 第一个参数代表较小的 第二个较大 public int compare(String o1, String o2) { return o1.charAt(0) - o2.charAt(0); } });// Lamada改写 Collections.sort(list1, (o1, o2) -> o1.charAt(0) - o2.charAt(0)); Collections.sort(list1, Comparator.comparingInt(o -> o.charAt(0))); System.out.println(list1);//[abc, bca, cba]Comparable使用Student实体类import lombok.AllArgsConstructor;import lombok.Data;@Data@AllArgsConstructorpublic class Student implements Comparable<Student> { private String name; private int age; @Override public int compareTo(Student o) { return this.age - o.age;//升序 }}或者用if判断重写 @Override public int compareTo(Student o) { //升序 if (this.age > o.age) { return 1; } else if (this.age < o.age){ return -1; } else{ return 0; } }测试// 创建四个学生对象 存储到集合中 ArrayList<Student> list = new ArrayList<Student>(); list.add(new Student("rose", 18)); list.add(new Student("jack", 16)); list.add(new Student("mark", 16)); list.add(new Student("mona", 20));/*让学生 按照年龄排序 升序*/ Collections.sort(list);//要求 该list中元素类型 必须实现比较器Comparable接口 for (Student student : list) { System.out.println(student); }stream获取最大/小值ArrayList<Integer> list = new ArrayList<>();Collections.addAll(list, 2, 5, 3, 8, 7, 9);Integer max = list.stream().max(Integer::compare).get();Integer min = list.stream().min(Integer::compare).get();System.out.println("最大" + max + ",最小" + min); //最大9,最小2针对与于对象,例如上述Student获取最大年龄跟最小年龄ArrayList<Student> list = new ArrayList<Student>();list.add(new Student("rose", 18));list.add(new Student("jack", 16));list.add(new Student("mark", 16));list.add(new Student("bob", 27));list.add(new Student("mona", 20));Student max = list.stream().max(Student::compareTo).get();Student min = list.stream().min(Student::compareTo).get();System.out.println(max);System.out.println(min);但是如果没有继承Comparable接口重写compareTo的话,就得代码比较年龄了 ArrayList<Student> list = new ArrayList<Student>(); list.add(new Student("rose", 18)); list.add(new Student("jack", 16)); list.add(new Student("mark", 15)); list.add(new Student("bob", 27)); list.add(new Student("mona", 20));// 取最大年龄 这里同样用Comparator Student max = list.stream().max(new Comparator<Student>() { @Override public int compare(Student a, Student b) { if (a.getAge() > b.getAge()) { return 1; } else { return -1; } } }).get();// 取最小年龄 取较大值中最小值 这里也可以用max 不过就要将>改为< Student min = list.stream().min((a, b) -> { if (a.getAge() > b.getAge()) { return 1; } else { return -1; } }).get();// Lamada简写 Student max1 = list.stream().max((a, b) -> a.getAge()-b.getAge()).get(); Student max2 = list.stream().max(Comparator.comparingInt(Student::getAge)).get();// 若跟参数a b顺序不对应的话无法简写成comparingInt 但max这时就成取最小值; Student min1 = list.stream().max((a, b) -> b.getAge()-a.getAge()).get(); Student min2 = list.stream().min((a, b) -> a.getAge()-b.getAge()).get(); System.out.println(min); System.out.println(min1); System.out.println(min2); System.out.println(max); System.out.println(max1); System.out.println(max2);对double等类型比较在Student实体类中加入Double hign身高属性,直接调用Comparator.comparingDouble方法,或者直接使用Comparator.comparing也可以。// 打印最高的学生 Student studentMax = list.stream().max(Comparator.comparingDouble(Student::getHign)).get(); Student studentMin = list.stream().min(Comparator.comparingDouble(Student::getHign)).get(); System.out.println(studentMax); System.out.println(studentMin); Student studentMax1 = list.stream().max((a, b) -> { if (a.getHign() > b.getHign()) { return 1; } else { return -1; } }).get(); Student studentMin1 = list.stream().min((a, b) -> { if (a.getHign() > b.getHign()) { return 1; } else { return -1; } }).get(); System.out.println(studentMax1); System.out.println(studentMin1); Student studentMax2 = list.stream().max(Comparator.comparing(Student::getHign)).get(); System.out.println(studentMax2);当然了,也可以用sort进行排序,对于double也可以使用上述策略// 年龄从低到高 list.sort((a, b) -> a.getAge() - b.getAge()); System.out.println(list);// 身高升序 list.sort(Comparator.comparing(Student::getHign)); System.out.println(list);// 身高降序 简而言之就是o2.getHign()-o1.getHign()>0,但是compare方法只返回int,强制类型转换会导致不精准 list.sort(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { if (o1.getHign() < o2.getHign()) { return 1; } else { return -1; } } }); System.out.println(list);stream排序用sorted即可Stream<Student> asc = list.stream().sorted((a,b)->a.getAge()-b.getAge());asc = list.stream().sorted(Comparator.comparingInt(Student::getAge));Stream<Student> desc = list.stream().sorted((a,b)->b.getAge()-a.getAge());System.out.println(asc.collect(Collectors.toList()));System.out.println(desc.collect(Collectors.toList()));

解决idea创建springboot项目载入配置过慢问题

其实很简单,不使用默认的start.spring.io,而选择Custom,再填入阿里云的:https://start.aliyun.com即可

JAVA实现收发UDP请求

Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。发送import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;/* * 实现UDP协议的发送端: * 实现封装数据的类 java.net.DatagramPacket 将你的数据包装 * 实现数据传输类 java.net.DatagramSocket 将数据包发出去 * * 实现步骤: * 1.创建DatagramPacket对象,封装数据,接收的地址和端口 * 2.创建DatagramSocket对象, * 3.调用DatagramSocket类的方法send,发送数据包 * 4.关闭资源 * * DatagramPacket构造方法: * DatagramPacket(byte[] buf,int length,InetAddress address,int port) * * DatagramSocket构造方法: * DatagramSocket()空参数 * 方法:send(DatagramPacket d) * * */public class UDPSendTest { public static void main(String[] args) throws Exception {//创建发送端Socket对象 DatagramSocket ds = new DatagramSocket();//创建数据并打包 String s = "My name is happywindman"; byte[] bytes = s.getBytes(); int length = s.length(); InetAddress ip = InetAddress.getByName("127.0.0.1");//根据自己主机的ip地址或者主机名 int port = 10086; DatagramPacket dp = new DatagramPacket(bytes, length, ip, port);//发送数据 ds.send(dp);//释放资源 ds.close(); }}接收import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;/* * 实现UDP接收端 * 实现封装数据包java.net.DatagramPacket 将数据接收 * 实现输出传输 java.net.DatagramSocket 接受数据包 * * 实现步骤: * 1.创建DatagramSocket对象,绑定端口号 * 要和发送数据端口号一致 * 2.创建字节数组,接受发来的数组 * 3.创建数据包对象DatagramPacket * 4.调用DatagramSocket对象方法 receive(DatagramPacket dp) * 接受数据,数据放在数据包中 * 5.拆包 * 发送的IP地址 * 数据包对象DatagramPacket()方法getAddress()获取的是发送端的IP地址对象 * 接受到的字节个数 * 数据包对象DatagramPacket()方法getLength() * 发送方的端口号 * 数据包对象DatagramPacket()方法getPort() * 6.关闭资源 */public class UDPReceiveTest { public static void main(String[] args) throws Exception {//创建接收端Socket对象 DatagramSocket ds = new DatagramSocket(10086);//接收数据 byte[] bytes = new byte[1024]; int length = bytes.length; DatagramPacket dp = new DatagramPacket(bytes, length); ds.receive(dp); //解析数据 获取地址 带斜杠 InetAddress address = dp.getAddress(); //获取发送端的IP地址对象 String ip = address.getHostAddress(); //获取发送的端口号 int port = dp.getPort(); byte[] data = dp.getData(); int len = dp.getLength();//输出数据// System.out.println(address); System.out.println(String.format("发送方地址:%s:%s", ip, port)); System.out.println(new String(data, 0, len)); System.out.println(new String(bytes, 0, len)); ds.close(); }}

Java设置/获取系统剪切板/剪贴板

非常简单,调用jdk内部封装方法即可设置剪切板 public static void setClipboardString(String text) { // 获取系统剪贴板 Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); // 封装文本内容 Transferable trans = new StringSelection(text); // 把文本内容设置到系统剪贴板 clipboard.setContents(trans, null); }获取剪切板内容public String getFromClipboard() { Transferable transferable = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null); if (transferable != null && transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) { try { return (String) transferable.getTransferData(DataFlavor.stringFlavor); } catch (Exception e) { return ""; } } return "";}

Java获取本机本地IP地址

可显示本地IP,例如192.168.0.1public static InetAddress getLocalHostLANAddress() throws Exception { try { InetAddress candidateAddress = null; // 遍历所有的网络接口 for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) { NetworkInterface iface = (NetworkInterface) ifaces.nextElement(); // 在所有的接口下再遍历IP for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) { InetAddress inetAddr = (InetAddress) inetAddrs.nextElement(); if (!inetAddr.isLoopbackAddress()) {// 排除loopback类型地址 if (inetAddr.isSiteLocalAddress()) { // 如果是site-local地址,就是它了 return inetAddr; } else if (candidateAddress == null) { // site-local类型的地址未被发现,先记录候选地址 candidateAddress = inetAddr; } } } } if (candidateAddress != null) { return candidateAddress; } // 如果没有发现 non-loopback地址.只能用最次选的方案 InetAddress jdkSuppliedAddress = InetAddress.getLocalHost(); return jdkSuppliedAddress; } catch (Exception e) { e.printStackTrace(); } return null;}

对于selenium遍历元素获取text与html

示例 driver.get("http://zntx.cc/bbslist-2331.html"); List<WebElement> elements = driver.findElements(By.xpath("/html/body/div[1]/div")); for (int i = 0; i < elements.size(); i++) { WebElement element = elements.get(i); // 获取text 两种效果相同 System.out.println("getText"+element.getText()); System.out.println("innerText"+element.getAttribute("innerText"));// 获取html System.out.println("innerHTML"+element.getAttribute("innerHTML")); System.out.println(element.findElement(By.xpath("//*[@id=\"main\"]/div[5]/span[1]/a")).getAttribute("innerHTML")); }

两款不错的AI代码补全插件

https://www.codota.comhttps://www.aixcoder.com