Java | | après avoir lu le Code que j'ai écrit en deuxième année, j'ai commencé à imiter silencieusement...

Tangcheng 2021-11-25 17:15:26
java apr avoir lu le

Contexte

Voilà ce qui s'est passé.,En ce moment, je suis impliqué dans XXXX Construction du projet,Besoin d'interfaces d'amarrage avec des tiers.Il y a plusieurs notifications asynchrones dans l'interface de l'autre,Pour la sécurité de l'interface,Les paramètres de l'interface doivent être vérifiés et signés.

Pour faciliter le traitement des paramètres de retour des notifications asynchrones,Z Le collègue propose d'encapsuler uniformément la fonction d'inspection des étiquettes,Tout ce que vous devez faire, c'est vous concentrer sur votre logique d'entreprise.

ZLa solution du collègue

Z Les collègues ont choisi“Analyseur de paramètres personnalisé”Solutions pour,Ensuite, regardons le Code.

Commentaires personnalisés

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface RsaVerify {
    
    /**
     * Si la fonction de vérification des signatures est activée,Vérification par défaut
     */
    boolean verifySign() default true;
}

Analyseur de paramètres de méthode personnalisé

@AllArgsConstructor
@Component
//Réalisation HandlerMethodArgumentResolver Interface
public class RsaVerifyArgumentResolver implements HandlerMethodArgumentResolver {
    private final SecurityService securityService;
    /**
     * Cette méthode est utilisée pour déterminer si l'interface demandée doit analyser les paramètres,
     * Retour si nécessaire true,Puis appelez ce qui suit resolveArgument Méthodes,
     *  Si le retour n'est pas nécessaire false
     */
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RsaVerify.class);
    }
    /**
     * La vraie méthode d'analyse,Résoudre la valeur du paramètre dans la requête à un objet
     * parameter Paramètres de la méthode à analyser
     * mavContainer Demande actuelle ModelAndViewContainer(Fournir l'accès au modèle pour la demande)
     * webRequest Demande actuelle
     * WebDataBinderFactory Pour créer WebDataBinder L'usine de
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        RsaVerify parameterAnnotation = parameter.getParameterAnnotation(RsaVerify.class);
        if (!parameterAnnotation.verifySign()) {
            return mavContainer.getModel();
        }
        
        //Logique de traitement et de vérification des paramètres
        ......
        
        //Renvoie le paramètre de classe d'entité traité
        return ObjectMapperFactory
                .getDateTimeObjectMapper("yyyyMMddHHmmss")
                .readValue(StringUtil.queryParamsToJson(sb.toString()), parameter.getParameterType());
    }
   
}

Créer une classe de configuration

@Configuration
@AllArgsConstructor
public class PayTenantWebConfig implements WebMvcConfigurer {
    private final RsaVerifyArgumentResolver rsaVerifyArgumentResolver;
    
    /**
     * Ajouter un analyseur de paramètres de méthode personnalisé à la classe de configuration
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(rsaVerifyArgumentResolver);
    }
}

Utiliser

La méthode d'utilisation est très simple,Il suffit d'introduire des annotations sur les paramètres

@RestController
@Slf4j
@RequestMapping("/xxx")
public class XxxCallbackController {
    /**
     * @param params
     * @return
     */
    @PostMapping("/callback")
    public String callback(@RsaVerify CallbackReq params) {
        log.info("receive callback req={}", params);
  //Traitement de la logique d'entreprise
  .....
  
        return "success";
    }
}

Questions

Question 1

Regarde ça.,Un ami prudent devrait avoir des questions:Maintenant que des annotations personnalisées sont utilisées ici,Pourquoi pas?TangentePour réaliser,Au lieu de cela, utilisez un analyseur de paramètres personnalisé?Very Good!C'est pareil.QQuestions soulevées,Les collègues disent que c'est parce que jackson L'action de désrialisation deSupérieur àPriorité de la section,Donc vous avez signalé une erreur de désrialisation qui a échoué avant d'entrer dans la section.

Deuxième question

Pourquoi? controller Note moyenne @RequestBody Il a disparu?

Pour répondre à cette question,Il faut qu'on comprenne.HandlerMethodArgumentResolverCompositeC'est la classe.,Ci - après dénomméeComposite.SpringMVC Au démarrage, tous les Analyseurs de paramètres sont placés dans Composite Moyenne,Composite Est une collection de tous les paramètres.Lorsqu'un paramètre est analysé, une paire de support est sélectionnée dans cette collection d'Analyseurs de paramètres parameter Analyseur de paramètres analysé,L'analyseur est ensuite utilisé pour l'analyse des paramètres.

