【问题标题】:Springboot @Value not loadingSpring Boot @Value 未加载
【发布时间】:2019-07-31 09:44:52
【问题描述】:

Github 上的示例Springboot 项目中,启动应用程序时不会加载@Value 属性。我无法解释这种奇怪的行为,希望任何人都可以帮助我解决它并避免这种愚蠢的错误?

@RestController
public class PostClient {

    @Value(value = "${target.uri}")
    public String uri;

    private RestTemplate restTemplate = new RestTemplate();
    private HttpHeaders headers = new HttpHeaders();

    public PostClient() {}

    public HttpStatus postNumberPlate(CamImage camImage) {

        LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
        map.add("numplate", camImage.getIdentifier());
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<LinkedMultiValueMap<String,
                        Object>>(map, headers);

        ByteArrayResource resource = new ByteArrayResource(camImage.getData()) {
            @Override
            public String getFilename() {
                return camImage.getIdentifier() + ".png";
            }
        };
        map.add("image", resource);

        System.out.println(uri);

        ResponseEntity<String> result = restTemplate.exchange(uri,
                HttpMethod.POST,
                requestEntity, String.class);

        return result.getStatusCode();
    }
}

application.properties

target.uri=http://localhost:9001/postoffice

read@Value 是 Springboot 的核心功能,应该可以正常工作。我的项目是如此之小,以至于我想知道什么可能会破坏框架的自动值替换行为。我发现了关于@Value 问题的不同和相似的问题,但找不到真正的解释。

我尝试使用带有 getter/setter 的 @Component 类,并尝试将 @Autowire 放入显示的类中,但这也不起作用。

我想采用 Springboot 参考的建议方式,因为任何硬编码的字符串都会导致问题,在构建 docker 容器时,我必须传递一个配置参数。所以我不能只依赖类路径中的固定application.properties

编辑: 运行应用程序如下所示:

shell:>one
Euro Plate                                      # unimportant sysout
CamImage [identifier=BNAYG63, data=[B@4f4c4c4b] # generated plate
null                   # from sysout here should be the address!!
URI is not absolute
Details of the error have been omitted. You can use the stacktrace command to print the full stacktrace.

shell:>stacktrace
java.lang.IllegalArgumentException: URI is not absolute
    at java.base/java.net.URL.fromURI(URL.java:674)
    at java.base/java.net.URI.toURL(URI.java:1116)
    at org.springframework.http.client.SimpleClientHttpRequestFactory.createRequest(SimpleClientHttpRequestFactory.java:145)
    at org.springframework.http.client.support.HttpAccessor.createRequest(HttpAccessor.java:87)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:731)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:579)
    at dev.semo.npgen.service.PostClient.postNumberPlate(PostClient.java:45)
    at dev.semo.npgen.shell.NumberplateClientCommands.one(NumberplateClientCommands.java:62)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282)
    at org.springframework.shell.Shell.evaluate(Shell.java:180)
    at org.springframework.shell.Shell.run(Shell.java:142)
    at org.springframework.shell.jline.InteractiveShellApplicationRunner.run(InteractiveShellApplicationRunner.java:84)
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:770)
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202)
    at dev.semo.npgen.NpgenApplication.main(NpgenApplication.java:10)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)

【问题讨论】:

  • @Value("${target.uri}") private String uri;一样使用
  • 谢谢。但是有什么区别呢?我试过了,但同样的问题。
  • 以上评论不正确。您必须自动装配 `PostClient' 而不是创建对象。请参考下面的答案。
  • 您使用的PostClient 不是由 Spring 管理的。你正在做new PostClient() 来构造一个实例,而不是你应该@Autowire PostClient
  • @M.Deinum 感谢您的努力。:-D

标签: spring-boot


【解决方案1】:

我已从 github 提取您的源代码并进行了测试。正如你提到的,最初它会抛出错误。在我进行如下更改后,它工作正常。您应该自动连接PostClient,因为扫描发生并在您启动应用程序时加载了默认值。

@ShellComponent
public class NumberplateClientCommands {

    @Autowired
    private PostClient postClient;

    .....

    @ShellMethod("Sends one simple POST request.")
    public String one() throws FileNotFoundException {
        NumberPlateUtility np = new NumberPlateUtility();
        HttpStatus response = postClient.postNumberPlate(np.completeImage());
        if (response == HttpStatus.ACCEPTED) {
            return "Request sent successfully.";
        }
        return String.format("Request failed: %s", response.getReasonPhrase());
    }

   .......
}

【讨论】:

    【解决方案2】:

    关注此代码片段

    @Value("${target.uri}")
    private String uri;
    

    【讨论】:

    • 谢谢,但在上面 Chokkan 的评论中没有区别。我已经使用过这种语法,但它不起作用。
    猜你喜欢
    • 2016-04-06
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-03
    • 2018-11-11
    • 2015-02-14
    • 1970-01-01
    相关资源
    最近更新 更多