WebService(9)_Apache CXF_CXFFrame_发布框架

如何为RK3588S定制Ubuntu系统镜像?一步步教你编译SDK(v1.0.6c版本) 本文详细介绍了如何为RK3588S处理器定制Ubuntu系统镜像,从SDK编译环境搭建到镜像优化全流程。涵盖v1.0.6c版本SDK的获取、解压、编译及高级定制技巧,包括内核模块调整、文件系统定制和固件打包优化,帮助开发者高效完成嵌入式系统开发。 阅读详情

CXFFrame 

封装CXF框架(发布平台),业务模块作为SDK插入平台


目的:

    1.封装WebService发布过程 

    2.对外发布一个WebService服务,即可包含不同的业务模块,统一入口/出口 参数类型

    3.WebService服务 与 业务模块代码 解耦

    4.业务组开发人员不用再关心WebService的发布,只要关注SDK业务模块的业务处理即可

    5.业务模块可插拔,更灵活


平台功能:

    1.发布WebService服务

    2.加载SDK业务模块程序

    3.加载SDK业务模块配置信息

    4.对传递的参数做基本校验功能

    5.SDK私有模块的实例化


CXFFrame平台源码已经上传GitHub,如果代码更新就在这个上面(优快云下载包不更新),地址:CXFFrame

CXFFrame Linux服务器安装包,地址:CXFFrame平台 模块SDK Linux安装包

CXFFrame平台-SDK源码,地址:CXFFrame平台-SDKDemo源码


在平台中有一个抽象类ServiceBase,SDK模块主类继承这个类之后,实现三个方法,分别是:(调用顺序也是以下顺序)

loadConfig(HashMap<String, String> configs):从平台中获取sdk私有模块配置信息

init():sdk私有模块参数/资源初始化

process(String params):sdk私有模块主方法


下面讲解下CXFFrame平台的代码:

cxfframe_conf.properties

#CXF发布端口
CXFFRAME_PORT=9099
#CXF发布服务名
CXFFRAME_RELEASE_NAME=CXFFrame_QueryService

这个是平台发布WebService的必要参数,这里只要指定发布名称和端口,平台默认读取安装机器的IP地址


cxfframe_log4j.properties

log4j.rootCategory=DEBUG,stdout
log4j.addivity.org.apache=true
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l - %m%n

log4j.logger.cxfframe=DEBUG,cxfframe
log4j.appender.cxfframe=org.apache.log4j.RollingFileAppender
log4j.appender.cxfframe.File=./log/cxfframe.log
log4j.appender.cxfframe.Threshold=DEBUG
log4j.appender.cxfframe.MaxBackupIndex=5
log4j.appender.cxfframe.MaxFileSize=1KB
log4j.appender.cxfframe.layout=org.apache.log4j.PatternLayout
log4j.appender.cxfframe.layout.ConversionPattern=%d %p %l - %m%n

log4j.logger.sample=DEBUG,sample
log4j.appender.sample=org.apache.log4j.RollingFileAppender
log4j.appender.sample.File=./log/sample.log
log4j.appender.sample.Threshold=DEBUG
log4j.appender.sample.MaxBackupIndex=5
log4j.appender.sample.MaxFileSize=1KB
log4j.appender.sample.layout=org.apache.log4j.PatternLayout
log4j.appender.sample.layout.ConversionPattern=%d %p %l - %m%n
这个是平台和sdk私有模块的log4j配置,当添加一个sdk后,需要在这个里面配置对应的logger配置。

这个配置是根据不同模块打印不同的地址信息。注意看模块名以及输出路径

平台加载log4j配置的时候,加入了log4j的监听器,支持动态修改log4j配置文件。


Modules.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!-- 配置模块SDK信息 -->
<modules>

	<!-- 模块名和class全路径 -->
	<!-- 注意,模块名必须与模块工程名(Linux模块名)完全一致 -->
	<module name="sample" class="com.module.sample.Sample" />
	<module name="gis" class="com.module.gis.GisServer" />

</modules>
这个是平台获取sdk主类的配置,每次添加sdk模块,都需要在这里加上对应的配置信息。

name 就是 sdk模块的名字,这个名字很重要,很多地方都要保持一直,比如说安装服务器后再modules目录下的目录名,以及客户端调用服务端传的模块名

class 就是 sdk模块的主类全路径


CommConstans.java

package com.cxfframe.server.common;

