zhou-hao 3 years ago
parent
commit
e4187d3d9c

+ 19 - 28
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonErrorControllerAdvice.java

@@ -2,6 +2,7 @@ package org.hswebframework.web.crud.web;
 
 import io.r2dbc.spi.R2dbcDataIntegrityViolationException;
 import lombok.extern.slf4j.Slf4j;
+import org.hswebframework.web.CodeConstants;
 import org.hswebframework.web.authorization.exception.AccessDenyException;
 import org.hswebframework.web.authorization.exception.AuthenticationException;
 import org.hswebframework.web.authorization.exception.UnAuthorizedException;
@@ -13,7 +14,6 @@ import org.hswebframework.web.exception.ValidationException;
 import org.hswebframework.web.i18n.LocaleUtils;
 import org.hswebframework.web.logger.ReactiveLogger;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
-import org.springframework.context.MessageSource;
 import org.springframework.core.annotation.Order;
 import org.springframework.http.HttpStatus;
 import org.springframework.validation.BindException;
@@ -37,18 +37,11 @@ import java.util.stream.Collectors;
 @Order
 public class CommonErrorControllerAdvice {
 
-    private final MessageSource messageSource;
-
-    public CommonErrorControllerAdvice(MessageSource messageSource) {
-        this.messageSource = messageSource;
-    }
-
     @ExceptionHandler
     @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
     public Mono<ResponseMessage<Object>> handleException(BusinessException e) {
         return LocaleUtils
-                .resolveThrowable(messageSource,
-                                  e,
+                .resolveThrowable(e,
                                   (err, msg) -> ResponseMessage.error(err.getStatus(), err.getCode(), msg));
     }
 
@@ -56,14 +49,14 @@ public class CommonErrorControllerAdvice {
     @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
     public Mono<ResponseMessage<?>> handleException(UnsupportedOperationException e) {
         return LocaleUtils
-                .resolveThrowable(messageSource, e, (err, msg) -> (ResponseMessage.<TokenState>error(401, "unsupported", msg)));
+                .resolveThrowable(e, (err, msg) -> (ResponseMessage.<TokenState>error(401, CodeConstants.Error.unsupported, msg)));
     }
 
     @ExceptionHandler
     @ResponseStatus(HttpStatus.UNAUTHORIZED)
     public Mono<ResponseMessage<TokenState>> handleException(UnAuthorizedException e) {
         return LocaleUtils
-                .resolveThrowable(messageSource, e, (err, msg) -> (ResponseMessage.<TokenState>error(401, "unauthorized", msg)
+                .resolveThrowable(e, (err, msg) -> (ResponseMessage.<TokenState>error(401, CodeConstants.Error.unauthorized, msg)
                         .result(e.getState())));
     }
 
@@ -71,7 +64,7 @@ public class CommonErrorControllerAdvice {
     @ResponseStatus(HttpStatus.FORBIDDEN)
     public Mono<ResponseMessage<Object>> handleException(AccessDenyException e) {
         return LocaleUtils
-                .resolveThrowable(messageSource, e, (err, msg) -> ResponseMessage.error(403, e.getCode(), e.getMessage()))
+                .resolveThrowable(e, (err, msg) -> ResponseMessage.error(403, e.getCode(), e.getMessage()))
                 ;
     }
 
@@ -79,7 +72,7 @@ public class CommonErrorControllerAdvice {
     @ResponseStatus(HttpStatus.NOT_FOUND)
     public Mono<ResponseMessage<Object>> handleException(NotFoundException e) {
         return LocaleUtils
-                .resolveThrowable(messageSource, e, (err, msg) -> ResponseMessage.error(404, "not_found", msg))
+                .resolveThrowable(e, (err, msg) -> ResponseMessage.error(404, CodeConstants.Error.not_found, msg))
                 ;
     }
 
@@ -87,8 +80,8 @@ public class CommonErrorControllerAdvice {
     @ResponseStatus(HttpStatus.BAD_REQUEST)
     public Mono<ResponseMessage<List<ValidationException.Detail>>> handleException(ValidationException e) {
         return LocaleUtils
-                .resolveThrowable(messageSource, e, (err, msg) -> ResponseMessage
-                        .<List<ValidationException.Detail>>error(400, "illegal_argument",msg)
+                .resolveThrowable(e, (err, msg) -> ResponseMessage
+                        .<List<ValidationException.Detail>>error(400, CodeConstants.Error.illegal_argument, msg)
                         .result(e.getDetails()))
                 ;
     }
@@ -139,14 +132,14 @@ public class CommonErrorControllerAdvice {
     @ExceptionHandler
     @ResponseStatus(HttpStatus.BAD_REQUEST)
     public Mono<ResponseMessage<?>> handleException(javax.validation.ValidationException e) {
-        return Mono.just(ResponseMessage.error(400, "illegal_argument", e.getMessage()));
+        return Mono.just(ResponseMessage.error(400, CodeConstants.Error.illegal_argument, e.getMessage()));
     }
 
     @ExceptionHandler
     @ResponseStatus(HttpStatus.GATEWAY_TIMEOUT)
     public Mono<ResponseMessage<Object>> handleException(TimeoutException e) {
 
-        return Mono.just(ResponseMessage.error(504, "timeout", e.getMessage()))
+        return Mono.just(ResponseMessage.error(504, CodeConstants.Error.timeout, e.getMessage()))
                    .doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
 
     }
@@ -173,7 +166,7 @@ public class CommonErrorControllerAdvice {
     public Mono<ResponseMessage<Object>> handleException(IllegalArgumentException e) {
 
         return LocaleUtils
-                .resolveThrowable(messageSource, e, (err, msg) -> ResponseMessage.error(400, "illegal_argument", msg))
+                .resolveThrowable(e, (err, msg) -> ResponseMessage.error(400, CodeConstants.Error.illegal_argument, msg))
                 .doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)))
                 ;
     }
@@ -182,7 +175,7 @@ public class CommonErrorControllerAdvice {
     @ResponseStatus(HttpStatus.BAD_REQUEST)
     public Mono<ResponseMessage<Object>> handleException(AuthenticationException e) {
         return LocaleUtils
-                .resolveThrowable(messageSource, e, (err, msg) -> ResponseMessage.error(400, e.getCode(), msg))
+                .resolveThrowable(e, (err, msg) -> ResponseMessage.error(400, e.getCode(), msg))
                 .doOnEach(ReactiveLogger.onNext(r -> log.error(e.getLocalizedMessage(), e)))
                 ;
     }
@@ -191,7 +184,7 @@ public class CommonErrorControllerAdvice {
     @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
     public Mono<ResponseMessage<Object>> handleException(UnsupportedMediaTypeStatusException e) {
         return LocaleUtils
-                .resolveMessageReactive(messageSource, "error.unsupported_media_type")
+                .resolveMessageReactive("error.unsupported_media_type")
                 .map(msg -> ResponseMessage
                         .error(415, "unsupported_media_type", msg)
                         .result(e.getSupportedMediaTypes()))
@@ -203,7 +196,7 @@ public class CommonErrorControllerAdvice {
     public Mono<ResponseMessage<Object>> handleException(NotAcceptableStatusException e) {
 
         return LocaleUtils
-                .resolveMessageReactive(messageSource, "error.not_acceptable_media_type")
+                .resolveMessageReactive("error.not_acceptable_media_type")
                 .map(msg -> ResponseMessage
                         .error(406, "not_acceptable_media_type", msg)
                         .result(e.getSupportedMediaTypes()))
@@ -214,7 +207,7 @@ public class CommonErrorControllerAdvice {
     @ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
     public Mono<ResponseMessage<Object>> handleException(MethodNotAllowedException e) {
         return LocaleUtils
-                .resolveMessageReactive(messageSource, "error.method_not_allowed")
+                .resolveMessageReactive("error.method_not_allowed")
                 .map(msg -> ResponseMessage
                         .error(406, "method_not_allowed", msg)
                         .result(e.getSupportedMethods()))
@@ -233,7 +226,7 @@ public class CommonErrorControllerAdvice {
             log.warn(e.getMessage(), e);
         }
         return LocaleUtils
-                .resolveMessageReactive(messageSource, code)
+                .resolveMessageReactive(code)
                 .map(msg -> ResponseMessage.error(400, code, msg));
     }
 
@@ -251,17 +244,15 @@ public class CommonErrorControllerAdvice {
         } while (exception != null && exception != e);
 
         return LocaleUtils
-                .resolveThrowable(messageSource,
-                                  exception,
-                                  (err, msg) -> ResponseMessage.error(400, "illegal_argument", msg));
+                .resolveThrowable(exception,
+                                  (err, msg) -> ResponseMessage.error(400, CodeConstants.Error.illegal_argument, msg));
     }
 
     @ExceptionHandler
     @ResponseStatus(HttpStatus.BAD_REQUEST)
     public Mono<ResponseMessage<Object>> handleException(I18nSupportException e) {
         return LocaleUtils
-                .resolveThrowable(messageSource,
-                                  e,
+                .resolveThrowable(e,
                                   (err, msg) -> ResponseMessage.error(400, err.getCode(), msg));
     }
 

+ 2 - 3
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonWebFluxConfiguration.java

@@ -5,7 +5,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
 import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.context.MessageSource;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.ReactiveAdapterRegistry;
@@ -19,8 +18,8 @@ public class CommonWebFluxConfiguration {
 
     @Bean
     @ConditionalOnMissingBean
-    public CommonErrorControllerAdvice commonErrorControllerAdvice(MessageSource messageSource) {
-        return new CommonErrorControllerAdvice(messageSource);
+    public CommonErrorControllerAdvice commonErrorControllerAdvice() {
+        return new CommonErrorControllerAdvice();
     }
 
 

+ 17 - 0
hsweb-core/src/main/java/org/hswebframework/web/CodeConstants.java

@@ -0,0 +1,17 @@
+package org.hswebframework.web;
+
+public interface CodeConstants {
+
+    interface Error {
+        String illegal_argument = "illegal_argument";
+
+        String timeout = "timeout";
+
+        String unsupported = "unsupported";
+
+        String unauthorized = "unauthorized";
+
+        String not_found="not_found";
+    }
+
+}

+ 93 - 7
hsweb-core/src/main/java/org/hswebframework/web/i18n/LocaleUtils.java

@@ -1,7 +1,9 @@
 package org.hswebframework.web.i18n;
 
 import org.hswebframework.web.exception.I18nSupportException;
+import org.reactivestreams.Publisher;
 import org.springframework.context.MessageSource;
+import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 import reactor.core.publisher.Signal;
 import reactor.core.publisher.SignalType;
@@ -15,11 +17,19 @@ import java.util.function.Function;
 
 /**
  * 用于进行国际化消息转换
+ * 常用方法:
+ *
+ * <ul>
+ *  <li>{@link LocaleUtils#current()} </li>
+ *  <li>{@link LocaleUtils#currentReactive()}</li>
+ *  <li>{@link LocaleUtils#resolveMessageReactive(String, Object...)}</li>
+ *  <li>{@link LocaleUtils#doOnNext(BiConsumer)}</li>
+ * </ul>
  *
  * @author zhouhao
  * @since 4.0.11
  */
-public class LocaleUtils {
+public final class LocaleUtils {
 
     public static final Locale DEFAULT_LOCALE = Locale.getDefault();
 
@@ -244,6 +254,19 @@ public class LocaleUtils {
                 });
     }
 
+    /**
+     * 使用默认的消息源,响应式方式解析消息
+     *
+     * @param code 消息编码
+     * @param args 参数
+     * @return 解析后的消息
+     */
+    public static Mono<String> resolveMessageReactive(String code,
+                                                      Object... args) {
+        return currentReactive()
+                .map(locale -> resolveMessage(messageSource, locale, code, code, args));
+    }
+
     /**
      * 使用指定的消息源,响应式方式解析消息
      *
@@ -350,14 +373,77 @@ public class LocaleUtils {
         };
     }
 
-    /* SignalType.ON_NEXT */
-    public static <T> Consumer<Signal<T>> onNext(BiConsumer<T, Locale> operation) {
-        return on(SignalType.ON_NEXT, (s, l) -> operation.accept(s.get(), l));
+    /**
+     * 在响应式的各个周期获取地区并执行指定的操作
+     *
+     * <pre>
+     *     monoOrFlux
+     *     .as(LocaleUtils.doOn(ON_NEXT,(signal,locale)-> ... ))
+     *     ...
+     * </pre>
+     *
+     * @param type      周期类型
+     * @param operation 操作
+     * @param <E>       响应式流中元素类型
+     * @param <T>       响应式流类型
+     * @return 原始流
+     */
+    @SuppressWarnings("all")
+    public static <E, T extends Publisher<E>> Function<T, T> doOn(SignalType type, BiConsumer<Signal<E>, Locale> operation) {
+        return publisher -> {
+            if (publisher instanceof Mono) {
+                return (T) Mono
+                        .from(publisher)
+                        .doOnEach(on(type, operation));
+            }
+            return (T) Flux
+                    .from(publisher)
+                    .doOnEach(on(type, operation));
+        };
+    }
+
+    /**
+     * <pre>
+     * monoOrFlux
+     * .as(LocaleUtils.doOnNext(element-> .... ))
+     * ...
+     * </pre>
+     */
+    public static <E, T extends Publisher<E>> Function<T, T> doOnNext(Consumer<E> operation) {
+        return doOn(SignalType.ON_NEXT, (s, l) -> operation.accept(s.get()));
+    }
+
+    /**
+     * <pre>
+     * monoOrFlux
+     * .as(LocaleUtils.doOnNext((element,locale)-> .... ))
+     * ...
+     * </pre>
+     */
+    public static <E, T extends Publisher<E>> Function<T, T> doOnNext(BiConsumer<E, Locale> operation) {
+        return doOn(SignalType.ON_NEXT, (s, l) -> operation.accept(s.get(), l));
     }
 
-    /* SignalType.ON_ERROR */
-    public static <T> Consumer<Signal<T>> onError(BiConsumer<Throwable, Locale> operation) {
-        return on(SignalType.ON_ERROR, (s, l) -> operation.accept(s.getThrowable(), l));
+    /**
+     * <pre>
+     * monoOrFlux
+     * .as(LocaleUtils.doOnError(error-> .... ))
+     * ...
+     * </pre>
+     */
+    public static <E, T extends Publisher<E>> Function<T, T> doOnError(Consumer<Throwable> operation) {
+        return doOn(SignalType.ON_ERROR, (s, l) -> operation.accept(s.getThrowable()));
+    }
+
+    /**
+     * <pre>
+     * monoOrFlux
+     * .as(LocaleUtils.doOnError((error,locale)-> .... ))
+     * ...
+     * </pre>
+     */
+    public static <E, T extends Publisher<E>> Function<T, T> doOnError(BiConsumer<Throwable, Locale> operation) {
+        return doOn(SignalType.ON_ERROR, (s, l) -> operation.accept(s.getThrowable(), l));
     }
 
 }

+ 25 - 0
hsweb-core/src/test/java/org/hswebframework/web/i18n/LocaleUtilsTest.java

@@ -0,0 +1,25 @@
+package org.hswebframework.web.i18n;
+
+import org.junit.Test;
+import reactor.core.publisher.Flux;
+
+import java.util.Locale;
+
+import static org.junit.Assert.*;
+
+public class LocaleUtilsTest {
+
+
+    @Test
+    public void testOnNext() {
+        Flux.just(1)
+            .as(LocaleUtils.doOnNext((i, l) -> {
+                assertEquals(i.intValue(), 1);
+                assertEquals(l, Locale.CHINA);
+            }))
+            .subscriberContext(LocaleUtils.useLocale(Locale.CHINA))
+            .blockLast();
+    }
+
+
+}