Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue with Spring Webflux webclient , nothing happens when trying to send post request

Have the following implementation of webclient :

    public <T> WebClient.ResponseSpec sendRequest(HttpMethod method, String contentType, T body, String baseUrl, String path) {
    try {
        WebClient webClient = WebClient.builder().baseUrl(baseUrl).filter(logRequest()).build();
        WebClient.ResponseSpec responseSpec = webClient.method(method)
                .uri(path)
                .header(HttpHeaders.CONTENT_TYPE, contentType)
                .body(BodyInserters.fromObject(body))
                .retrieve();
        return responseSpec;
    } catch (Exception e) {
        throw new WebClientProcessingException("Exception when trying to execute request", e);

    }
}

// This method returns filter function which will log request data
private static ExchangeFilterFunction logRequest() {
    return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
        LOGGER.info("Request: {} {} {}", clientRequest.method(), clientRequest.url(), clientRequest.body());
        clientRequest.headers().forEach((name, values) -> values.forEach(value -> LOGGER.info("{}={}", name, value)));
        return Mono.just(clientRequest);
    });
}

Also have the following code , which is creating user object and command which contains user object , then calling webclient to send an request

@Autowired
private BaseWebClient baseWebClient;
@Override
public void saveOrUpdateUser() {
        UserPayload userPayload = new UserPayload();
        userPayload.setUserId(111L);
        userPayload.setCreatedAt(ZonedDateTime.now(DateTimeProps.systemTimeZone));
        UserCommand userCommand = new UserCommand();
        userCommand.setUser(userPayload);
        baseWebClient.sendRequest(HttpMethod.POST, "application/json",
            Stream.of(userCommand).collect(Collectors.toList()),
            "http://localhost:8080",
            "/users").onStatus(HttpStatus::isError, clientResponse -> {
        throw new WebClientUserSaveOrUpdateeFailedException("Exception when trying to update user state")
        .bodyToMono(String.class);
    });
}

User payload :

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserPayload {
  Long userId;
  ZonedDateTime createdAt;
}

User command :

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserCommand {
     @JsonProperty("user")
     UserPayload user;
}

Json which is waiting for my other app (whom I am sending a request) :

[
  { "user":
            { 
              "userId": 1,
              "createdAt": "2019-05-16T08:24:46.412Z"
            } 
  }
]

Using : Spring boot 2 , Lombok (for getter/setter) , gradle When I'm trying to send a request nothing happens. No exception even. I tried with very simple case as well the same issue. One more note, is it possible to log body? I mean somehow see final json I guess I am missing something general.

like image 879
nairavs Avatar asked May 26 '19 15:05

nairavs


People also ask

Should I use WebClient or RestTemplate?

Conclusion RestTemplate uses Java Servlet API and is therefore synchronous and blocking. Conversely, WebClient is asynchronous and will not block the executing thread while waiting for the response to come back. The notification will be produced only when the response is ready. RestTemplate will still be used.

Can I use WebClient in spring MVC?

Webclient is part of the spring mvc project, and it will allow communication with http servers; after releasing spring 5, the web client is best and recommended for client communication. In addition, the webclient is a component that was used to make the calls with other services.

Is WebClient part of WebFlux?

WebClient is part of Spring 5's reactive web framework called Spring WebFlux. To use WebClient, you need to include the spring-webflux module in your project. Go to http://start.spring.io.

How to serve post requests using Spring Boot webflux using functional programming?

To write the client code, Spring provides WebClient API. Here we will create a Spring Boot WebFlux application to serve POST requests using functional programming. By default Spring Boot uses Reactor as reactive library and Netty as server.

What is spring webflux?

Sending HTTP requests with Spring WebClient In Spring 5, Spring gained a reactive web framework: Spring WebFlux. This is designed to co-exist alongside the existing Spring Web MVC APIs, but to add support for non-blocking designs.

When to notify callers about error in webflux?

There are different situations, when notifying callers about concrete reasons is important – think about server-side validations, business logic errors that come due to bad requests or simple not found situations. The mechanism of error handling in Webflux is different, from what we know from Spring MVC.

What is spring webclient example?

Spring WebClient – GET, PUT, POST, DELETE examples Spring WebClient is a non-blocking and reactive web client to perform HTTP requests. WebClient has been added in Spring 5 (spring-webflux module) and provides fluent functional style API.


1 Answers

In Reactor, nothing happens until you subscribe. retrive() does not actually start the request. As you can see in the example, you should use one of the method to convert the ResponseSpec to a Publisher and then eventually subscribe to that publisher.

Depending on how you're using this method, you might be able to let Spring subscribe to the publisher instead. WebFlux supports reactive types in the model which means you can directly return a Mono from your RestController methods, for example.

like image 156
Panda Avatar answered Oct 17 '22 21:10

Panda