maven 无法在Sping Boot Java中读取application.properties文件

cgvd09ve  于 2023-08-03  发布在  Maven
关注(0)|答案(2)|浏览(146)

我试图在Windows上使用Java和Maven Sping Boot 项目与VSCode创建一个类来发布GraphQL API。我遇到了一个错误,它找不到任何我使用@Value链接的URL。
这是错误日志

Exception in thread "main" java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)   
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:95)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65)
Caused by: org.springframework.web.reactive.function.client.WebClientRequestException: Unable to parse url [] 
        at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException$9(ExchangeFunctions.java:136)
        Suppressed: The stacktrace has been enhanced by Reactor, refer to additional information below:       
Error has been observed at the following site(s):
        *__checkpoint ? Request to POST  [DefaultWebClient]
Original Stack Trace:
                at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException$9(ExchangeFunctions.java:136)
                at reactor.core.publisher.MonoErrorSupplied.subscribe(MonoErrorSupplied.java:55)
                at reactor.core.publisher.Mono.subscribe(Mono.java:4495)
                at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103)
                at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:222)
                at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:222)
                at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:222)
                at reactor.core.publisher.MonoNext$NextSubscriber.onError(MonoNext.java:93)
                at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onError(MonoFlatMapMany.java:204)   
                at reactor.core.publisher.Operators.reportThrowInSubscribe(Operators.java:232)
                at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:71)        
                at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55)
                at reactor.core.publisher.Mono.subscribe(Mono.java:4495)
                at reactor.core.publisher.Mono.block(Mono.java:1711)
                at com.tarkov.randomweapongenerator.service.FetchAPI.SelectDataByWeaponId(FetchAPI.java:31)   
                at com.tarkov.randomweapongenerator.RandomWeaponGeneratorApplication.main(RandomWeaponGeneratorApplication.java:18)
                at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
                at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.base/java.lang.reflect.Method.invoke(Method.java:568)
                at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
                at org.springframework.boot.loader.Launcher.launch(Launcher.java:95)
                at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
                at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65)
        Suppressed: java.lang.Exception: #block terminated with an error
                at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:103)
                at reactor.core.publisher.Mono.block(Mono.java:1712)
                at com.tarkov.randomweapongenerator.service.FetchAPI.SelectDataByWeaponId(FetchAPI.java:31)   
                at com.tarkov.randomweapongenerator.RandomWeaponGeneratorApplication.main(RandomWeaponGeneratorApplication.java:18)
                at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
                at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                at java.base/java.lang.reflect.Method.invoke(Method.java:568)
                at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
                at org.springframework.boot.loader.Launcher.launch(Launcher.java:95)
                at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
                at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65)
Caused by: java.lang.IllegalArgumentException: Unable to parse url []
        at reactor.netty.http.client.UriEndpointFactory.createUriEndpoint(UriEndpointFactory.java:68)
        at reactor.netty.http.client.UriEndpointFactory.createUriEndpoint(UriEndpointFactory.java:44)
        at reactor.netty.http.client.HttpClientConnect$HttpClientHandler.<init>(HttpClientConnect.java:509)   
        at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.subscribe(HttpClientConnect.java:208)
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
        at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55)
        at reactor.core.publisher.Mono.subscribe(Mono.java:4495)
        at reactor.core.publisher.Mono.block(Mono.java:1711)
        at com.tarkov.randomweapongenerator.service.FetchAPI.SelectDataByWeaponId(FetchAPI.java:31)
        at com.tarkov.randomweapongenerator.RandomWeaponGeneratorApplication.main(RandomWeaponGeneratorApplication.java:18)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)   
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:95)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65)

字符串
它告诉“无法解析url []”,这意味着url为空。
这是我的项目树。

├─.mvn
│  └─wrapper
├─src
│  ├─main
│  │  ├─java
│  │  │  └─com
│  │  │      └─tarkov
│  │  │          └─randomweapongenerator
│  │  │              ├─controller
│  │  │              ├─entity
│  │  │              ├─repository
│  │  │              └─service
│  │  └─resources
│  │      └─templates
│  └─test
│      └─java
│          └─com
│              └─tarkov
│                  └─randomweapongenerator
└─target
    ├─classes
    │  ├─com
    │  │  └─tarkov
    │  │      └─randomweapongenerator
    │  │          ├─controller
    │  │          ├─entity
    │  │          └─service
    │  └─templates
    ├─generated-sources
    │  └─annotations
    ├─generated-test-sources
    │  └─test-annotations
    ├─maven-archiver
    ├─maven-status
    │  └─maven-compiler-plugin
    │      ├─compile
    │      │  └─default-compile
    │      └─testCompile
    │          └─default-testCompile
    ├─surefire-reports
    └─test-classes
        └─com
            └─tarkov
                └─randomweapongenerator