import com.cxfframe.server.util.CommonUtils;

/**
 * 常量
 *
 * @author CYX
 * @create 2017-05-24-21:41
 */
public class CommConstans {

    //判断相对路径根路径
    static {
        if (CommonUtils.isWindowsOS()) {
            SYSTEN_ROOT_PATH = "./";
        } else {
            SYSTEN_ROOT_PATH = "../";
        }
    }

    /**
     * 相对路径根路径
     * Windows(./) Linux(../)
     */
    public static String SYSTEN_ROOT_PATH;

    /**
     * CXFFrame配置文件路径
     */
    public static final String CXFFRAME_CONF_PATH = SYSTEN_ROOT_PATH + "conf/cxfframe_conf.properties";

    /**
     * CXFFrame_log4j配置文件路径
     */
    public static final String CXFFRAME_LOG4J_CONF_PATH = SYSTEN_ROOT_PATH + "conf/cxfframe_log4j.properties";

    /**
     * modules目录的路径
     */
    public static final String MODULES_DIR_PATH = SYSTEN_ROOT_PATH + "modules";

    /**
     * Modules.xml配置文件路径
     */
    public static final String MODULES_XML_PATH = SYSTEN_ROOT_PATH + "conf/Modules.xml";
}
这里配置的是成员变量,主要是平台配置文件的路径


ExceptionInfoConstans.java

package com.cxfframe.server.common;

/**
 * Exception错误信息
 *
 * @author CYX
 */
public class ExceptionInfoConstans {

    /**
     * moduleName和Params参数错误
     */
    public static final String MODULENAME_PARAMS_EXCEPTION = "[ErrorCode-01] Error information : Server receives the information , moduleName or params is null , please check it ";

    /**
     * moduleName找不到对应模块
     */
    public static final String MODULENAME_CLASS_EXCEPTION = "[ErrorCode-02] Error information : The server can not find the corresponding module";

    /**
     * 实例化模块错误
     */
    public static final String INSTANTIATE_MODULE_EXCEPTION = "[ErrorCode-03] Error information : Instantiate module error";

    /**
     * 服务端模块处理错误
     */
    public static final String SERVER_PROCESS_EXCEPTION = "[ErrorCode-04] Error information : Server module processing error";
}
这个配置的是平台/sdk处理异常后,返回给客户端的错误信息


KeyConstans.java

package com.cxfframe.server.common;

/**
 * 配置文件中的key常量
 *
 * @author CYX
 * @create 2017-05-24-22:15
 */
public class KeyConstans {

    public static final String CXFFRAME_PORT = "CXFFRAME_PORT";

    public static final String CXFFRAME_RELEASE_NAME = "CXFFRAME_RELEASE_NAME";


}
这里配置的是properties配置文件中的key,常量


QueryService.java

package com.cxfframe.server.inter;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

/**
 * Created by CYX on 2017/5/24.
 */
@WebService
public interface QueryService {

    @WebMethod
    String queryServerInformation(@WebParam(name = "ModuleName") String moduleName, @WebParam(name = "params") String params);

}
CXF发布的接口,这个不多说,使用过CXF或者WebService都知道,不了解的先去看之前的webService系列文章


QueryServiceImpl.java

package com.cxfframe.server.impl;

import com.cxfframe.server.common.ExceptionInfoConstans;
import com.cxfframe.server.inter.QueryService;
import com.cxfframe.server.load.LoadConfig;
import com.cxfframe.server.module.ModuleFactory;
import com.cxfframe.server.module.ServiceBase;
import com.cxfframe.service.CXFFrameRelease;
import org.apache.cxf.common.util.StringUtils;
import org.apache.log4j.Logger;

/**
 * WebService接口实现
 *
 * @author CYX
 * @create 2017-05-24-21:15
 */
public class QueryServiceImpl implements QueryService {


    private final Logger logger = CXFFrameRelease.logger;


