spring cloud config-server .properties 内容协商失败

Posted

技术标签:

【中文标题】spring cloud config-server .properties 内容协商失败【英文标题】:spring cloud config-server .properties content-negotiation failing 【发布时间】:2016-08-12 20:04:33 【问题描述】:

对我来说,例如内容协商机制。对于从Angel.SR5Angel.SR6 切换到Spring Cloud Brixton.RC1Brixton.RC2 后,.properties 在Spring Cloud Config Server 中不起作用。

当我使用gradlew bootRunjava -jar ... 启动服务时会出现问题。不过,它在我的集成测试中有效(请参阅下面的Working Integration-Test)。

使用场景:

我想访问应用程序my-service 的配置文件testing 中的配置,所以我打电话给http://localhost:8888/my-service/testing.properties

预期结果:

some.property=1234
some.other.property=hello there

实际结果:

没有Accept-标头:

<!DOCTYPE html>
<html>
    <head>
        <title>Error 406</title>
    </head>
    <body>
        <h1>Error 406: Not Acceptable</h1>
        <br/>
        Could not find acceptable representation
    </body>
</html>

带有Accept-标头application/json


    "timestamp": 1461140158009,
    "status": 406,
    "error": "Not Acceptable",
    "exception": "org.springframework.web.HttpMediaTypeNotAcceptableException",
    "message": "Could not find acceptable representation",
    "path": "/config/my-service/default.properties"

从示例中可以看出,内容协商机制似乎适用于错误处理,但对于配置访问却不是。

工作集成测试:

我编写了以下 Spock-Test

@WebIntegrationTest("server.port=0", "management.port=0")
@ActiveProfiles("testing")
@ContextConfiguration(loader = SpringApplicationContextLoader.class, classes = ConfigurationServiceApplication.class)
class ConfigurationAccessTest extends Specification 

    @Autowired
    TestserverInfo testserverInfo

    def "testing profile returns testing properties"() 
        given:
        RestTemplate rest = new TestRestTemplate(null, null)
        Properties properties = new Properties()

        when:
        String result = rest.getForObject( testserverInfo.getBasePath() + "/my-service-testing.properties", String.class );
        properties.load( new StringReader(result) )

        then:
        properties['test'] == 'Testing Profile World'
        properties['my.long.testing.property'] == 'Testing Profile Property'
    

到目前为止我已经做过的事情:

    为此场景编写了上述 Spock-Test,该场景Spring Cloud Config Server 的所有注释版本中都有效 就我对 Spring MVC 中的内容协商的了解而言,检查 ConfigServerMvcConfiguration 是否有任何明显的配置错误

    自己提供一个 WebMvcConfigurer 并像上面引用的配置类一样初始化内容协商:

    @EnableWebMvc
    @Configuration
    public class ConfigMvcConfiguration extends WebMvcConfigurerAdapter 
        private final Logger logger =  LoggerFactory.getLogger(ConfigMvcConfiguration.class);
    
        @Override
        public void configureContentNegotiation(ContentNegotiationConfigurer configurer) 
            configurer.mediaType("properties", MediaType.valueOf("text/plain"));
            configurer.mediaType("yml", MediaType.valueOf("text/yaml"));
            configurer.mediaType("yaml", MediaType.valueOf("text/yaml"));
            logger.info("media-types added");
        
    
    

谁能重现此问题或提供有关如何解决此问题的任何指导?

【问题讨论】:

不确定以前是如何工作的。属性的 url 应该是 localhost:8888/my-service-testing.properties 这对您来说是个问题,因为您的服务名称中有破折号。 谢谢@spencergibb。我也刚刚意识到,我在猎杀鬼。 你能说说你的问题是什么吗? 当然,很抱歉将其打开。我会添加一个答案。 【参考方案1】:

写完这个问题引起了一阵骚动,我意识到:我在猎杀鬼。 在检查我自己编写的集成测试时,我发现我试图使用错误的 url-schema 访问属性。

TLDR

我试图使用 URL 访问属性

http://localhost:8888/config/my-service/testing.properties   <-- wrong
rather than
http://localhost:8888/config/my-service-testing.properties   <-- correct

详情

可以使用以下 url 模式访问 JSON 格式的属性(不使用标签时):

http://<host>:<port>/<contextPath>/<application>/<profile>

如果想要以 json 以外的格式访问属性,她必须使用另一个 url-schema(同样是没有标签的示例)

http://<host>:<port>/<contextPath>/<application>-<profile>.<format>

使用格式beeing properties/yml/yaml 作为当前支持的格式。

又是一个会使事情复杂化的小错误。

【讨论】:

以上是关于spring cloud config-server .properties 内容协商失败的主要内容,如果未能解决你的问题,请参考以下文章

springCloud学习-高可用的分布式配置中心(Spring Cloud Config)

Spring Cloud搭建手册——Spring Cloud Config

CVE-2020-5405spring-cloud-config-server路径穿越漏洞分析

第五篇 高可用配置中心config-server(SVN版)

Spring Cloud Config服务拉取git配置失效的情况之一

spring cloud:config