Un collègue a signalé que l'annotation @Dict ne fonctionnait pas, bien que toute la configuration soit correcte. Après investigation, nous avons découvert que l'aspect chargé de traduire les dictionnaires n'était pas exécuté lors des appels API. Le point de coupure défini pour l'annottaion @Dict était :
public * org.jeecg.modules..*.*Controller.*(..))"
Or, le contrôleur en question était nommé MonControllerApp, ce qui ne correspondait pas au motif attendu. Deux solutions :
- Renommer le contrôleur pour qu'il corrresponde au motif par défaut (ex :
MonController). - Modifier le point de coupure dans la configuration du framework.
- L'aspect de traduction des dictionnaires ne gère que les objets IPage
L'aspect par défaut (DictAspect.java situé dans org/jeecg/modules/system/aspect/) ne traite que les résultats de type IPage. Cela pose problème lorsque l'on souhaite traduire des dictionnaires pour des résultats de type Map, List, objet simple ou JSONObject.
Pour étendre cette fonctionnalité, nous avons ajouté une branche else après le bloc if existant dans l'aspect, avec le code suivant :
else if (!(((Result)result).getResult() instanceof String)){
Object object = ((Result)result).getResult();
if (oConvertUtils.isEmpty(object)) return result;
Class<?> resultClass = ((Result)result).getResult().getClass();
if ("java.util.HashMap".equals(resultClass.getName())) {
Map<String, Object> sourceMap = (Map<String,Object>) object;
Map<String, Object> translatedMap = new HashMap<>();
for (String key : sourceMap.keySet()) {
Object value = sourceMap.get(key);
List<Object> records = new ArrayList<>();
if (value instanceof List) {
records = (List<Object>) value;
} else {
records = oConvertUtils.objToList(value, Object.class);
}
if (!checkHasDict(records)) continue;
List<JSONObject> translatedRecords = getDictTextForList(records);
translatedMap.put(key, translatedRecords);
}
((Result)result).setResult(translatedMap);
} else if (resultClass == List.class) {
List<Object> records = oConvertUtils.objToList(object, Object.class);
if (!checkHasDict(records)) return result;
List<JSONObject> translatedRecords = getDictTextForList(records);
((Result)result).setResult(translatedRecords);
} else {
Object record = ((Result)result).getResult();
// skip boolean types
if (record instanceof Boolean) return result;
log.debug(" __ Entrée dans l'aspect de traduction DictAspect —— ");
String json = "{}";
try {
json = objectMapper.writeValueAsString(record);
} catch (JsonProcessingException e) {
log.error("Erreur de sérialisation JSON : " + e.getMessage(), e);
}
JSONObject item = JSONObject.parseObject(json, Feature.OrderedField);
for (Field field : oConvertUtils.getAllFields(record)) {
String value = item.getString(field.getName());
if (oConvertUtils.isEmpty(value)) continue;
if (field.getAnnotation(Dict.class) != null) {
String code = field.getAnnotation(Dict.class).dicCode();
String text = field.getAnnotation(Dict.class).dicText();
String table = field.getAnnotation(Dict.class).dictTable();
String key = String.valueOf(item.get(field.getName()));
String fieldDictCode = code;
if (!StringUtils.isEmpty(table)) {
fieldDictCode = String.format("%s,%s,%s", table, text, code);
}
String textValue = this.translateDictValue(code, text, table, key);
log.debug(" Valeur du dictionnaire : " + textValue);
item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
}
}
((Result)result).setResult(item);
}
}
La méthode utilitaire getDictTextForList a également été ajoutée :
private List<JSONObject> getDictTextForList(List<Object> records) {
List<JSONObject> items = new ArrayList<>();
List<Field> dictFields = new ArrayList<>();
Map<String, List<String>> dataMap = new HashMap<>(5);
log.debug(" __ Entrée dans l'aspect de traduction DictAspect —— ");
for (Object record : records) {
String json = "{}";
try {
json = objectMapper.writeValueAsString(record);
} catch (JsonProcessingException e) {
log.error("Erreur de sérialisation JSON : " + e.getMessage(), e);
}
JSONObject item = JSONObject.parseObject(json, Feature.OrderedField);
for (Field field : oConvertUtils.getAllFields(record)) {
String value = item.getString(field.getName());
if (oConvertUtils.isEmpty(value)) continue;
if (field.getAnnotation(Dict.class) != null) {
if (!dictFields.contains(field)) dictFields.add(field);
String code = field.getAnnotation(Dict.class).dicCode();
String text = field.getAnnotation(Dict.class).dicText();
String table = field.getAnnotation(Dict.class).dictTable();
String dictCode = code;
if (!StringUtils.isEmpty(table)) {
dictCode = String.format("%s,%s,%s", table, text, code);
}
List<String> dataList = dataMap.computeIfAbsent(dictCode, k -> new ArrayList<>());
this.listAddAllDeduplicate(dataList, Arrays.asList(value.split(",")));
}
}
items.add(item);
}
// Traduction groupée
Map<String, List<DictModel>> translations = this.translateAllDict(dataMap);
for (JSONObject item : items) {
for (Field field : dictFields) {
String code = field.getAnnotation(Dict.class).dicCode();
String text = field.getAnnotation(Dict.class).dicText();
String table = field.getAnnotation(Dict.class).dictTable();
String dictCode = code;
if (!StringUtils.isEmpty(table)) {
dictCode = String.format("%s,%s,%s", table, text, code);
}
String value = item.getString(field.getName());
if (oConvertUtils.isNotEmpty(value)) {
List<DictModel> dictModels = translations.get(dictCode);
if (dictModels == null || dictModels.isEmpty()) continue;
String textValue = this.translDictText(dictModels, value);
log.debug(" Valeur du dictionnaire : " + textValue);
item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
}
}
}
return items;
}
Ces modifications permettent désormais de traudire les dictionnaires pour des objets simples, des listes et des maps, en plus des IPage.