    public String queryServerInformation(String moduleName, String params) {

        // 参数为空,直接返回错误信息
        if (StringUtils.isEmpty(moduleName) & StringUtils.isEmpty(params)) {
            logger.info(ExceptionInfoConstans.MODULENAME_PARAMS_EXCEPTION);
            return ExceptionInfoConstans.MODULENAME_PARAMS_EXCEPTION;
        }

        // 根据模块名找class,找不到直接返回错误信息
        LoadConfig loadConfig = LoadConfig.getInstance();
        if (loadConfig.getModulesConfigWithInfomation().get(moduleName).isEmpty()) {
            logger.info("module name : " + moduleName + " can not find the corresponding module");
            return ExceptionInfoConstans.MODULENAME_CLASS_EXCEPTION;// moduleName找不到对应模块
        }


        logger.info("==================== The server begins processing ====================");
        logger.info("==================== The server begins processing ====================");


        logger.info("module name : " + moduleName + " , params : " + params);

        String responseResult = "";

        try {

            // 根据模块名获取模块实例,加载模块配置并初始化
            ServiceBase serviceBase = ModuleFactory.getModuleInstance(moduleName);

            //实例化模块失败,返回错误信息
            if (serviceBase == null) {
                logger.info(ExceptionInfoConstans.INSTANTIATE_MODULE_EXCEPTION);
                return ExceptionInfoConstans.INSTANTIATE_MODULE_EXCEPTION;
            }


            // 调用私有模块主方法
            responseResult = serviceBase.process(params);


        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ExceptionInfoConstans.SERVER_PROCESS_EXCEPTION;
        }

        logger.info("==================== The server is finished ====================");
        logger.info("==================== The server is finished ====================");

        return responseResult;
    }
}
CXF接口的实现。

在这个类中,会根据模块名,生成对应的模块实例,然后调用主方法,执行sdk业务,并返回指定数据


CXFFrameRelease.java

package com.cxfframe.service;

import com.cxfframe.server.impl.QueryServiceImpl;
import com.cxfframe.server.load.LoadConfig;
import org.apache.log4j.Logger;

import javax.xml.ws.Endpoint;

/**
 * CXFFrame发布主程序
 *
 * @author CYX
 * @create 2017-05-24-21:22
 */
public class CXFFrameRelease {

    public static final Logger logger = Logger.getLogger("cxfframe");

    public static void main(String[] args) {

        LoadConfig loadConfig = null;

        // 加载配置文件,出现异常,直接退出程序
        try {

            loadConfig = LoadConfig.getInstance();
            loadConfig.init();

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            System.exit(1);
        }

        // 发布CXF服务(WebService)
        try {

            String address = "http://" + loadConfig.getCxfFrame_IP() + ":" + loadConfig.getCxfFrame_PORT() + "/" + loadConfig.getCxfFrame_ServiceName() + "?wsdl";

            // CXFFrame主方法
            Endpoint.publish(address, new QueryServiceImpl());

            logger.info("CXFFrame release is success , address : " + address);

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

    }

}
CXFFrame平台发布主方法


LoadConfig.java

package com.cxfframe.server.load;

import com.cxfframe.server.common.CommConstans;
import com.cxfframe.server.common.KeyConstans;
import com.cxfframe.service.CXFFrameRelease;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;

/**
 * 加载配置
 *
 * @author CYX
 * @create 2017-05-24-21:39
 */
public class LoadConfig {

    private final Logger logger = CXFFrameRelease.logger;

    //单例
    private static class LoadConfigHolder {
        private static final LoadConfig INSTANCE = new LoadConfig();
    }

    public static final LoadConfig getInstance() {
        return LoadConfigHolder.INSTANCE;
    }


    private String cxfFrame_IP;
    private String cxfFrame_PORT;
    private String cxfFrame_ServiceName;

    /**
     * 模块名和class全路径的映射
     */
    private HashMap<String, String> moduleNameWithClass = new HashMap<String, String>(20);

    /**
     * 存放私有模块的配置信息
     * 模块名-(配置文件名-配置文件内容)
     */
    private HashMap<String, HashMap<String, String>> modulesConfigWithInfomation = new HashMap<String, HashMap<String, String>>(20);

    /**
     * CXFFrame初始化
     *
     * @throws Exception
     */
    public void init() throws Exception {

        // 加载logger
        loadLogger();

        // 加载配置文件
        loadCXFFrameCofig();

        // 加载所有模块的私有配置
        loadModulesCofig();

        // 加载modules.xml
        loadModulesXML();

    }

    /**
     * 加载logger 支持动态改变log4j配置(类似于热部署)
     *
     * @throws Exception
     */
    private void loadLogger() throws Exception {
        PropertyConfigurator.configure(CommConstans.CXFFRAME_LOG4J_CONF_PATH);
        PropertyConfigurator.configureAndWatch(CommConstans.CXFFRAME_LOG4J_CONF_PATH, 1000);
    }

