优化i18n

This commit is contained in:
zhouhao
2022-03-24 16:48:53 +08:00
parent 0da2441a69
commit 7666ea5f09
3 changed files with 75 additions and 22 deletions

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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 {
@Test
public void test(){
test(Locale.CHINA,"不能为空");
test(Locale.ENGLISH,"must not be blank");
static {
System.setProperty("i18n.validation.property.enabled", "true");
}
public void test(Locale locale,String msg){
@Test
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, 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;