Encore parce que@RequestBodyDonc l'analyseur de paramètres utiliséRequestResponseBodyMethodProcessorPriorité sur notre analyseur de paramètres personnalisé,Donc si le partage est intercepté par le premier,Donc pour une utilisation normale,Nous devons@RequestBody Note enlevée.

/**
 * Find a registered {@link HandlerMethodArgumentResolver} that supports
 * the given method parameter.
 */
@Nullable
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
    HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
    if (result == null) {
        for (HandlerMethodArgumentResolver resolver : this.argumentResolvers) {
            if (resolver.supportsParameter(parameter)) {
                result = resolver;
                this.argumentResolverCache.put(parameter, result);
                break;
            }
        }
    }
    return result;
}

CLa solution du collègue

En haut Z Le plan du collègue peut déjà résoudre le problème,Mais le programme présente encore deux lacunes:

  • Chaque rappel est nécessaire pour créer son propre controller Couche,Il n'y a pas d'entrée unifiée vers l'extérieur;

  • Une annotation personnalisée doit être ajoutée à la méthode,Très intrusif;

C'est pourquoi nous avons discuté,Décision d'abandonner le programme,Mais l'idée du programme mérite d'être étudiée.Ensuite, analysons la nouvelle solution:

Définir les classes d'interface d'affaires

La classe d'interface d'affaires contient deux méthodes:Types de processus opérationnels spécifiques;Traitement spécifique des affaires.

public interface INotifyService {
 /**
  * Type de traitement
  */
 public String handleType();
 /**
  * Traiter des affaires spécifiques
  */
 Integer handle(String notifyBody);
}

Notification asynchrone entrée unifiée

@AllArgsConstructor
@RestController
@RequestMapping(value = "/notify")
public class NotifyController {
 private IService service;
    @PostMapping(value = "/receive")
    public String receive(@RequestBody String body) {
        //Traitement des notifications
        Integer status = service.handle(body);
        return "success";
    }
}

In Iservice En deux étapes:

  • In spring Après le démarrage,Collecter tous les types comme INotifyServiceEt mettremapMoyenne;

  • Transformation des paramètres de traitement,Traitement de l'inspection et de la signature;

private ApplicationContext applicationContext;
private Map<String,INotifyService> notifyServiceMap;
/**
 * Charge de démarrage
 */
