动态发布接口
发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,动态发布接口HTTP接口分为REST和SOAP2种方式,文中都涉及到,包含从动态生成文件到编译class再到装载到spring容器和ws.Endpoint中。REST风格方案:1.提供java文件模板
千家信息网最后更新 2025年12月02日动态发布接口
动态发布接口
HTTP接口分为REST和SOAP2种方式,文中都涉及到,包含从动态生成文件到编译class再到装载到spring容器和ws.Endpoint中。
REST风格
方案:
1.提供java文件模板
2.读取文件内容
3.查库修改生成java文件
4.通过JDK中的javax.tools.JavaCompiler动态编译成class
5.通过继承java.net.URLClassLoader动态加载class文件到内存
6.通过获取spring的ApplicationContext手动把mapping注册到RequestMappingHandlerMapping中完成动态发布
过程:
1.模板文件根据业务自行配置(涉及公司机密,忽略)
2.读取文件内容,生成java文件,编译class,加载class,发布接口
//动态创建接口 @Override public Boolean createGenerate(String serviceName,Long interfaceId,String structrue) { try { //首字母大写 serviceName = StringUtils.firstCharUpper(serviceName); //目录路径 Path directoryPath = Paths.get(outDirectory); // 如果目录不存在 if (!Files.exists(directoryPath)) { //创建目录 Files.createDirectories(directoryPath); } String controllerJava = serviceName + "Controller.java"; String autoJavaFile = outDirectory + controllerJava; //文件路径 Path filePath = Paths.get(autoJavaFile); if (!Files.exists(filePath)) { //创建文件 Files.createFile(filePath); } else { logger.error("动态创建接口错误,文件已存在:"+autoJavaFile); return false; } // 读取模板文件流 String javaFile = directory + "RestTemplateController.java"; String content = FileUtils.readFile(javaFile); //替换文件 content = replaceJava(content, serviceName, interfaceId,structrue); //写入文件 Files.write(filePath, content.getBytes(charsetName)); String fullName = packageName + serviceName + "Controller"; //动态编译class JavaStringCompiler compiler = new JavaStringCompiler(); Map results = compiler.compile(controllerJava, content); //加载class Class> clzMul = compiler.loadClass(fullName, results); //获取spring的applicationContext ApplicationContext applicationContext = SpringContextHelper.getApplicationContext(); //注册接口到注册中心 MappingRegulator.controlCenter(clzMul, applicationContext, create); } catch (Exception e) { logger.error("动态创建接口错误",e); return false; } return true; } /** * controlCenter(运行时RequestMappingHandlerMapping中添加、删除、修改Mapping接口) * @param Class 希望加载的类Class * @param ApplicationContext spring上下文 * @param type 1新增 2修改 3删除 * @throws Exception * @throws IllegalAccessException * @Exception 异常对象 * @since CodingExample Ver(编码范例查看) 1.1 * @author jiaxiaoxian */ public static void controlCenter(Class> controllerClass,ApplicationContext Context,Integer type) throws IllegalAccessException, Exception{ //获取RequestMappingHandlerMapping RequestMappingHandlerMapping requestMappingHandlerMapping=(RequestMappingHandlerMapping) Context.getBean("requestMappingHandlerMapping"); Method getMappingForMethod =ReflectionUtils.findMethod(RequestMappingHandlerMapping.class, "getMappingForMethod",Method.class,Class.class); //设置私有属性为可见 getMappingForMethod.setAccessible(true); //获取类中的方法 Method[] method_arr = controllerClass.getMethods(); for (Method method : method_arr) { //判断方法上是否有注解RequestMapping if (method.getAnnotation(RequestMapping.class) != null) { //获取到类的RequestMappingInfo RequestMappingInfo mappingInfo = (RequestMappingInfo) getMappingForMethod.invoke(requestMappingHandlerMapping, method,controllerClass); if(type == 1){ //注册 registerMapping(requestMappingHandlerMapping, mappingInfo, controllerClass, method); }else if(type == 2){ //取消注册 unRegisterMapping(requestMappingHandlerMapping, mappingInfo); registerMapping(requestMappingHandlerMapping, mappingInfo, controllerClass, method); }else if(type == 3){ unRegisterMapping(requestMappingHandlerMapping, mappingInfo); } } } } /** * * registerMapping(注册mapping到spring容器中) * @param requestMappingHandlerMapping * @Exception 异常对象 * @since CodingExample Ver(编码范例查看) 1.1 * @author jiaxiaoxian */ public static void registerMapping(RequestMappingHandlerMapping requestMappingHandlerMapping,RequestMappingInfo mappingInfo, Class> controllerClass, Method method) throws Exception, IllegalAccessException{ requestMappingHandlerMapping.registerMapping(mappingInfo, controllerClass.newInstance(),method); } /** * * unRegisterMapping(spring容器中删除mapping) * @param requestMappingHandlerMapping * @Exception 异常对象 * @since CodingExample Ver(编码范例查看) 1.1 * @author jiaxiaoxian */ public static void unRegisterMapping(RequestMappingHandlerMapping requestMappingHandlerMapping,RequestMappingInfo mappingInfo) throws Exception, IllegalAccessException{ requestMappingHandlerMapping.unregisterMapping(mappingInfo); } 结果:
可以正常发布spring接口,动态生成文件注入mapping到spring接口中。
SOAP风格
方案:
1.提供java文件模板
2.读取文件内容
3.查库修改生成java文件
4.通过JDK中的javax.tools.JavaCompiler动态编译成class
5.通过继承java.net.URLClassLoader动态加载class文件到内存
6.通过javax.xml.ws.Endpoint的publish动态发布接口
过程:
1.模板文件根据业务自行配置(涉及公司机密,忽略)
2.读取文件内容,生成java文件,编译class,加载class,通过Endpoint发布接口
@Override public Boolean createGenerate(String serviceName, Long interfaceId, String structrue) { try { serviceName = StringUtils.firstCharUpper(serviceName); Path directoryPath = Paths.get(outDirectory); // 如果文件不存在 if (!Files.exists(directoryPath)) { Files.createDirectories(directoryPath); } String controllerJava = serviceName + "Controller.java"; String autoJavaFile = outDirectory + controllerJava; Path filePath = Paths.get(autoJavaFile); if (!Files.exists(filePath)) { Files.createFile(filePath); } else { logger.error("动态创建接口错误ws,文件已存在:" + autoJavaFile); return false; } String wsJavaFile = directory + "JwsTemplateController.java"; String content = FileUtils.readFile(wsJavaFile); content = replaceJava(content, serviceName, interfaceId, structrue); Files.write(filePath, content.getBytes(charsetName)); String fullName = packageName + serviceName + "Controller"; JavaStringCompiler compiler = new JavaStringCompiler(); Map results = compiler.compile(controllerJava, content); Class> clzMul = compiler.loadClass(fullName, results); publish(clzMul, serviceName); } catch (Exception e) { logger.error("动态创建接口错误ws", e); return false; } return true; } //动态发布接口 private void publish(Class> clzMul, String serviceName) throws Exception { serviceName = firstCharLower(serviceName); Endpoint endpoint = Endpoint.create(clzMul.newInstance()); endpoint.publish(wsDomain + serviceName); //redisUtil.set(serviceName, endpoint); endpointMap.put(serviceName, endpoint); } 结果:
可以正常发布SOAP接口,动态生成文件发布SOAP接口。
后面附件会上传动态生成需要的工具类,需要的小伙伴可以下载,记得好评!
author:贾小仙
time:2018/9/5
文件
动态
接口
生成
编译
模板
内容
错误
容器
对象
目录
编码
范例
业务
公司
内存
方案
方法
机密
结果
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
含能共晶数据库
内蒙古态势推演系统软件开发
华为针对网络安全会议的讲话
桓台物流竞价报价软件开发咨询
中国互联网科技含量
餐饮数据库链接
服务器oracle怎么查用户名
交警举报系统软件开发
政治新闻网络安全
鸿蒙软件开发计算器
看好网络安全概念股
科奥科技有限公司互联网
快迅云服务器怎么了
浦东新区网络技术开发热线
上海玄清软件开发
预防中小学生网络安全家长
贵阳服务器备份一体机厂家
软件开发和测试工作的区别
计算机网络技术习题基础
陕西暖爱互联网科技有限公司
十大院士共同揭幕网络安全会
网络安全是否需要法律法规
国网公司网络安全案例
王牌战争高手最多的服务器
手机连接服务器超时要怎么解决
沈明航 网络安全
公司加强网络安全管理
数据库 创建列不为 负数
广州金融软件开发小公司
关闭数据库释放资源命令