【问题标题】:Spring boot get application properties per request mappingSpring Boot 获取每个请求映射的应用程序属性
【发布时间】:2018-08-24 12:39:52
【问题描述】:

我尝试从我的应用程序属性中获取每个请求的一些参数。

我的 ApplicationConfig 类:

@Configuration
@ConfigurationProperties("org.a.b")
public class ApplicationConfig implements Serializable {

    private String name;
    private String ip;
// GETTER AND SETTER

我的 application.properties:

org.a.b.name=huhu
org.a.b.ip=x.x.x.x

我尝试不同的可能性:

@RestController
public class HelloController

第一:

@Autowired
private ApplicationConfig applicationConfig;

@ResponseBody
@GetMapping(value = "/", produces = "application/json")
public ApplicationConfig index() {
    return applicationConfig;
}

例外:

{"timestamp":"2018-08-24T12:28:50.623+0000","status":500,"error":"Internal Server Error","message":"Type definition error: [simple type, class org.springframework.context.expression.StandardBeanExpressionResolver]; nested exception is com.fasterxml.jackson.datab
ind.exc.InvalidDefinitionException: No serializer found for class org.springframework.context.expression.StandardBeanExpressionResolver and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (
through reference chain: hello.bootstrap.ApplicationConfig$$EnhancerBySpringCGLIB$$31a0e3d2[\"$$beanFactory\"]->org.springframework.beans.factory.support.DefaultListableBeanFactory[\"beanExpressionResolver\"])","path":"/"}

第二:

@ResponseBody
@GetMapping(value = "/", produces = "application/json")
public ApplicationConfig index() {
    return new ApplicationConfig();
}
// return nothing {"name": null, "ip": null}

第三:

@ResponseBody
@GetMapping(value = "/", produces = "application/json")
public String index() {
    return applicationConfig.getIp();
}
// return x.x.x.x

我的 pom.xml:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>


    <build>
        <sourceDirectory>src/main/java</sourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>hello.ConfigServiceApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

我希望应用程序属性为对象,例如:

{"name": "dev", "ip": "x.x.x.x"}

【问题讨论】:

    标签: java json spring-boot get request-mapping


    【解决方案1】:

    您的第一次尝试是正确的,您发现的问题是,当 Spring 接管像这样的对象的管理时 - 从配置文件中设置值 - 它不使用它的“普通”实例,但是是代理版本。

    网上有很多关于代理如何工作的详细信息,我不会在这里解释(主要是因为,就我而言,它很神奇)。

    不过,对于您的情况,最简单的选择可能是将标有 @Configuration 注释的类转换为简单的 POJO。最简单的可能是这样的:

    public class ApplicationConfigResponse {
        private final String name;
        private final String ip;
    
        public ApplicationConfigResponse(ApplicationConfig applicationConfig) {
            this.name = applicationConfig.getName();
            this.ip = applicationConfig.getIp();
        }
    
        public String getName() {
            return name;
        }
    
        public String getIp() {
            return ip;
        }
    }
    

    然后你可以从你的控制器返回那个 POJO,就像你的第一个例子一样:

    @Autowired
    private ApplicationConfig applicationConfig;
    
    @ResponseBody
    @GetMapping(value = "/", produces = "application/json")
    public ApplicationConfigResponse index() {
        return new ApplicationConfigResponse(applicationConfig);
    }
    

    如果您希望拥有更多属性,或者希望这是在大型应用程序中重复使用的模式,您可能更愿意查看 Spring 用于在对象之间转换的内置功能 - 本教程是一个很好的起点: https://www.baeldung.com/spring-type-conversions

    【讨论】:

    • 它正在工作,但我尝试使用 ResponseEntity 的不同解决方案。 @ResponseBody @GetMapping(value = "/", produces = "application/json") public ResponseEntity&lt;ApplicationConfig&gt; index() { return new ResponseEntity(applicationConfig, HttpStatus.OK); } 我有很多不同配置文件的应用程序。我不能对每个属性都使用 pojo。
    【解决方案2】:

    不建议使用 @Configuration@ConfigurationProperties 注释类,因为 spring 以特殊方式处理带有 @Configuration 的任何内容。

    使用第一种方法,不要用@Configuration 注释ApplicationConfig。您的第一种方法应该可行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-25
      • 2019-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-12
      • 2020-11-08
      • 1970-01-01
      相关资源
      最近更新 更多