@PostConstruct
public void init(){
 Map<String,INotifyService> map = applicationContext.getBeansOfType(INotifyService.class);
 Collection<INotifyService> services = map.values();
 if(CollectionUtils.isEmpty(services)){
  return;
 }
 notifyServiceMap = services.stream().collect(Collectors.toMap(INotifyService::handleType, x -> x));
}
@Override
public Map<String, INotifyService> getNotifyServiceMap() {
 return notifyServiceMap;
}
@Override
public Integer handle(String body) {
 //Traitement des paramètres+Logique de vérification des signatures
    ......
        
 //Obtenir des classes de mise en œuvre d'entreprise spécifiques
 INotifyService notifyService=notifyServiceMap.get(notifyType);
 Integer status=null;
 if(Objects.nonNull(notifyService)) {
  //Exécution des activités spécifiques
  try {
   status=notifyService.handle(JSON.toJSONString(requestParameter));
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 //Traitement logique ultérieur
    ......
        
 return status;
}

Réalisation concrète de l'entreprise

@Service
public class NotifySignServiceImpl implements INotifyService {
    @Override
    public String handleType() {
        return "type_sign";
    }
    @Override
    @Transactional
    public Integer handle(String notifyBody) {
        //Traitement spécifique des affaires
        ......
    }
}

Résumé

  • Ce système fournit une entrée de notification asynchrone unifiée,Séparer la logique commune de traitement des paramètres et de vérification des signatures de la logique opérationnelle.

  • Utilisation java Propriétés de la classe de chargement dynamique,Collecte des classes d'implémentation par type.

  • Utilisation java Propriétés polymorphes,Gérer différentes logiques d'affaires par différentes classes d'implémentation.

Regarde ça.,Je crois que vous avez une certaine compréhension de ces deux options de mise en oeuvre,Vous pouvez essayer de l'appliquer à un projet ultérieur,Une expérience!

版权声明
本文为[Tangcheng]所创,转载请带上原文链接,感谢
https://javamana.com/2021/11/20211125171258787Q.html

  1. 应急响应入门之Linux分析排查
  2. Twitter如何升级Hadoop+Kafka架构实现实时处理数十亿个事件?
  3. 引人入胜,实战讲解“Java性能调优六大工具”之linux命令行工具
  4. docker 查看实时日志
  5. JFrog Artifactory 7.27 上传应用到私服和从maven私服下载制品
  6. Ces protocoles http simples
  7. [including thesis + source code] JavaWeb hospital triage registration management system SSH [package running successfully]
  8. Java初学者,想知道如何用if语法当条件成立后什么都不执行,否则执行动作
  9. 体验.NET Core使用IKVM对接Java
  10. 深入JavaScript高级语法-coderwhy
  11. 排序算法--Java实例/原理
  12. 停止docker时报错:Warning: Stopping docker.service, but it can still be activated by: docker.socket
  13. 【完整示例】采用jenkins pipeline实现自动构建并部署至k8s
  14. 【Linux】腾讯云服务器,使用FRP内网穿透,端口映射,远程访问内网ubuntu机器
  15. 关于#java#的问题:resultMap type映射不到我想要的类 只能映射java的内部类 加了全路径也映射不了 怎么解决
  16. 排序算法--Java實例/原理
  17. 就这一次,阿里最新出品源码阅读指南,一套搞定JDK+vm源码
  18. 两个小时手写了个Zookeeper分布式服务注册中心
  19. Algorithme de tri - - instance / principe Java
  20. Plongez dans la syntaxe avancée javascript - coderwhy
  21. JavaScript高级程序设计读后感(一)之零碎知识点查漏补缺
  22. 先到先学!Alibaba甩出第四次更新的JDK源码高级笔记(终极版)
  23. Java File类
  24. How To Install MariaDB on linux
  25. #yyds干货盘点# Mybatis 的 XML 配置
  26. Spring认证中国教育管理中心-Spring Data MongoDB教程七
  27. Linux进程和任务管理
  28. Linux文件系统日志分析
  29. Redis-客户端-重点知识
  30. Redis-事件-重点知识
  31. Redis-AOF持久化-重点知识
  32. Redis-RDB持久化-重点知识
  33. http://lx.gongxuanwang.com/sszt/32.htm
  34. 回顾我两个月面试阿里,携程,小红书,美团,网易等等(Java岗)
  35. JavaScript高级程序设计读后感(一)之零碎知识点查漏补缺
  36. Rocketmq source code analysis: message sending process
  37. Rocketmq source code analysis: how does rocketmq store messages?
  38. RocketMQ source analysis: how to debug the RocketMQ source in IDEA
  39. How To Install MariaDB on linux
  40. Comment installer mariadb sur Linux
  41. http://lx.gongxuanwang.com/sszt/7.htm
  42. Classe de fichiers Java
  43. Premier arrivé, premier servi! Alibaba lance la quatrième mise à jour de JDK source Advanced notes (Ultimate)
  44. #yyds干货盘点#设计模式之【工厂模式】
  45. Java * SpringBoot实现万能文件在线预览,已开源,真香
  46. Redis | 第4章 Redis中的数据库《Redis设计与实现》
  47. Liang Tingwei's first variety show of "director, please give advice" reshapes the classic work "spring of a new town"
  48. Redis | 第4章 Redis中的数据库《Redis设计与实现》
  49. 关于centos docker版本过低导致 is not a valid repository/tag: invalid reference format
  50. Redis 源码简洁剖析 02 - SDS 字符串
  51. 回顧我兩個月面試阿裏,攜程,小紅書,美團,網易等等(Java崗)
  52. Rétrospectivement, j'ai passé deux mois à interviewer Ali, ctrip, Little Red Book, meituan, NetEase, etc. (Java post)
  53. Docker + webhook Automation Deployment Front End Project
  54. Java技术之Spring、Hibernate框架整合方法
  55. http://lx.gongxuanwang.com/sszt/32.htm
  56. 亚马逊自己的 Linux 发行版现在完全基于 Fedora 了
  57. Redis 源码简洁剖析 02 - SDS 字符串
  58. Java技術之Spring、Hibernate框架整合方法
  59. Méthode d'intégration des cadres de printemps et d'hibernation de la technologie Java
  60. Redis source Concise Analysis 02 - SDS String