这是一个类我取得的API。

@Service
public class FetchAPI {

    @Value("${graphql.endpoint}")
    private String GraphQLurl;
    private WebClient webClient=WebClient.create();


    public void SelectDataByWeaponId(String id){
        String query="{\"query\" :\"{ items { name }}\"}";
        
        String response=webClient.post()
            .uri(GraphQLurl)
            .header(HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_JSON_VALUE)
            .body(BodyInserters.fromValue(query))
            .retrieve()
            .bodyToMono(String.class)
            .block();
        
        System.out.println(response);
    }

}


第一次,我使用@Value("${graphql.endpoint}")在代码中链接API URL。所以我搜索了一个原因,我发现@ComponentScan,我必须用它来扫描和添加组件到一个容器!
这是我添加的代码。

@SpringBootApplication
@ComponentScan(basePackages = "com.tarkov.randomweapongenerator")
public class RandomWeaponGeneratorApplication {

    public static void main(String[] args) {
        SpringApplication.run(RandomWeaponGeneratorApplication.class, args);
        System.out.println("hello");
        FetchAPI api=new FetchAPI();
        api.SelectDataByWeaponId("");
    }

}


在SelectDataByWeaponId中,参数不需要填充。我现在没有在FetchAPI类中使用它。
我还确保我正确编写了application.properties文件。这是我在application.properties中设置的端点URL。
graphql.endpoint=https://api.tarkov.dev/graphql
该文件也被放置在正确的文件夹。
x1c 0d1x的数据
我使用命令“mvn clean install”和“java-jar result_file.jar”构建并执行项目。
请告诉我如何解决。谢谢!

wh6knrhe

wh6knrhe1#

Spring注解(如@Value)只能在Spring bean中工作,Spring bean由Spring在应用程序上下文中管理。
main方法中,你自己在Spring之外创建了FetchAPI类的示例:

FetchAPI api=new FetchAPI();
api.SelectDataByWeaponId("");

字符串
变量api引用的对象不是Spring管理的bean,因为您自己使用new示例化它。这样做时,不会处理诸如@Value之类的Spring注解,因此对象中的成员变量GraphQLurlnull
不要直接使用new示例化那些打算成为Spring bean的类。相反,让Spring在应用程序上下文中示例化和管理它们,并在需要使用它们时使用依赖注入(自动装配)。
你可以这样做:
首先,从主应用程序类中删除SpringApplication.run()之后的调用。您也可以删除@ComponentScan注解,因为它在本例中没有任何区别:

@SpringBootApplication
public class RandomWeaponGeneratorApplication {

    public static void main(String[] args) {
        SpringApplication.run(RandomWeaponGeneratorApplication.class, args);
    }
}


添加一个实现接口CommandLineRunner的类到你的应用程序中,你可以将FetchAPI的示例自动连接到这个类中,而不是自己用new创建它:

@Component
public class RandomWeaponGeneratorRunner implements CommandLineRunner {

    @Autowired
    private FetchAPI api;

    @Override
    public void run(String... args) {
        api.SelectDataByWeaponId("");
    }
}


Sping Boot 会在找到这个类时自动示例化并调用run方法。

km0tfn4u

km0tfn4u2#

这里的问题是,您有点将Plain Java对象创建与Spring(DI,IOC等)结合在一起。
你必须明白,@Valueannotation的处理是由BeanPostProcessor执行的,在你的特定情况下,这意味着你必须使用DI来访问这个值被初始化的类。
换句话说,非常简单。你不能合并

new FetchAPI(); with @Value annotation

字符串
(其实有一些方法,但不是这样的)。
如果你想遵循spring的方式,但做一些类似console runner的事情--你可以使用下面的代码

@SpringBootApplication
public class SpringBootConsoleApplication
    implements CommandLineRunner {

    private final FetchAPI fetchAPI; //Injection of your FetchAPI service bean using constructor

    @Autowired
    public SpringBootConsoleApplication(FetchAPI fetchAPI) {
        this.fetchAPI = fetchAPI;
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringBootConsoleApplication.class, args);
    }

    @Override
    public void run(String... args) {
        //call your singleton bean with already initiated @Value annotation inside
        fetchAPI.SelectDataByWeaponId("your ID");
    }
}

相关问题