'Bean of type 'org.springframework.web.reactive.function.client.WebClient' that could not be found

I'm studying push notifications using the example of this manual https://golb.hplar.ch/2018/01/Sending-Web-push-messages-from-Spring-Boot-to-Browsers.html. I am faced with the problem that when I run the application, I get the error

Parameter 1 of constructor in ru.stepanb.MetricPushingApplication.push.PushChuckJokeService required could not be found. 

Consider defining a bean of type 'org.springframework.web.reactive.function.client.WebClient' in your configuration. " 

.

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;

@Service
public class PushChuckJokeService {

  private final FcmClient fcmClient;

  private final WebClient webClient;

  private int seq = 0;

  public PushChuckJokeService(FcmClient fcmClient, WebClient webClient) {
     this.fcmClient = fcmClient;
     this.webClient = webClient;
  }

  @Scheduled(fixedDelay = 30_000)
  public void sendChuckQuotes() {
    IcndbJoke joke = 
    this.webClient.get().uri("http://api.icndb.com/jokes/random")
    .retrieve().bodyToMono(IcndbJoke.class).block();
     try {
      sendPushMessage(joke);
     } 
    catch (InterruptedException | ExecutionException e) {
      //Application.logger.error("send chuck joke", e);
   }
  }

  void sendPushMessage(IcndbJoke joke) throws InterruptedException, 
    ExecutionException {
      Map<String, String> data = new HashMap<>();
      data.put("id", String.valueOf(joke.getValue().getId()));
      data.put("joke", joke.getValue().getJoke());
      data.put("seq", String.valueOf(this.seq++));
      data.put("ts", String.valueOf(System.currentTimeMillis()));

      System.out.println("Sending chuck joke...");
      this.fcmClient.send(data);
     }

  }

Here is my pom.xml file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>ru.stepanb</groupId>
<artifactId>MetricPushingApplication</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>MetricPushingApplication</name>
<description>Demo project for Spring Boot</description>

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

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
        <groupId>com.google.firebase</groupId>
        <artifactId>firebase-admin</artifactId>
        <version>6.8.1</version>
        <exclusions>
            <exclusion>
                <groupId>org.codehaus.jackson</groupId>
                <artifactId>jackson-core-asl</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.google.http-client</groupId>
                <artifactId>google-http-client-jackson</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.google.http-client</groupId>
                <artifactId>google-http-client-gson</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.google.api-client</groupId>
                <artifactId>google-api-client-gson</artifactId>
            </exclusion>
            <exclusion>
                <groupId>joda-time</groupId>
                <artifactId>joda-time</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.google.auto.value</groupId>
                <artifactId>auto-value</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.threeten</groupId>
                <artifactId>threetenbp</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.json</groupId>
                <artifactId>json</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.google.cloud</groupId>
                <artifactId>google-cloud-firestore</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.google.apis</groupId>
                <artifactId>google-api-services-storage</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpcore</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.google.api</groupId>
                <artifactId>gax</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.google.cloud</groupId>
                <artifactId>google-cloud-storage</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.google.code.findbugs</groupId>
        <artifactId>jsr305</artifactId>
        <version>3.0.2</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <debug>true</debug>
                <parameters>true</parameters>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-configuration-processor</artifactId>
                        <version>2.1.5.RELEASE</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>           
    </plugins>
</build>

And my controller

    import org.springframework.http.HttpStatus;
    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.ResponseStatus;
    import org.springframework.web.bind.annotation.RestController;

    import reactor.core.publisher.Mono;

    @RestController
    @CrossOrigin
    public class RegistryController {

        private final FcmClient fcmClient;

        public RegistryController(FcmClient fcmClient) {
            this.fcmClient = fcmClient;
        }

        @PostMapping("/register")
        @ResponseStatus(HttpStatus.NO_CONTENT)
        public Mono<Void> register(@RequestBody Mono<String> token) {
            return token.doOnNext(t -> this.fcmClient.subscribe("chuck", t)).then();
        }

    }

Could you also explain to me how the creation of a WebClient occurs at all when Spring application is created by this line?

SpringApplication.run(MetricPushingApplication.class, args);


Solution 1:[1]

There is no WebClient registered as bean.

You can simply use it like this:

WebClient.create().get().uri("http://api.icndb.com/jokes/random")
                  .retrieve().bodyToMono(IcndbJoke.class).block();

Or you use it like described in the Spring Boot Reference Manual

@Service
public class MyService {

    private final WebClient webClient;

    public MyService(WebClient.Builder webClientBuilder) {
        this.webClient = webClientBuilder.baseUrl("https://example.org").build();
    }

    public Mono<Details> someRestCall(String name) {
        return this.webClient.get().uri("/{name}/details", name)
                        .retrieve().bodyToMono(Details.class);
    }

}

See: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#io.rest-client.webclient

Solution 2:[2]

You should config the bean in the Configuration Class. For example:

@Configuration
    class Configuration{
    @Bean
    WebClient webClient(WebClient.Builder builder) {
        return builder.build();
    }
    }

And then you could use the webClient dependency in other class. For Example:

class otherClass{
 private WebClient client;
 //Your use
}

Solution 3:[3]

You should update the dependency to resolve the issue of 'org.springframework.web.reactive.function.client.WebClient' that could not be found

Please see this answer already posted.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 zb226
Solution 2 michael garcia
Solution 3 Praveen Kumar Verma