onErrorResume () не будет вызван - PullRequest
0 голосов
/ 22 марта 2020

Я новичок ie для запуска webflux и реактора. Я хочу иметь запасной механизм, когда возникает какое-то конкретное c исключение, основанное на моих исследованиях метода onErrorResume, но оно не будет вызвано, и я получу 500 внутренняя ошибка сервера вместо моего отката сработала и предотвратила эту ошибку.

Примечание: я использую пружинный webflux, что означает, что он внес некоторые изменения в нормальное поведение проекта реактора

public Mono<Date> getExpirationDateFromToken(String token) {
    return getAllClaimsFromToken(token)
            .onErrorResume(ExpiredJwtException.class, e -> Mono.just(e.getClaims()))
            .map(Claims::getExpiration);
}

public Mono<Claims> getAllClaimsFromToken(String token) {
    return Mono.just(Jwts.parserBuilder()
            .setSigningKey(Base64.getEncoder().encodeToString(secret.getBytes()))
            .build()
            .parseClaimsJws(token)
            .getBody());
}

, и это трассировка стека

    io.jsonwebtoken.ExpiredJwtException: JWT expired at 2020-03-22T08:17:15Z. Current time: 2020-03-22T08:50:56Z, a difference of 2021835 milliseconds.  Allowed clock skew: 0 milliseconds.
        at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:439) ~[jjwt-impl-0.11.0.jar:0.11.0]
        Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
    Error has been observed at the following site(s):
        |_ checkpoint ⇢ Handler ir.siavash.customerservice.security.controller.AuthController#refreshToken(Mono) [DispatcherHandler]
        |_ checkpoint ⇢ org.springframework.security.web.server.authorization.AuthorizationWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ org.springframework.security.web.server.authentication.logout.LogoutWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ org.springframework.security.web.server.header.HttpHeaderWriterWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain]
        |_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
        |_ checkpoint ⇢ HTTP POST "/auth/refreshToken" [ExceptionHandlingWebHandler]
Stack trace:
        at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:439) ~[jjwt-impl-0.11.0.jar:0.11.0]
        at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:541) ~[jjwt-impl-0.11.0.jar:0.11.0]
        at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:601) ~[jjwt-impl-0.11.0.jar:0.11.0]
        at io.jsonwebtoken.impl.ImmutableJwtParser.parseClaimsJws(ImmutableJwtParser.java:173) ~[jjwt-impl-0.11.0.jar:0.11.0]
        at ir.siavash.customerservice.security.JWTUtil.getAllClaimsFromToken(JWTUtil.java:42) ~[classes/:na]

1 Ответ

2 голосов
/ 22 марта 2020

ок, на второй взгляд понятно. Это распространенная ошибка. Реактивные компоненты могут быть сложными для изучения, но вы не очень далеки от решения.

Mono.just принимает предварительно вычисленное значение в качестве параметра. Следовательно, ваш getAllClaimsFromToken создаст Mono только после того, как весь код, присвоенный просто , будет выполнен. Это означает, что ваша ошибка происходит до того, как любой реактивный компонент становится доступным для управления ошибками (время сборки).

Вместо этого вы можете использовать Mono # fromCallable , чтобы попросить Reactor вычислить токен Jwt на или создайте Mono только с начальной строкой, затем сопоставьте ее с помощью вашей функции.

Давайте посмотрим на второе решение:

public Mono<Date> getExpirationDateFromToken(String token) {
    return Mono.just(token)
            .map(this::getAllClaimsFromToken)
            .onErrorResume(ExpiredJwtException.class, e -> Mono.just(e.getClaims()))
            .map(Claims::getExpiration);
}

public Claims getAllClaimsFromToken(String token) {
    return Jwts.parserBuilder()
            .setSigningKey(Base64.getEncoder().encodeToString(secret.getBytes()))
            .build()
            .parseClaimsJws(token)
            .getBody();
}
...