2024-05-25
温故知新
00

问题始末

学习Nacos配置启动,用的Windows,部署集群刚开始用的8846-8847-8848三个端口,结果8847一直报端口占用,cmd查看端口并没有被占用。把88468848都停掉后,就没占用了,但是如果先启动884788468848都起不来了。。。。刚开始以为不能用同一台机器部署集群,但是百度很多都是用同一个电脑测试的集群,把8847端口改成8850就可以了,越想越奇怪,我又增加了个8847,结果还是不行,把8847改成8844又可以了。。。。。

不知道这是不是个官方Bug,记录一下吧。有懂的大佬欢迎指点解答~~

PS:后来知道是官方的设定导致的。。文末有答案。。

  • 说明:所有节点使用的是同一套文件,只进行了配置文件(application.propertiescluster.conf)的修改!Nacos版本2.0.3
2024-05-25
温故知新
00

直接上源码(注释很清晰)

代码内含有测试main方法,可直接复制运行。

java
package top.oldmoon.api.compiler; import com.itranswarp.compiler.JavaStringCompiler; import lombok.extern.slf4j.Slf4j; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; /** * @Description java编译器工具类 * @Author dingdangdog * @Date 2021/8/25 16:38 */ @Slf4j public class CompilerUtilOm { /** * 动态编译 * * @param className 类名 * @param packageName 包名 * @param classSource 类源码 * @return java.lang.Class * @author dingdangdog * @date 2021/8/26 10:08 */ public static Class compiler(String className, String packageName, String classSource) throws IOException, ClassNotFoundException { String fullName = packageName + "." + className; // 编译器 JavaStringCompiler compiler = new JavaStringCompiler(); Map<String, byte[]> javaFile = compiler.compile(className + ".java", classSource); // 加载内存中byte到Class<?>对象 Class<?> clazz = compiler.loadClass(fullName, javaFile); return clazz; } /** * 反射获取类实例 * * @param clazz 类 * @return java.lang.Object * @author dingdangdog * @date 2021/8/26 10:06 */ public static Object newInstance(Class clazz) throws InstantiationException, IllegalAccessException { // 类实例化 Object object = clazz.newInstance(); return object; } /** * 通过反射,获取想要的方法 * * @param clazz 方法持有类 * @param methodName 方法名 * @param paramTypes ... 方法参数类(可以传入多个参数类) * @return java.lang.reflect.Method * @author dingdangdog * @date 2021/8/26 10:05 */ public static Method getMethod(Class clazz, String methodName, Class... paramTypes) throws NoSuchMethodException { Method method = clazz.getMethod(methodName, paramTypes); return method; } /** * 反射方法执行 * * @param method 方法实例 * @param object 方法持有者实例 * @param param ... 方法参数(可以传入多个参数) * @return java.lang.Object * @author dingdangdog * @date 2021/8/26 10:01 */ public static Object invokeMethod(Method method, Object object, Object... param) throws IllegalAccessException, InvocationTargetException { try { return method.invoke(object, param); } catch (IllegalAccessException | InvocationTargetException e) { log.error("++++++++++++++++++++{}方法执行出错++++++++++++++++++++", method.getName()); e.printStackTrace(); } return null; } public static void main(String[] args) throws Exception { // 传入String类型的代码 String source = "package oldmoon.api.compiler;" + "import java.util.Arrays;" + "public class Main {" + "public static String test(String[] args, String test) {" + "System.out.println(Arrays.toString(args));" + "System.out.println(test);" + "return \"testReturn\";" + "}" + "}"; String[] param = new String[]{"1", "2", "3"}; String test = new String("test"); try { // 编译字节码对象 Class mainClazz = CompilerUtilOm.compiler("Main", "oldmoon.api.compiler", source); // 实例化对象 Object mainObject = CompilerUtilOm.newInstance(mainClazz); // 反射获取方法 Method mainMethod = CompilerUtilOm.getMethod(mainClazz, "test", param.getClass(), test.getClass()); // 执行方法,获取返回值 Object result = CompilerUtilOm.invokeMethod(mainMethod, mainObject, param, test); // 输出返回值 System.out.println(result); } catch (IOException | ClassNotFoundException e) { log.error("++++++++++++++++++++动态编译出错++++++++++++++++++++"); e.printStackTrace(); } catch (InstantiationException e) { log.error("++++++++++++++++++++实例化出错++++++++++++++++++++"); e.printStackTrace(); } catch (NoSuchMethodException e) { log.error("++++++++++++++++++++反射获取方法出错++++++++++++++++++++"); e.printStackTrace(); } catch (IllegalAccessException e) { log.error("++++++++++++++++++++反射实例化出错 || 反射执行方法出错++++++++++++++++++++"); e.printStackTrace(); } catch (InvocationTargetException e) { log.error("++++++++++++++++++++反射执行方法出错++++++++++++++++++++"); e.printStackTrace(); } catch (Exception e) { log.error("++++++++++++++++++++未知错误++++++++++++++++++++"); e.printStackTrace(); } } }
2024-05-25
温故知新
00

springboot启动类剔除扫描某个包

java
// 排除api中不引数据库导致的报错包 @ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.REGEX,pattern = "top.oldmoon.aop.log.service.*") })

通过该注解配置,可以实现剔除某个包,让Spring不自动扫描该包下的内容。

适用于依赖api或者其他包时,一些不必要或不支持的对象被扫描到,引发的报错或内存占用等问题。通过该配置可以去掉这些不必要的扫描。

2024-05-25
温故知新
00

Java正则--地址结构化解析

java
public static Map<String, String> addressResolution(String address) { String regex = "(?<province>.*?自治区|.*?省|.*?行政区|.*?市)(?<city>.*?自治州|.*?地区|.*?行政单位|市辖区|.*?市)?(?<county>.*?市|.*?县|.*?区)?(?<village>.*)"; Matcher m = Pattern.compile(regex).matcher(address); String province, city, county, village; Map<String, String> row = null; while (m.find()) { row = new LinkedHashMap<>(); province = StringUtils.isNotBlank(m.group("province")) ? m.group("province").trim() : ""; row.put("province", StringUtils.isEmpty(province) ? address : province); city = StringUtils.isNotBlank(m.group("city")) ? m.group("city").trim() : ""; row.put("city", StringUtils.isEmpty(city) ? province : city); county = StringUtils.isNotBlank(m.group("county")) ? m.group("county").trim() : ""; row.put("county", StringUtils.isEmpty(county) ? city : county); village = StringUtils.isNotBlank(m.group("village")) ? m.group("village").trim() : ""; row.put("village", StringUtils.isEmpty(village) ? county : village); } if (row == null) { row = new LinkedHashMap<>(); row.put("village", address); } return row; } public static void main(String[] args) { System.out.println(addressResolution("山东省潍坊市昌邑市龙源国际小区")); }
2024-05-25
温故知新
00

问题

通过传统的 form 表单提交的方式上传文件

html
<form id="uploadForm" action="" method="post" enctype="multipart/form-data">        <p>上传文件:<input type ="file" name="file"/></p>        <input type="submit" value="上传"/>   </form>

不过传统的 form 表单提交会导致页面刷新,但是在有些情况下,我们不希望页面被刷新,这种时候我们都是使用 Ajax 的方式进行请求的。

使用 serialize() 对 form 表单进行序列化提交

javascript
$.ajax({        url: "",        type: "POST",        data: $('#uploadForm').serialize(),        success: function(data) {           },        error: function(data) {      }   });

如上,通过 $('#uploadForm').serialize() 可以对 form 表单进行序列化,从而将 form 表单中的所有参数传递到服务端。

但是上述方式,只能传递一般的参数,上传文件的文件流是无法被序列化并传递的。不过如今主流浏览器都开始支持一个叫做 FormData 的对象,有了这个对象就可以轻松地使用 Ajax 方式进行文件上传了。