千家信息网

动态发布接口

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,动态发布接口HTTP接口分为REST和SOAP2种方式,文中都涉及到,包含从动态生成文件到编译class再到装载到spring容器和ws.Endpoint中。REST风格方案:1.提供java文件模板
千家信息网最后更新 2026年11月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安全错误 数据库的锁怎样保障安全 互联网与科技 亿人帮互联网科技有限公司 广东猪兼强互联网科技有限公司 互联网和科技创新 远拓互联网科技 深圳齐家互联网科技 互联网科技大会 现代科技和互联网有关系吗 福州新华互联网科技学校 知乎 互联网还是高科技吗 花神(南京)互联网科技有限公司 互联网与医疗科技 移动互联网年度科技创新 互联网在线教育科技创业 阿里互联网科技企业 锡山区互联网智能科技产品供应 每天都有哪些好的互联网科技 电子商务与互联网科技的关系 陕西云淼互联网科技公司 互联网高科技行业有哪些企业 咖啡 互联网金融公司科技 青岛互联网科技公司 无锡溥仪互联网科技有限公司 银川新华互联网科技职业技术培训学校图片 河南猎农互联网科技有限公司 宝灵互联网科技有限公司 青岛科技大学互联网大赛研究生 上海乐五互联网科技有限公司 银川新华互联网科技学校招聘
0