jmix 打包后读取外部 application.properties

俩问题:
1.打包后有没有什么快捷的方式将application.properties 配置文件打出来。
2.使用services开出接口的时候,返回了一个对象,对象中如果为null的字段不显示的问题怎么解决。
后端:{key1:123,key2:null} , 返回给前端的话只是{key1:123}

1 个赞
  1. 可以使用 Spring Boot Actuators 来查看所有属性,参考:https://www.baeldung.com/spring-boot-actuators

/env returns the current environment properties. Additionally, we can retrieve single properties.

  1. 返回的是什么类型的对象?

  2. 另外建议一个帖子只讨论一个问题

1 个赞

第一个问题,看标题你是要打包后读取外部属性文件?
运行时可以通过 Spring boot 的命令行参数 --spring.config.location=<外部属性文件> 指定运行时的属性文件,但是注意,这里会覆盖 Jar 中自带的文件,需要把所有内容都复制到外部属性文件中。因此,可以在项目中维护一个部署时使用的属性文件,比如叫 deploy.properties,然后通过 Gradle 的 Copy 类型任务复制到 build 目录,在执行 bootJar 打包时将该任务添加为前置任务,例如:

task copyDeployFiles(type: Copy) {
    // 这个文件需要手动维护,将修改的 application.properties 内容加进来。
    from 'src/main/resources/deploy.properties' 
    into 'build/libs'
   // 复制到 build 目录后,可以重命名为 application.properties
    rename('deploy.properties', 'application.properties')
}

第二个问题,目前开箱不支持。

但是 Jmix 框架是可以扩展的,自己写一个类继承 ServicesControllerManager,并使用 @Primary 注解。然后将原来类中的 _invokeServiceMethod 方法复制到你自己的类中,在调用 entitySerializationAPI.toJson() 的两个地方,分别加上 EntitySerializationOption.SERIALIZE_NULLS 参数就可以了。
image

返回的是JmixEntity 实体类。

请问是不是将 bootstrap.properties 打出去操作是一样 的,另外第二个问题继承ServicesControllerManager 类的方法 未生效

第一个问题,我想是的。第二个问题,我测试了下,是可以的,类应该是这样的:

package com.company.forum.service;  // TODO:这里要替换成你自己的包。

import io.jmix.core.Entity;
import io.jmix.core.EntitySerializationOption;
import io.jmix.core.metamodel.datatype.Datatype;
import io.jmix.core.metamodel.model.MetaClass;
import io.jmix.rest.exception.RestAPIException;
import io.jmix.rest.impl.config.RestServicesConfiguration;
import io.jmix.rest.impl.service.ServicesControllerManager;
import io.jmix.rest.transform.JsonTransformationDirection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

@Primary
@Component("forum_MyServiceControllerManager") // TODO: 这里可以改个组件名
public class MyServiceControllerManager extends ServicesControllerManager {

    private static final Logger log = LoggerFactory.getLogger(MyServiceControllerManager.class);

    @Nullable
    @Override
    protected ServiceCallResult _invokeServiceMethod(String serviceName,
                                                     String methodName,
                                                     HttpMethod httpMethod,
                                                     List<String> paramNames,
                                                     List<String> paramValuesStr,
                                                     String modelVersion) throws Throwable {
        Object service = beanFactory.getBean(serviceName);
        RestServicesConfiguration.RestMethodInfo restMethodInfo =
                restServicesConfiguration.getRestMethodInfo(serviceName, methodName, httpMethod.name(), paramNames);
        if (restMethodInfo == null) {
            throw new RestAPIException("Service method not found",
                    serviceName + "." + methodName + "(" + paramNames.stream().collect(Collectors.joining(",")) + ")",
                    HttpStatus.NOT_FOUND);
        }
        Method serviceMethod = restMethodInfo.getMethod();
        List<Object> paramValues = new ArrayList<>();
        Type[] types = restMethodInfo.getMethod().getGenericParameterTypes();
        for (int i = 0; i < types.length; i++) {
            int idx = i;
            try {
                idx = paramNames.indexOf(restMethodInfo.getParams().get(i).getName());
                String valueStr = idx == -1 ? null : paramValuesStr.get(idx);
                paramValues.add(restParseUtils.toObject(types[i], valueStr, modelVersion));
            } catch (Exception e) {
                log.error("Error on parsing service param value", e);
                throw new RestAPIException("Invalid parameter value",
                        "Invalid parameter value for " + paramNames.get(idx),
                        HttpStatus.BAD_REQUEST,
                        e);
            }
        }

        Object methodResult;
        try {
            methodResult = serviceMethod.invoke(service, paramValues.toArray());
        } catch (InvocationTargetException | IllegalAccessException ex) {
            throw ex.getCause();
        }

        if (methodResult == null) {
            return null;
        }

        Class<?> methodReturnType = serviceMethod.getReturnType();
        if (Entity.class.isAssignableFrom(methodReturnType)) {
            String entityJson = entitySerializationAPI.toJson(methodResult,
                    null,
                    EntitySerializationOption.SERIALIZE_INSTANCE_NAME,
                    EntitySerializationOption.SERIALIZE_NULLS,
                    EntitySerializationOption.DO_NOT_SERIALIZE_DENIED_PROPERTY);
            entityJson = restControllerUtils.transformJsonIfRequired(metadata.getClass(methodResult).getName(),
                    modelVersion, JsonTransformationDirection.TO_VERSION, entityJson);
            return new ServiceCallResult(entityJson, true);
        } else if (Collection.class.isAssignableFrom(methodReturnType)) {
            Type returnTypeArgument = getMethodReturnTypeArgument(serviceMethod);
            if ((returnTypeArgument instanceof Class && Entity.class.isAssignableFrom((Class) returnTypeArgument))
                    || isEntitiesCollection((Collection) methodResult)) {
                Collection<?> entities = (Collection<?>) methodResult;
                String entitiesJson = entitySerializationAPI.toJson(entities,
                        null,
                        EntitySerializationOption.SERIALIZE_INSTANCE_NAME,
                        EntitySerializationOption.SERIALIZE_NULLS,
                        EntitySerializationOption.DO_NOT_SERIALIZE_DENIED_PROPERTY);
                if (returnTypeArgument != null) {
                    MetaClass metaClass = metadata.getClass((Class) returnTypeArgument);
                    if (metaClass != null) {
                        entitiesJson = restControllerUtils.transformJsonIfRequired(metaClass.getName(), modelVersion,
                                JsonTransformationDirection.TO_VERSION, entitiesJson);
                    } else {
                        log.error("MetaClass for service collection parameter type {} not found", returnTypeArgument);
                    }
                }
                return new ServiceCallResult(entitiesJson, true);
            } else {
                return new ServiceCallResult(restParseUtils.serialize(methodResult), true);
            }
        } else {
            Datatype<?> datatype = datatypeRegistry.find(methodReturnType);
            if (datatype != null) {
                return new ServiceCallResult(datatype.format(methodResult), false);
            } else {
                return new ServiceCallResult(restParseUtils.serialize(methodResult), true);
            }
        }
    }
}

好的,容我再试一下,感谢耐心解答及示例! :smile:

问题已解决,感谢解答!