Bladeren bron

优化i18n

zhouhao 3 jaren geleden
bovenliggende
commit
7666ea5f09

+ 19 - 2
hsweb-core/src/main/java/org/hswebframework/web/exception/I18nSupportException.java

@@ -5,6 +5,10 @@ import lombok.AccessLevel;
 import lombok.Getter;
 import lombok.Setter;
 import org.hswebframework.web.i18n.LocaleUtils;
+import reactor.core.publisher.Mono;
+
+import java.util.Locale;
+import java.util.Objects;
 
 /**
  * 支持国际化消息的异常,code为
@@ -45,11 +49,24 @@ public class I18nSupportException extends RuntimeException {
 
     @Override
     public String getMessage() {
+        if (Objects.equals(super.getMessage(), this.getI18nCode())) {
+            return getLocalizedMessage();
+        }
         return super.getMessage() != null ? super.getMessage() : getLocalizedMessage();
     }
 
     @Override
-    public String getLocalizedMessage() {
-        return LocaleUtils.resolveMessage(i18nCode, args);
+    public final String getLocalizedMessage() {
+        return getLocalizedMessage(LocaleUtils.current());
+    }
+
+    public String getLocalizedMessage(Locale locale) {
+        return LocaleUtils.resolveMessage(i18nCode, locale, getMessage(), args);
+    }
+
+    public final Mono<String> getLocalizedMessageReactive() {
+        return LocaleUtils
+                .currentReactive()
+                .map(this::getLocalizedMessage);
     }
 }

+ 32 - 10
hsweb-core/src/main/java/org/hswebframework/web/exception/ValidationException.java

@@ -6,10 +6,13 @@ import lombok.Getter;
 import lombok.Setter;
 import org.hswebframework.web.i18n.LocaleUtils;
 import org.springframework.http.HttpStatus;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.ResponseStatus;
 
 import javax.validation.ConstraintViolation;
 import java.util.*;
+import java.util.stream.Collectors;
 
 @Getter
 @Setter
@@ -31,9 +34,6 @@ public class ValidationException extends I18nSupportException {
     public ValidationException(String message, List<Detail> details, Object... args) {
         super(message, args);
         this.details = details;
-        for (Detail detail : this.details) {
-            detail.translateI18n(args);
-        }
     }
 
     public ValidationException(Set<? extends ConstraintViolation<?>> violations) {
@@ -48,23 +48,44 @@ public class ValidationException extends I18nSupportException {
 
         //{0} 属性 ,{1} 验证消息
         //property也支持国际化?
-        String resolveMessage = propertyI18nEnabled ?
-                LocaleUtils.resolveMessage(first.getRootBeanClass().getName() + "." + property, property)
+        String propertyI18n = propertyI18nEnabled ?
+                first.getRootBeanClass().getName() + "." + property
                 : property;
 
-        setArgs(new Object[]{resolveMessage, first.getMessage()});
+        setArgs(new Object[]{propertyI18n, first.getMessage()});
 
         details = new ArrayList<>(violations.size());
         for (ConstraintViolation<?> violation : violations) {
-            details.add(new Detail(violation.getPropertyPath().toString(), violation.getMessage(), null));
+            details.add(new Detail(violation.getPropertyPath().toString(),
+                                   violation.getMessage(),
+                                   null));
         }
     }
 
+    public List<Detail> getDetails(Locale locale) {
+        return CollectionUtils.isEmpty(details)
+                ? Collections.emptyList()
+                : details
+                .stream()
+                .map(detail -> detail.translateI18n(locale))
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public String getLocalizedMessage(Locale locale) {
+        if (propertyI18nEnabled && "validation.property_validate_failed".equals(getI18nCode()) && getArgs().length > 0) {
+            Object[] args = getArgs().clone();
+            args[0] = LocaleUtils.resolveMessage(String.valueOf(args[0]), locale, String.valueOf(args[0]));
+            return LocaleUtils.resolveMessage(getI18nCode(), locale, getMessage(), args);
+        }
+        return super.getLocalizedMessage(locale);
+    }
 
     @Getter
     @Setter
     @AllArgsConstructor
     public static class Detail {
+
         @Schema(description = "字段")
         String property;
 
@@ -74,10 +95,11 @@ public class ValidationException extends I18nSupportException {
         @Schema(description = "详情")
         Object detail;
 
-        public void translateI18n(Object... args) {
-            if (message.contains(".")) {
-                message = LocaleUtils.resolveMessage(message, message, args);
+        public Detail translateI18n(Locale locale) {
+            if (StringUtils.hasText(message) && message.contains(".")) {
+                return new Detail(property, LocaleUtils.resolveMessage(message, locale, message), detail);
             }
+            return this;
         }
     }
 }

+ 22 - 8
hsweb-core/src/test/java/org/hswebframework/web/validator/ValidatorUtilsTest.java

@@ -4,7 +4,9 @@ import lombok.Getter;
 import lombok.Setter;
 import org.hswebframework.web.exception.ValidationException;
 import org.hswebframework.web.i18n.LocaleUtils;
+import org.hswebframework.web.i18n.MessageSourceInitializer;
 import org.junit.Test;
+import org.springframework.context.support.StaticMessageSource;
 
 import javax.validation.constraints.NotBlank;
 
@@ -14,27 +16,39 @@ import static org.junit.Assert.*;
 
 public class ValidatorUtilsTest {
 
+    static {
+        System.setProperty("i18n.validation.property.enabled", "true");
+    }
 
     @Test
-    public void test(){
-        test(Locale.CHINA,"不能为空");
-        test(Locale.ENGLISH,"must not be blank");
+    public void test() {
+        StaticMessageSource source = new StaticMessageSource();
+        source.addMessage("validation.property_validate_failed", Locale.CHINA, "{0} {1}");
+        source.addMessage("validation.property_validate_failed", Locale.ENGLISH, "{0} {1}");
+
+        source.addMessage(TestEntity.class.getName() + ".notBlank", Locale.ENGLISH, "Test");
+        source.addMessage(TestEntity.class.getName() + ".notBlank", Locale.CHINA, "测试");
+
+        MessageSourceInitializer.init(source);
+        test(Locale.CHINA, "不能为空", "测试 不能为空");
+        test(Locale.ENGLISH, "must not be blank", "Test must not be blank");
     }
 
-    public void test(Locale locale,String msg){
+    public void test(Locale locale, String msg, String msg2) {
         try {
-            LocaleUtils.doWith(locale,en->{
+            LocaleUtils.doWith(locale, en -> {
                 ValidatorUtils.tryValidate(new TestEntity());
             });
             throw new IllegalStateException();
-        }catch (ValidationException e){
-            assertEquals(msg,e.getDetails().get(0).getMessage());
+        } catch (ValidationException e) {
+            assertEquals(msg, e.getDetails().get(0).getMessage());
+            assertEquals(msg2, e.getLocalizedMessage(locale));
         }
     }
 
     @Getter
     @Setter
-    public static class TestEntity{
+    public static class TestEntity {
 
         @NotBlank
         private String notBlank;