    /**
     * 加载CXFFrame配置文件
     *
     * @throws Exception
     */
    private void loadCXFFrameCofig() throws Exception {
        Properties pro = new Properties();
        pro.load(new FileInputStream(new File(CommConstans.CXFFRAME_CONF_PATH)));

        // 默认获取本地IP
        cxfFrame_IP = InetAddress.getLocalHost().getHostAddress();
        cxfFrame_PORT = pro.getProperty(KeyConstans.CXFFRAME_PORT);
        cxfFrame_ServiceName = pro.getProperty(KeyConstans.CXFFRAME_RELEASE_NAME);

        logger.debug("cxfFrame_IP : " + cxfFrame_IP);
        logger.debug("cxfFrame_PORT : " + cxfFrame_PORT);
        logger.debug("cxfFrame_ServiceName : " + cxfFrame_ServiceName);

    }

    /**
     * 加载modules.xml
     *
     * @throws Exception
     */
    private void loadModulesXML() throws Exception {

        String modulesResult = FileUtils.readFileToString(new File(CommConstans.MODULES_XML_PATH), "UTF-8");

        // 解析modules.xml
        handleModulesXML(modulesResult);

    }

    /**
     * 解析modules.xml
     *
     * @param modulesResult
     * @throws Exception
     */
    private void handleModulesXML(String modulesResult) throws Exception {

        Document document = DocumentHelper.parseText(modulesResult);
        Element rootElement = document.getRootElement();

        // 获取modules节点下所有的module节点
        List<Element> modules = rootElement.elements("module");

        for (Element module : modules) {
            String moduleName = module.attributeValue("name");// 获取name的属性值
            String moduleClass = module.attributeValue("class");// 获取class的属性值

            moduleNameWithClass.put(moduleName, moduleClass);
        }

    }

    /**
     * 加载modules目录下所有模块的私有配置
     *
     * @throws Exception
     */
    private void loadModulesCofig() throws Exception {

        // modules目录下,所有的子模块
        File[] moduleDirs = new File(CommConstans.MODULES_DIR_PATH).listFiles(new FileFilter() {
            public boolean accept(File pathname) {
                return pathname.isDirectory();
            }
        });

        for (File moduleDir : moduleDirs) {

            // 加载单个私有模块的配置信息
            loadPrivatelyOwnedModuleConf(moduleDir);
        }

    }

    /**
     * 加载单个私有模块的配置
     */
    private void loadPrivatelyOwnedModuleConf(File moduleDir) throws Exception {

        String moduleName = moduleDir.getName();// 模块名

        // 获取私有模块conf目录下所有配置文件
        File[] configFiles = new File(moduleDir.getPath() + "/conf").listFiles(new FileFilter() {
            public boolean accept(File pathname) {
                return pathname.isFile();
            }
        });

        // 循环读取conf目录下的配置文件
        HashMap<String, String> configFileNameWithinfo = new HashMap<String, String>();

        if (null != configFiles) {

            for (File configFile : configFiles) {

                String configFileName = configFile.getName();// 文件名
                String configInformation = FileUtils.readFileToString(configFile, "UTF-8");// 文件内容

                // 文件名-文件内容,存入map
                configFileNameWithinfo.put(configFileName, configInformation);
            }

        } else {
            logger.info("module Name : " + moduleName + " , configFiles is null");
        }

        // 模块名-(配置文件名-配置文件内容)
        modulesConfigWithInfomation.put(moduleName, configFileNameWithinfo);

        logger.info("All modules private configuration" + modulesConfigWithInfomation);
    }

    public String getCxfFrame_IP() {
        return cxfFrame_IP;
    }

    public String getCxfFrame_PORT() {
        return cxfFrame_PORT;
    }

    public String getCxfFrame_ServiceName() {
        return cxfFrame_ServiceName;
    }

    public HashMap<String, String> getModuleNameWithClass() {
        return moduleNameWithClass;
    }

    public HashMap<String, HashMap<String, String>> getModulesConfigWithInfomation() {
        return modulesConfigWithInfomation;
    }
}
这个类是加载平台配置信息,以及SDK私有模块配置信息的。

上面代码注释写的已经很清楚了。


ModuleFactory.java

package com.cxfframe.server.module;

import com.cxfframe.server.load.LoadConfig;
import com.cxfframe.service.CXFFrameRelease;
import org.apache.cxf.common.util.StringUtils;
import org.apache.log4j.Logger;

import java.util.HashMap;

/**
 * 模块工厂,负责创建模块对象
 *
 * @author CYX
 * @create 2017-05-25-11:00
 */
public class ModuleFactory {

