Maison  >  Article  >  Java  >  Comment Springboot+AOP implémente l'internationalisation des invites de données de retour

Comment Springboot+AOP implémente l'internationalisation des invites de données de retour

WBOY
WBOYavant
2023-05-29 15:45:331319parcourir

Texte

Premier coup d'oeil à la structure des répertoires du projet de cet exemple de tutoriel :

Comment Springboot+AOP implémente linternationalisation des invites de données de retour

(Bien sûr, le dossier i18n et les trois fichiers de propriétés de la ressource doivent également être construits par nous-mêmes, mais ne vous inquiétez pas pour le Resource Bundle, c'est dans yml Plus les éléments de configuration correspondants sont automatiquement générés. Si vous n'êtes pas sûr, continuez simplement à lire le tutoriel ci-dessous)

Commencez à taper le code (CV) :

pom.xml Dépendance :

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.68</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

. Énumération du code de retour

CodeEnum. java

/**
 * @author JCccc
 */
public enum CodeEnum {
 
    SUCCESS(1000, "请求成功"),
    FAIL(2000, "请求失败");
    public final int code;
    public final String msg;
    public Integer getCode() {
        return this.code;
    }
    CodeEnum(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public String getMsg() {
        return this.msg;
    }
}

Encapsulation simple des données de retour

ResultData.java

import com.test.myi18n.enums.CodeEnum;
import lombok.Data;
 
/**
 * @author JCccc
 */
@Data
public class ResultData<T> {
    private Integer code;
    private String message;
    private T data;
    public ResultData(int code, String message) {
        this.code = code;
        this.message = message;
    }
    public static ResultData success(CodeEnum codeEnum) {
        return new ResultData(codeEnum.code, codeEnum.msg);
    }
    public static ResultData success(String msg) {
        return new ResultData(CodeEnum.SUCCESS.getCode(),msg);
    }
}

Locale, encapsulation de méthode simple de MessageSource

LocaleMessage.java

rr cours d'outil de conversion de langue reee

i18n

I1 8nUtils.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
 
import java.util.Locale;
 
/**
 * @author JCccc
 */
@Component
public class LocaleMessage {
    @Autowired
    private MessageSource messageSource;
    public String getMessage(String code){
        return this.getMessage(code,new Object[]{});
    }
    public String getMessage(String code,String defaultMessage){
        return this.getMessage(code,null,defaultMessage);
    }
    public String getMessage(String code,String defaultMessage,Locale locale){ return this.getMessage(code,null,defaultMessage,locale); }
    public String getMessage(String code,Locale locale){
        return this.getMessage(code,null,"",locale);
    }
    public String getMessage(String code,Object[] args){ return this.getMessage(code,args,""); }
    public String getMessage(String code,Object[] args,Locale locale){
        return this.getMessage(code,args,"",locale);
    }
    public String getMessage(String code,Object[] args,String defaultMessage){ return this.getMessage(code,args, defaultMessage,LocaleContextHolder.getLocale()); }
    public String getMessage(String code,Object[]args,String defaultMessage,Locale locale){ return messageSource.getMessage(code,args, defaultMessage,locale); }
}

L'étape suivante est une étape clé de notre conversion. La méthode aop intercepte les données renvoyées par l'interface du contrôleur :

LanguageAspect.java

import java.util.Locale;
import com.test.myi18n.message.LocaleMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class I18nUtils {
 
    @Autowired
    private LocaleMessage localeMessage;
 
    /**
     * 获取key
     *
     * @param key
     * @return
     */
    public  String getKey(String key) {
        String name = localeMessage.getMessage(key);
        return name;
    }
 
    /**
     * 获取指定哪个配置文件下的key
     *
     * @param key
     * @param local
     * @return
     */
    public  String getKey(String key, Locale local) {
        String name = localeMessage.getMessage(key, local);
        return name;
    }
}

Une interprétation simple du code :

1. L'adresse de l'annotationLangCut au-dessus du contrôle de coupe de point doit être modifiée par vous-même. Remplacez-la par le chemin du dossier que vous souhaitez contrôler

2. Annotation @ConditionalOnProperty, lisez l'élément de configuration commençant par lang dans le yml, le la clé est ouverte, la valeur est vraie

Seulement si elle est vraie, cette interception aop prendra effet

3. String langFlag = request.getHeader("lang");
Vous pouvez voir dans cette phrase que ce que j'ai adopté dans cet article a pour but de laisser l'interface d'accueil (front-end) transmettre l'indicateur de langue qui doit être utilisé dans l'en-tête. Par exemple, transmettre EN (anglais) signifie que la langue de l'invite doit être convertie en anglais.

Vous pouvez combiner la situation réelle de votre projet et la modifier pour lire depuis yml, lire depuis la base de données, lire depuis redis, etc.

4. ResultData r = (ResultData) obj;
String msg = r.getMessage().trim();

Le but de ces deux lignes de code est d'obtenir l'invite de message dans l'obj intercepté. Les données renvoyées ne sont pas les ResultData utilisées dans mon article, vous devez donc effectuer vous-même des ajustements magiques.

Les derniers sont trois fichiers de propriétés du mess :

mess.properties

Langage de retour personnalisé = Bonjour, si l'article vous est utile, merci de suivre + favori + commentaire

Ce fichier suit l'aop de cet article Dans la méthode d'interception, la valeur actuelle de l'indicateur de langue sera détectée en premier. Si elle n'est pas détectée, elle sera trouvée dans le fichier
mess.properties.

mess_en_US.properties

request success=success
request failed=fail

mess_zh_CN.properties

request success=request success
request failed=request failed
success=request success
fail=request échec

Enfin, écrivez une interface de test pour démontrer l'effet à tout le monde :

import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
 
import javax.servlet.http.HttpServletRequest;
import java.util.*;
 
/**
 * @author JCccc
 */
@Aspect
@Component
@AllArgsConstructor
@ConditionalOnProperty(prefix = "lang", name = "open", havingValue = "true")
public class LanguageAspect {
    @Autowired
    I18nUtils i18nUtils;
 
    @Pointcut("execution(* com.test.myi18n.controller.*.*(..)))")
    public void annotationLangCut() {
    }
 
    /**
     * 拦截controller层返回的结果,修改msg字段
     *
     * @param point
     * @param obj
     */
    @AfterReturning(pointcut = "annotationLangCut()", returning = "obj")
    public void around(JoinPoint point, Object obj) {
        Object resultObject = obj;
        try {
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            //从获取RequestAttributes中获取HttpServletRequest的信息
            HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
            String langFlag = request.getHeader("lang");
            if (null != langFlag) {
                ResultData r = (ResultData) obj;
                String msg = r.getMessage().trim();
                if (StringUtils.isNotEmpty(msg)) {
                    if ("CN".equals(langFlag)) {
                        Locale locale = Locale.CHINA;
                        msg = i18nUtils.getKey(msg, locale);
                    } else if ("EN".equals(langFlag)) {
                        Locale locale = Locale.US;
                        msg = i18nUtils.getKey(msg, locale);
                    } else {
                        msg = i18nUtils.getKey(msg);
                    }
                }
                r.setMessage(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            //返回原值
            obj = resultObject;
        }
    }
}

Appelez le test :

Comment Springboot+AOP implémente linternationalisation des invites de données de retour

Comment Springboot+AOP implémente linternationalisation des invites de données de retour

Comment Springboot+AOP implémente linternationalisation des invites de données de retour

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer