Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SpringBoot5WebClient在检查HTTP响应头之前首先验证HTTPStatus_Java_Spring_Spring Boot_Spring Webflux - Fatal编程技术网

Java SpringBoot5WebClient在检查HTTP响应头之前首先验证HTTPStatus

Java SpringBoot5WebClient在检查HTTP响应头之前首先验证HTTPStatus,java,spring,spring-boot,spring-webflux,Java,Spring,Spring Boot,Spring Webflux,我试图用Spring5WebClient确认HTTP响应头的值,但前提是web调用使用HTTP200状态代码进行响应。在本用例中,如果身份验证未成功,则API调用返回HTTP 401,而不存在响应头。下面的代码在功能上是有效的,但它会进行两次web调用(因为我阻塞了两次)。除了只阻塞HTTP响应头,并在头不存在时为NPE设置try/catch之外,还有什么“更干净”的方法可以做到这一点吗 import java.net.URI; import java.time.Duration; impor

我试图用Spring5WebClient确认HTTP响应头的值,但前提是web调用使用HTTP200状态代码进行响应。在本用例中,如果身份验证未成功,则API调用返回HTTP 401,而不存在响应头。下面的代码在功能上是有效的,但它会进行两次web调用(因为我阻塞了两次)。除了只阻塞HTTP响应头,并在头不存在时为NPE设置try/catch之外,还有什么“更干净”的方法可以做到这一点吗

import java.net.URI;
import java.time.Duration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.ExchangeFunction;
import org.springframework.web.reactive.function.client.ExchangeFunctions;


import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@SpringBootApplication
public class ContentCheckerApplication {

private static final Logger LOGGER = LoggerFactory.getLogger(ContentCheckerApplication.class);

private ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector());         

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(ContentCheckerApplication.class);
    // prevent SpringBoot from starting a web server
    app.setWebApplicationType(WebApplicationType.NONE);
    app.run(args);
}

@Bean
public CommandLineRunner myCommandLineRunner() {

    return args -> {
              // Our reactive code will be declared here
        LinkedMultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();

        formData.add("username", args[2]);
        formData.add("password", args[3]);

        ClientRequest request = ClientRequest.method(HttpMethod.POST, new URI(args[0]+"/api/token"))
                .body(BodyInserters.fromFormData(formData)).build();

        Mono<ClientResponse> mresponse = exchange.exchange(request);
        Mono<String> mnewToken = mresponse.map(response -> response.headers().asHttpHeaders().getFirst("WSToken"));
        LOGGER.info("Blocking for status code...");
        HttpStatus statusCode = mresponse.block(Duration.ofMillis(1500)).statusCode();
        LOGGER.info("Got status code!");

        if (statusCode.value() == 200) {

            String newToken = mnewToken.block(Duration.ofMillis(1500));
            LOGGER.info("Auth token is: " + newToken);

        } else {
            LOGGER.info("Unable to authenticate successfully! Status code: "+statusCode.value());
        }
       };
    }
}
导入java.net.URI;
导入java.time.Duration;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入org.springframework.boot.CommandLineRunner;
导入org.springframework.boot.SpringApplication;
导入org.springframework.boot.WebApplicationType;
导入org.springframework.boot.autoconfigure.springboot应用程序;
导入org.springframework.context.annotation.Bean;
导入org.springframework.http.HttpMethod;
导入org.springframework.http.HttpStatus;
导入org.springframework.http.client.reactive.ReactorClientHttpConnector;
导入org.springframework.util.LinkedMultiValueMap;
导入org.springframework.web.reactive.function.BodyInserters;
导入org.springframework.web.reactive.function.client.ClientRequest;
导入org.springframework.web.reactive.function.client.ClientResponse;
导入org.springframework.web.reactive.function.client.ExchangeFunction;
导入org.springframework.web.reactive.function.client.ExchangeFunctions;
导入reactor.core.publisher.Flux;
导入reactor.core.publisher.Mono;
@SpringBoot应用程序
公共类ContentCheckerApplication{
私有静态最终记录器Logger=LoggerFactory.getLogger(ContentCheckerApplication.class);
私有ExchangeFunction exchange=ExchangeFunctions.create(新建ReactorClient TTPConnector());
公共静态void main(字符串[]args){
SpringApplication app=新的SpringApplication(ContentCheckerApplication.class);
//防止SpringBoot启动web服务器
app.setWebApplicationType(WebApplicationType.NONE);
应用程序运行(args);
}
@豆子
公共命令行运行程序myCommandLineRunner(){
返回参数->{
//我们的反应式代码将在这里声明
LinkedMultiValueMap formData=新LinkedMultiValueMap();
添加(“用户名”,参数[2]);
添加(“密码”,参数[3]);
ClientRequest=ClientRequest.method(HttpMethod.POST,新URI(args[0]+“/api/token”))
.body(BodyInserters.fromFormData(formData)).build();
Mono-mresponse=exchange.exchange(请求);
Mono mnewToken=mresponse.map(response->response.headers().asHttpHeaders().getFirst(“WSToken”);
LOGGER.info(“阻止状态代码…”);
HttpStatus statusCode=mresponse.block(持续时间为1500毫秒)).statusCode();
LOGGER.info(“获取状态代码!”);
如果(statusCode.value()==200){
字符串newToken=mnewToken.block(持续时间为1500毫米);
LOGGER.info(“身份验证令牌为:“+newToken”);
}否则{
LOGGER.info(“无法成功进行身份验证!状态代码:+statusCode.value());
}
};
}
}

多亏@M.Deinum的评论来指导我,我有以下代码,现在可以使用了

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.ExchangeFunction;
import org.springframework.web.reactive.function.client.ExchangeFunctions;
import org.springframework.web.reactive.function.client.WebClient;

import reactor.core.publisher.Mono;

@SpringBootApplication
public class ContentCheckerApplication {

private static final Logger LOGGER = LoggerFactory.getLogger(ContentCheckerApplication.class);

private ExchangeFunction exchange = ExchangeFunctions.create(new ReactorClientHttpConnector());         

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(ContentCheckerApplication.class);
    // prevent SpringBoot from starting a web server
    app.setWebApplicationType(WebApplicationType.NONE);
    app.run(args);
}

@Bean
public CommandLineRunner myCommandLineRunner() {

    return args -> {
              // Change some Netty defaults
        ReactorClientHttpConnector connector = new ReactorClientHttpConnector(
                  options -> options.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000)
                                    .compression(true)
                                    .afterNettyContextInit(ctx -> {
                                        ctx.addHandlerLast(new ReadTimeoutHandler(1500, TimeUnit.MILLISECONDS));
                                    }));


        LinkedMultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();

        formData.add("username", args[2]);
        formData.add("password", args[3]);

        WebClient webClient = WebClient.builder().clientConnector(connector).build();

            Mono<String> tokenResult = webClient.post()
                    .uri( args[0] + "/api/token" )
                    .body( BodyInserters.fromFormData(formData))
                    .exchange()
                    .onErrorMap(ContentCheckerApplication::handleAuthTokenError)
                    .map(response -> {

                            if (HttpStatus.OK.equals(response.statusCode())) {
                                return response.headers().asHttpHeaders().getFirst("WSToken");
                            } else {
                                return "";
                            }

                    });

            LOGGER.info("Subscribing for the result and then going to sleep");
            tokenResult.subscribe(ContentCheckerApplication::handleAuthTokenResponse);

        Thread.sleep(3600000);
       };
    }

private static Throwable handleAuthTokenError(Throwable e) {
    LOGGER.error("Exception caught trying to process authentication token. ",e);
    ContentCheckerApplication.handleAuthTokenResponse("");      
    return null;        
}

private static void handleAuthTokenResponse(String newToken) {

    LOGGER.info("Got status code!");

    if (!newToken.isEmpty()) {

        LOGGER.info("Auth token is: " + newToken);

    } else {
        LOGGER.info("Unable to authenticate successfully!");
    }

    System.exit(0);
}
}
import org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入org.springframework.boot.CommandLineRunner;
导入org.springframework.boot.SpringApplication;
导入org.springframework.boot.WebApplicationType;
导入org.springframework.boot.autoconfigure.springboot应用程序;
导入org.springframework.context.annotation.Bean;
导入org.springframework.http.HttpStatus;
导入org.springframework.http.client.reactive.ReactorClientHttpConnector;
导入org.springframework.util.LinkedMultiValueMap;
导入org.springframework.web.reactive.function.BodyInserters;
导入org.springframework.web.reactive.function.client.ExchangeFunction;
导入org.springframework.web.reactive.function.client.ExchangeFunctions;
导入org.springframework.web.reactive.function.client.WebClient;
导入reactor.core.publisher.Mono;
@SpringBoot应用程序
公共类ContentCheckerApplication{
私有静态最终记录器Logger=LoggerFactory.getLogger(ContentCheckerApplication.class);
私有ExchangeFunction exchange=ExchangeFunctions.create(新建ReactorClient TTPConnector());
公共静态void main(字符串[]args){
SpringApplication app=新的SpringApplication(ContentCheckerApplication.class);
//防止SpringBoot启动web服务器
app.setWebApplicationType(WebApplicationType.NONE);
应用程序运行(args);
}
@豆子
公共命令行运行程序myCommandLineRunner(){
返回参数->{
//改变一些棘手的默认设置
ReactorClientHttpConnector连接器=新的ReactorClientHttpConnector(
选项->选项.option(ChannelOption.CONNECT\u TIMEOUT\u MILLIS,2000)
.压缩(真)
.AfterNettyContact(ctx->{
addHandlerLast(新的ReadTimeoutHandler(1500,TimeUnit.ms));
}));
LinkedMultiValueMap formData=新LinkedMultiValueMap();
添加(“用户名”,参数[2]);
添加(“密码”,参数[3]);
WebClient WebClient=WebClient.builder().clientConnector(connector.build();
Mono-tokenResult=webClient.post()
.uri(args[0]+“/api/token”)
.body(BodyInserters.fromFormData(formData))
.exchange()
.OneErrorMap(ContentCheckerApplication::handleAuthTokenError)
.map(响应->{
if(HttpStatus.OK.equals(response.statusCode())){