    private static final Logger logger = CXFFrameRelease.logger;

    /**
     * 获取模块实例
     *
     * @param modeulName
     * @return
     */
    public static ServiceBase getModuleInstance(String moduleName) {

        LoadConfig loadConfig = LoadConfig.getInstance();

        ServiceBase serviceBase = null;

        // 实例化模块
        Object obj = null;
        try {
            // 获取模块对应的class路径
            String moduleClass = loadConfig.getModuleNameWithClass().get(moduleName);
            logger.info("module : " + moduleName + " , class : " + moduleClass);
            if (StringUtils.isEmpty(moduleClass)) {
                logger.info("module : " + moduleName + " , class is null");
                return null;
            }

            // 通过反射获取模块实例
            Class exampleClass = Class.forName(moduleClass);
            obj = exampleClass.newInstance();

            serviceBase = (ServiceBase) obj;

            // 加载模块并初始化

            // 根据模块名,取出模块对应的配置文件
            HashMap<String, String> moduleConfigNameWithInfo = loadConfig.getModulesConfigWithInfomation().get(moduleName);

            // 私有模块加载配置
            serviceBase.loadConfig(moduleConfigNameWithInfo);

            // 私有模块初始化
            serviceBase.init();

            logger.info("===== Load Configuration Initialize the private module is complete =====");

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return null;
        }

        return serviceBase;
    }

}
这个类是根据模块名声称对应模块实例的主要方法


ServiceBase.java

package com.cxfframe.server.module;

import java.util.HashMap;

/**
 * 基类
 *
 * @author CYX
 * @create 2017-05-25-11:01
 */
public abstract class ServiceBase {

    /**
     * CXFFrame将模块对应的配置文件,传给对应私有模块
     *
     * @param moduleConf
     * @throws Exception
     */
    public abstract void loadConfig(HashMap<String, String> moduleConf) throws Exception;

    /**
     * 初始化
     *
     * @throws Exception
     */
    public abstract void init() throws Exception;

    /**
     * 模块主处理方法(子模块返回建议不要返回null)
     *
     * @param information
     * @return
     * @throws Exception
     */
    public abstract String process(String information) throws Exception;


}
这个是给SDK私有模块主类继承用的


CommonUtils.java

package com.cxfframe.server.util;

/**
 * 公共方法
 *
 * @author CYX
 * @create 2017-05-24-21:43
 */
public class CommonUtils {

