Nacos读写配置相关工具函数

import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

public class MyUtils {
     
    /**
     * 将驼峰式命名的字符串转换为中划线小写方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。
     * 例如:HelloWorld->hello-world
     * @param name 转换前的驼峰式命名的字符串
     * @return 转换后中划线小写方式命名的字符串
     */
    public static String hyphenName(String name) {
     
        StringBuilder result = new StringBuilder();
        if (name != null && name.length() > 0) {
     
            // 将第一个字符处理成大写
            result.append(name.substring(0, 1).toLowerCase());
            // 循环处理其余字符
            for (int i = 1; i < name.length(); i++) {
     
                String s = name.substring(i, i + 1);
                // 在大写字母前添加下划线
                if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
     
                    result.append("-");
                }
                // 其他字符直接转成大写
                result.append(s.toLowerCase());
            }
        }
        return result.toString();
    }

    /**
     * 配置参数使用ConfigurationProperties注解的Bean读入,这里将Bean读入的参数key=value以nacos的换行符\n来分割返回这个整体字符串。
     * 例如:HelloWorld->hello-world
     * @param configurationObject 有ConfigurationProperties注解的java类实例
     * @param configurationClass有ConfigurationProperties注解的java类
     * @return 转换后中划线小写方式命名的字符串
     */
    public static StringBuffer getConfigurationContent(Object configurationObject, Class<?> configurationClass){
     
        StringBuffer buffer = new StringBuffer();
        ConfigurationProperties anno = configurationClass.getAnnotation(ConfigurationProperties.class);
        if(ObjectUtils.isNotEmpty(anno)) {
     
            String prefix = anno.prefix() + ".";
            Field[] fields = configurationClass.getDeclaredFields();

            Arrays.asList(fields).forEach(field -> {
     
                String name = field.getName();
                String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
                try {
     
                    Method method = configurationClass.getDeclaredMethod(methodName);
                    Object value = method.invoke(configurationObject);
                    if (value == null) value = "";
                    if (value instanceof List) {
     
                        value = ((List) value).stream().collect(Collectors.joining(","));
                    }
                    ApiModelProperty apiModelProperty = field.getDeclaredAnnotation(ApiModelProperty.class);
                    if(ObjectUtils.isNotEmpty(apiModelProperty) && ObjectUtils.isNotEmpty(apiModelProperty.value())){
     
                        buffer.append("#").append(apiModelProperty.value()).append("\n");
                    }
                    buffer.append(prefix)
                            .append(MyUtils.hyphenName(field.getName()))
                            .append("=")
                            .append(value.toString())
                            .append("\n");
                } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
     
                    e.printStackTrace();
                }
            });
        }
        return buffer;
    }
    
    /**
     * configurationClass类中是否存在key转换为属性名对应的属性。
     * @param configurationObject 有ConfigurationProperties注解的java类实例
     * @param configurationClass有ConfigurationProperties注解的java类
     * @param key 如key=hello-world依次比对configurationClass中属性名转化为中划线转化后的字符串比较
     * @return 转换后中划线小写方式命名的字符串
     */
    public static boolean containKey(Object configurationObject, Class<?> configurationClass, String key){
     

        String prefix = (configurationClass.getAnnotation(ConfigurationProperties.class).prefix()) + ".";
        Field[] fields = configurationClass.getDeclaredFields();

        for(int i=0,len=fields.length ;i<len ;i++) {
     
            Field field = fields[i];
            String name = field.getName();
            String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
            try {
     
                Method method = configurationClass.getDeclaredMethod(methodName);
                method.invoke(configurationObject);

                String propertyName = prefix + MyUtils.hyphenName(field.getName());
                if(propertyName.equalsIgnoreCase(key)){
     
                    return true;

                }
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
     
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
	* 具体配置项参数可能是密码,这里用于对密码部门隐藏
	*/
    public static String replaceWithStar(String originString){
     
        if(ObjectUtils.isNotEmpty(originString)){
     
            if(originString.length()<3){
     
                return "***";
            }
            int pad = originString.length() / 3;
            if(pad>2) pad = pad/2+1;
            String left = originString.substring(0,pad);
            String middle = originString.substring(pad, originString.length()-1-pad).replaceAll(".","*");
            String right = originString.substring(originString.length()-pad);
            return left + middle + right;
        }
        return originString;
    }

    /**
     * 返回类对应键值
     */
    public static List<String> getConfigKeys(Object configurationObject, Class<?> configurationClass) {
     
        String prefix = (configurationClass.getAnnotation(ConfigurationProperties.class).prefix()) + ".";
        Field[] fields = configurationClass.getDeclaredFields();

        List<String> keys = new ArrayList<>();

        for(int i=0,len=fields.length ;i<len ;i++) {
     
            Field field = fields[i];
            String name = field.getName();
            String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
            try {
     
                Method method = configurationClass.getDeclaredMethod(methodName);
                method.invoke(configurationObject);

                String configKey = prefix + MyUtils.hyphenName(field.getName());
                keys.add(configKey);
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
     
                e.printStackTrace();
            }
        }
        return keys;
    }

    /**
     * 检查键的值是否跟现在的配置一致,发生改变的再提交修改
     */
    public static boolean isModified(Object configurationObject, Class<?> configurationClass, String key, String value) {
     
        String prefix = (configurationClass.getAnnotation(ConfigurationProperties.class).prefix()) + ".";
        Field[] fields = configurationClass.getDeclaredFields();

        for(int i=0,len=fields.length ;i<len ;i++) {
     
            Field field = fields[i];
            String name = field.getName();
            String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
            try {
     
                Method method = configurationClass.getDeclaredMethod(methodName);
                Object propValue = method.invoke(configurationObject);

                String propertyName = prefix + MyUtils.hyphenName(field.getName());
                if(propertyName.equalsIgnoreCase(key)){
     
                    boolean equal = ObjectUtils.isEmpty(value) && ObjectUtils.isEmpty(propValue);
                    if(!equal){
     
                        if (propValue instanceof Collection) {
     
                            Collection<String> list = (Collection<String>)propValue;
                            equal = ObjectUtils.equals(value, String.join(",",list));
                        }
                        else {
     
                            equal = ObjectUtils.equals(value, propValue.toString());
                        }
                    }

                    return !equal;
                }
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
     
                e.printStackTrace();
            }
        }
        return false;
    }
}

举例一个配置类

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;


/**
 * 数据持久化ID策略
 */
@ConfigurationProperties(prefix = "com.aa.bb.id.generator")
@RefreshScope
@Component
@Data
public class IdWorkerConfiguration {
     

    @ApiModelProperty(value = "数据中心id,数值范围1-11")
    private String workId = "1";

    @ApiModelProperty(value = "数据id,数值范围1-11")
    private String dataId = "1";

}

controller代码

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@Slf4j
@RestController
@Api(tags = {
     "Nacos配置"})
@RequestMapping({
     "/v1/nacos"})
public class NacosController {
     

    @Resource
    private RestTemplate directRestTemplate;

    @Resource
    private MyConfig myConfig;

    @Resource
    private PublicCephConfig publicCephConfig;

    @Resource
    private IdWorkerConfiguration idWorkerConfiguration;

    @Resource
    private SwaggerConfiguration swaggerConfiguration;

    @Resource
    private PublicDataSourceConfig publicDataSourceConfig;

    @Resource
    private ServletMultipartConfig servletMultipartConfig;

    public static final String CONF_LINE_STRING = "\n";

    private final NacosConfiguration conf;

    public NacosController(NacosConfiguration conf) {
     
        this.conf = conf;
    }

    @ApiOperation("所有主要配置")
    @GetMapping()
    public String[] getAllMajorConfig() {
     
        StringBuffer buffer = new StringBuffer();
        buffer.append(getMyConfigBuffer());
        buffer.append(getPublicCephConfigBuffer());
        buffer.append(getIdWorkerConfigurationBuffer());
        buffer.append(getSwaggerConfigurationBuffer());
        buffer.append(getPublicDataSourceConfigBuffer());
        buffer.append(getServletMultipartConfigBuffer());
        buffer.append("###<<<<<);
        return buffer.toString().split(CONF_LINE_STRING);
    }

    @ApiOperation("可修改配置")
    @GetMapping("/editable")
    public String[] getEditableConfig() {
     
        StringBuffer buffer = new StringBuffer();
        buffer.append(getMyConfigBuffer());
        buffer.append(getServletMultipartConfigBuffer());
        buffer.append(getIdWorkerConfigurationBuffer());
//        buffer.append(getSwaggerConfigurationBuffer());
        buffer.append("###<<<<<);
        return buffer.toString().split(CONF_LINE_STRING);
    }

    @ApiOperation("修改一项配置2")
    @PutMapping("/{key}/{value}")
    public Result updateConfig(@PathVariable String key, @PathVariable String value) {
     

        if(ObjectUtils.isEmpty(key) || ObjectUtils.isEmpty(value)){
     
            return Result.failed("参数无效");
        }
        try {
     
            Result result = Result.failed("配置项不存在");

            if (updateConf(myConfig, MyConfig.class, key,value,result)) {
     
                return result;
            }
            else if (updateConf(swaggerConfiguration, SwaggerConfiguration.class, key, value, result)) {
     
                return result;
            }
            else if (updateConf(servletMultipartConfig, ServletMultipartConfig.class, key, value, result)) {
     
                return result;
            }
            else if (updateConf(idWorkerConfiguration, IdWorkerConfiguration.class, key, value, result)) {
     
                return result;
            }
            else{
     
                return result;
            }
        }catch (Exception e){
     
            log.error("配置更新失败,key={},value={},原因:{}",key, value, e.getMessage());
            e.printStackTrace();
            return Result.failed("配置更新失败");
        }
    }

    private boolean updateConf(Object configObject,Class<?> configClass,String key, String value, Result refResult) throws Exception {
     

        if (MyUtils.containKey(configObject, configClass, key)) {
     
            Result result = null;
            if (MyUtils.isModified(configObject, configClass, key, value)) {
     
                result = Result.succeed(NacosConfigUtils.update(directRestTemplate, conf, key, value), ResultMsgEnum.SUCCESS);
            } else {
     
                result = Result.succeed("参数未改变");
                refResult.setCode(2);
            }

            refResult.setMsg(result.getMsg());
            refResult.setData(result.getData());
            return true;
        }
        return false;
    }

    @ApiOperation("修改一项配置1")
    @PutMapping()
    public Result updateConfig(@RequestParam String item) {
     
        if(ObjectUtils.isEmpty(item) || !item.contains("=") || item.split("=").length != 2){
     
            return Result.failed("参数无效");
        }

        String key = item.split("=")[0];
        String value = item.split("=")[1];

        return updateConfig(key,value);
    }


    @ApiOperation("人员配置")
    @GetMapping("/main")
    public String[] getMyConfig() {
     
        return getMyConfigBuffer().toString().split(CONF_LINE_STRING);
    }
    public StringBuffer getMyConfigBuffer() {
     
        StringBuffer buffer = new StringBuffer();
        buffer.append("###应用参数").append(CONF_LINE_STRING);
        buffer.append(MyUtils.getConfigurationContent(myConfig, MyConfig.class));
        buffer.append(CONF_LINE_STRING);
        return buffer;
    }

    @ApiOperation("ceph参数")
    @GetMapping("/ceph")
    public String[] getPublicCephConfig() {
     
        return getPublicCephConfigBuffer().toString().split(CONF_LINE_STRING);
    }
    public StringBuffer getPublicCephConfigBuffer() {
     
        StringBuffer buffer = new StringBuffer();
        buffer.append("###ceph参数").append(CONF_LINE_STRING);
        buffer.append(MyUtils.getConfigurationContent(publicCephConfig, PublicCephConfig.class));
        buffer.append(CONF_LINE_STRING);
        return buffer;
    }

    @ApiOperation("主键生成配置")
    @GetMapping("/idWorker")
    public String[] getIdWorkerConfiguration() {
     
        return getIdWorkerConfigurationBuffer().toString().split(CONF_LINE_STRING);
    }
    public StringBuffer getIdWorkerConfigurationBuffer() {
     
        StringBuffer buffer = new StringBuffer();
        buffer.append("###主键生成配置").append(CONF_LINE_STRING);
        buffer.append(MyUtils.getConfigurationContent(idWorkerConfiguration, IdWorkerConfiguration.class));
        buffer.append(CONF_LINE_STRING);
        return buffer;
    }

    @ApiOperation("文档配置")
    @GetMapping("/swagger")
    public String[] getSwaggerConfiguration() {
     
        return getSwaggerConfigurationBuffer().toString().split(CONF_LINE_STRING);
    }
    public StringBuffer getSwaggerConfigurationBuffer() {
     
        StringBuffer buffer = new StringBuffer();
        buffer.append("###文档配置").append(CONF_LINE_STRING);
        buffer.append(MyUtils.getConfigurationContent(swaggerConfiguration, SwaggerConfiguration.class));
        buffer.append(CONF_LINE_STRING);
        return buffer;
    }

    @ApiOperation("数据源配置")
    @GetMapping("/datasource")
    public String[] getPublicDataSourceConfig() {
     
        return getPublicDataSourceConfigBuffer().toString().split(CONF_LINE_STRING);
    }
    private StringBuffer getPublicDataSourceConfigBuffer() {
     
        StringBuffer buffer = new StringBuffer();
        buffer.append("###数据源配置").append(CONF_LINE_STRING);
        buffer.append(MyUtils.getConfigurationContent(publicDataSourceConfig, PublicDataSourceConfig.class));
        buffer.append(CONF_LINE_STRING);
        return buffer;
    }

    @ApiOperation("上传附件大小限制")
    @GetMapping("/multipart")
    public String[] getServletMultipartConfig() {
     
        return getServletMultipartConfigBuffer().toString().split(CONF_LINE_STRING);
    }

    private StringBuffer getServletMultipartConfigBuffer(){
     
        StringBuffer buffer = new StringBuffer();
        buffer.append("###上传附件大小限制").append(CONF_LINE_STRING);
        buffer.append(MyUtils.getConfigurationContent(servletMultipartConfig, ServletMultipartConfig.class));
        buffer.append(CONF_LINE_STRING);
        return buffer;
    }
}

你可能感兴趣的:(spring)