动态发布接口
发表于:2025-02-06 作者:千家信息网编辑
千家信息网最后更新 2025年02月06日,动态发布接口HTTP接口分为REST和SOAP2种方式,文中都涉及到,包含从动态生成文件到编译class再到装载到spring容器和ws.Endpoint中。REST风格方案:1.提供java文件模板
千家信息网最后更新 2025年02月06日动态发布接口
动态发布接口
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(); Mapresults = 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(); Mapresults = 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数据库集群
软件开发从事前端好吗
上海恰当网络技术中心
阿里云免费服务器邀请码
数据库中字段名词解释
保定3s双创软件开发
战地1怎么做服务器
无线网络安全的设置在哪里
网络数据库有哪些种类
马鞍山h3c塔式服务器
牛客网 网络安全
初学网络技术看什么书
非关系数据库 子表和表