    /**
     * 判断是否是windows操作系统
     *
     * @return String
     */
    public static boolean isWindowsOS() {
        boolean isWindowsOS = false;
        String osName = System.getProperty("os.name");
        if (osName.toLowerCase().indexOf("windows") > -1) {
            isWindowsOS = true;
        }
        return isWindowsOS;
    }

}
公共方法


pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com</groupId>
	<artifactId>CXF_Frame</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>CXF_Frame</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<cxf.version>3.1.11</cxf.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-jaxws</artifactId>
			<version>${cxf.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-transports-http</artifactId>
			<version>${cxf.version}</version>
		</dependency>
		<!-- Jetty is needed if you're are not using the CXFServlet -->
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-transports-http-jetty</artifactId>
			<version>${cxf.version}</version>
		</dependency>

		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>

		<dependency>
			<groupId>dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>1.6.1</version>
		</dependency>

		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.5</version>
		</dependency>

		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>

		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.2.2</version>
		</dependency>

	</dependencies>
	
	<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
	
</project>

这里平台的代码就讲解到这里...


这里贴上服务器上CXFFrame的结构图




SDK开发样例




在上面的安装包中,有详细的开发文档,欢迎互相讨论
一次解决Intellij IDEA can't load jvm DLL错误的过程 文章目录一次解决Intellij IDEA can't load JVM DLL错误的过程 一次解决Intellij IDEA can’t load JVM DLL错误的过程 今天在一台新的Windows 10电脑上安装Intellij IDEA 2019.2 community版本后,在启动Intellij时报错“Failedo to load JVM DLL” 的错误。 详细错误信息如下: ... 阅读详情

相关推荐

第九章 Nacos Config--服务配置

今天咱们接着 上一篇 第八章 SMS–短信服务 继续写 SpringCloud Alibaba全家桶 —> 第九章 Nacos Config–服务配置,废话不多说,开干 9.1 服务配置中心介绍 首先我们来看一下,微服务架构下关于配置文件的一些问题: 配置文件相对分散。在一个微服务架构下,配置文件会随着微服务的增多变的越来越多,而且分散在各个微服务中,不好统一配置和管理。 配置文件无...

程序员小刘 4786

菜单功能开发

1.1开标结束 功能:页面上增加导出Excel按钮,将开标一览表格

m0_60553605的博客 735

家庭路由器从入门到精通:连接设置、优化排障全指南

路由器作为家庭网络的核心枢纽,其工作原理基于NAT(网络地址转换)和DHCP(动态主机配置协议)两大关键技术。NAT负责将公网IP转换为多个内网IP,实现多设备共享上网;DHCP则自动为接入设备分配IP地址,简化网络配置。这些技术共同构建了稳定、安全的局域网环境,其价值在于为智能家居、在线办公、高清影音和游戏娱乐等场景提供可靠的网络基础。理解路由器的物理连接、后台设置与故障排查逻辑,是优化Wi-Fi信号覆盖、提升网络性能、保障家庭网络安全的关键。本文以路由器配置与排障为核心,详细解析从WAN/LAN口区分、

weixin_33393017的博客 406

jvm reference

JDK1.2之后,把对象的引用分为四种状态,即强引用、软引用、弱引用和虚引用。这样的方式,可以更加灵活地控制对象的生命周期。 一、强引用 开发中用的最多的就是强引用了。 强引用声明格式: String str="abc"; 只要某个对象与强引用关联,那么JVM在内存不足的情况下,宁愿抛出outOfMemoryError错误,也不会回收此类对象。 【1】如果我们想要JVM回收此类被强...

抛弃幻想,准备斗争 1185

Apache NiFi新手必看:从零开始的数据流设计入门教程(含实战案例)

本文为Apache NiFi新手提供从零开始的数据流设计入门指南。通过实战案例,详细讲解了如何利用这一强大的数据采集工具,以可视化拖拽方式构建自动化数据流,实现从文件监控、内容处理到数据入库的全流程,并涵盖核心概念、环境搭建及生产环境调优要点。

weixin_29066781的博客 149

从婴儿学步到工业级应用:VLA的‘隐式标定‘原理通俗图解

本文深入解析VLA(Vision-Language-Action)模型的'隐式标定'原理,通过类比婴儿学习机制,揭示其如何替代传统手眼标定技术。文章对比了工业机器人传统标定与VLA数据驱动方法的差异,并可视化神经网络注意力机制,展示其在空间关系编码上的突破性进展。最后探讨了VLA在工业应用中的优势与混合架构解决方案。

pz890123456的博客 324

JVM学习1

1.JVM的生命周期 JVM实例和JVM引擎实例  a.JVM实例对应了一个独立运行的java程序,它是进程级别。  b.JVM执行引擎实例则对应了属于用户运行程序的线程,它是线程级别 2.JVM的生命周期  a.JVM实例的诞生:当启动一个java程序时,一个JVM实例就产生了,任何一个拥有public static void main(String[] args)函数的cla

jiangtao7913的博客 408

Vivado2022.2下载安装

链接:https://pan.baidu.com/s/1lyfE2d-VmaWC-_aR8ratCQ提取码:mt09。

weixin_61081689的博客 2万+

spring类中某个方法注入失败

注入失败是因为方法的修饰出了问题,当全部是public private时没有问题,当public private共存的时候,private会对应新的实例,注入失败。

qq_29580963的博客 541

【数学基础】基于欧拉角表达的旋转顺序

欧拉角旋转顺序

FalschxMico 1384

74、光谱成像在电子内窥镜及色彩理论中的应用

本文探讨了光谱成像在电子内窥镜中的应用及其与色彩理论的深度融合。通过分析FICE技术、色彩再现模型及胃黏膜光谱测量,展示了光谱信息在提升医学诊断准确性方面的潜力。同时,系统阐述了颜色的物理属性、标准表示方法、同色异谱现象、颜色测量技术(密度法与比色法)以及CIELAB等均匀颜色空间的构建原理。结合流程图与对比表格,梳理了从光信号获取到颜色处理的完整路径,并展望了人工智能与新型视觉模型在未来医疗成像与色彩科学中的发展方向。

g2h3i4j5的博客 153

java安装找不到jvm,启动IDEA时出错:找不到JVM安装

I tried googling the issue and found my way to the Oracle websitewhere they offered JDK downloads. However there was no 32bit windowsversion available.Why do I need a JDK for Python development?intell...

weixin_30621429的博客 2784

STM32F4 SPI FLASH(W25Q128)驱动详解(含DMA+完整读写擦除+低功耗)

本文实现了一款基于STM32 HAL库的SPI Flash驱动,以W25Q128为例,提供了完整的初始化、读写、擦除、ID读取等功能。驱动集成了DMA传输、超时保护、页对齐写入等特性,支持扇区擦除、整片擦除、页写入及跨页缓冲写入。代码结构清晰,易于移植到其他SPI Flash型号(如W25Q64、W25Q16等),适用于数据存储、固件升级、文件系统等嵌入式场景。

kevin1499的博客 96

Mac安装Android Studio 提示can not find a valid JVM

Mac安装Android Studio 提示can not find a valid JVM 因为Android Studio中的JVM版本不对,解决方法: 应用程序-中找到Android Studio.app,右击-显示包内容-Contents,目录下找到Info.plist,文本编辑器打开,查找JVMVersion,将1.6*,改为你系统的JDK的版本,我用的1.8的JDK,改为1

... 2089

支付宝h5参数如何实现跳转?(包含相关Demo代码)

🏆本文收录于专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家!持续更新中,up!up!up!!

**My Coding Family** 3250

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

WebLogic常见问题

1、ClassNotFoundException:org.hibernate.hql.ast.HqlToken异常 使用Hibernate的工程部署到WebLogic下时,经常会出现ClassNotFoundException:org.hibernate.hql.ast.HqlToken的问题,出现该问题的主要原因在于WebLogic已经集成了antlr.jar包,在使用Hibernate时,会

z69183787的专栏 2万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

很奇葩的问题 your property named "%s" cannot find the corresponding database column name

原因竟然是 mybatis-plus 3.1.0 和热部署插件spring-boot-devtools 冲突。。。。。。。。。。。。。

sinat_33907356的博客 2043

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

解决运行java application时提示Could not find the main class.Program will exit.问题

解决运行java application时提示Could not find the main class.Program will exit.问题:    以Java Application的方式运行java类的时候,有时会提示Could not find the main class.Program will exit,遇到这样的情况,一般有如下几种原因和解决方式: 一、Java类中

架构师之路 1万+

Mac 配置Android Studio 出现 can't find valid JVM问题

下载完成Android Studio后打开,会出现can't find valid JVM的警告,可是在终端中运行Java -version 会出现是有jvm的版本好的也就是mac上是已经安装好jvm的。解决办法就是在你的 应用程序文件夹中,右键点击Android显示包内容,找到info.plist文件,找到JVMVersion  这个字段后面的1.6* 改成你当前系统的Java版本,比如我运行J

jiabinzhang4310的专栏 1215

mac使用jvm诊断工具arthas启动报错Can not find tools.jar under java home解决

linux操作系统遇到以下问题也可用同样的方式解决 -bash-3.2$ java -jar arthas-boot.jar [INFO] arthas-boot version: 3.4.5 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 14224 org.jetbrains.idea.mave

v_lquanlin的博客 6359

新建idea的scala项目报错

错误记录: 通过IDEA方式创建scala项目后,在修改项目目录结构时,将src、main、scala目录全部设置为Sources时, 运行程序时报错: Error:(1, 8) hello is already defined as object hello object hello { 解决方案: 只将程序上一层目录设置为Sources,问题解决。 ...

风尘子曰 731

SOFABoot源码解析之JVM服务

1.SOFABoot源码解析1.1  JVM服务1.1.1 服务发布        以SOFABoot自带的RPC案例sofaboot-sample-with-rpc为例,详细描述SOFABoot JVM服务发布过程。        在此提前说明,源码分析主要分析主流程,以及本人认为比较重要的一些内容,对于其它部分,大家可以基于本文档,自行研读。        RPC案例的SpringXML配置文...

闲来无事 3904
上一篇: Apache Camel - 18 - JDBC组件
下一篇: Java - 提高(0) - Collection
Simba_cheng
博客等级 码龄11年 250粉丝 203原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值