自定义一个maven插件,deploy(推送)依赖到私服的时候企业微信群里通知

news2024/11/25 6:52:14

很多时候,项目里面会引入各种同公司写的依赖,而这些依赖有时候更新到了nexus私服,其他人又不知道,导致本地的代码执行不符合预期。
我们这就有这种情况,因为依赖还处于开发阶段,并不是一个release版本,maven又是设置的不会每次都会去下载快照,就导致有人没有拉取最新的包写代码。为了避免这种情况,就考虑写一个maven插件,在deploy的时候,群里发一个通知。
大概的步骤就是下面5步,最后一步查看是否能正确发送消息。

  1. 创建一个maven插件项目
  2. 引入插件开发所需的依赖
  3. 编写发送通知的代码,然后install打包供其他项目当插件使用
  4. 项目pom文件build里面引入这个通知插件,创建一个企业微信机器人,拿到钩子地址,配置插件url属性
  5. 项目deploy,看企业微信是否收到消息

详细步骤:

创建maven项目

Idea新建一个普通的maven项目,名字的话,maven不要放在最前面,官方说,一般约定maven在最前面的是官方插件。
在这里插入图片描述
重要:packaging设置为maven-plugin,不然deploy的时候,会报错找不到plugin.xml
在这里插入图片描述

引入插件所需所需依赖

这个插件里面有后面要用到的注解和抽象类等等,设置为provided是因为到时候我们引入这个插件deploy的时候,他有这些依赖,打包的时候不用弄进去。

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven-plugin-tools.version>3.5.2</maven-plugin-tools.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>${maven-plugin-tools.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>${maven-plugin-tools.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

完整的pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.mvn</groupId>
    <artifactId>wechat-notify-deploy-maven</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>maven-plugin</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven-plugin-tools.version>3.5.2</maven-plugin-tools.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>${maven-plugin-tools.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>${maven-plugin-tools.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>
编写代码

首先编写一个http请求工具类,发送http请求我们用java原生的,还需要弄一个map转json的方法。之所以不用三方依赖比如hutool等是因为install这个插件项目的时候会报错。

package cn.mvn.notify.util;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * http请求工具,目前只用来发送post(主要是用gtp生成的,自己加了一个map里面value有map的类型处理)
 */
public final class HttpUtil {
    private HttpUtil() {
    }

    /**
     * 发送POST请求并接收响应
     *
     * @param url    请求URL
     * @param params 请求参数,Map形式
     * @return 响应结果字符串
     * @throws Exception 如果网络错误发生
     */
    public static String sendPostRequest(String url, Map<String, Object> params) throws Exception {
        HttpURLConnection connection = null;
        String result;
        String urlParameters = convertMapToJson(params); // 将Map转换为JSON字符串
        try {
            URL requestUrl = new URL(url);
            connection = (HttpURLConnection) requestUrl.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            connection.setRequestProperty("Accept", "application/json");
            connection.setDoOutput(true); // 发送POST请求必须设置允许输出
            connection.setDoInput(true); // 允许输入流读取服务器响应

            // 写入请求体
            try (OutputStream outputStream = connection.getOutputStream()) {
                byte[] input = urlParameters.getBytes(StandardCharsets.UTF_8);
                outputStream.write(input, 0, input.length);
            }

            // 读取响应
            StringBuilder builder = new StringBuilder();
            try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                String line;
                while ((line = in.readLine()) != null) {
                    builder.append(line);
                }
            }
            result = builder.toString();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
        return result;
    }

    /**
     * 将Map转换为JSON字符串
     *
     * @param map 要转换的Map
     * @return JSON字符串
     */
    private static String convertMapToJson(Map<String, Object> map) {
        // 这里简化处理,直接构造一个简单的JSON字符串。
        // 实际应用中可能需要使用如Jackson或Gson库来进行更复杂的对象转换。
        StringBuilder json = new StringBuilder();
        json.append("{");
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            Object value = entry.getValue();
            // 这里复杂类型只考虑map中含有Map类型的情况,不考虑含有list等其他类型的情况
            if (value instanceof Map) {
                json.append("\"").append(entry.getKey()).append("\":").append(convertMapToJson((Map<String, Object>) value))
                        .append(",");
            } else {
                json.append("\"").append(entry.getKey()).append("\":\"").append(value).append("\",");
            }
        }
        if (json.length() > 1) {
            json.setLength(json.length() - 1); // 移除最后一个逗号
        }
        json.append("}");
        return json.toString();
    }

}

接下来编写一个通知Mojo类,必须要实现AbstractMojo抽象类,然后重写execute方法,当我们使用这个插件的时候,会调用execute方法

package cn.mvn.notify.mojo;

import cn.mvn.notify.util.HttpUtil;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 通知mojo,定义Mojo(即插件中的goal)的注解,指定了这个Mojo(任务)的名称为wechat
 * 这个name在后面引入插件的时候会用到
 */
@Mojo(name = "wechat")
public class NotifyMojo extends AbstractMojo {
    /**
     * 企业微信机器人钩子地址,在plugin/configuration/url中可以配置,required = true意思是必须填,不然会报错(Idea里面会爆红提示)
     */
    @Parameter(required = true)
    private String url;
    /**
     * defaultValue里配置${}拿到引入了这个插件的项目pom文件里面的一些参数,readonly代表不允许用户修改这些参数
     */
    @Parameter(defaultValue = "${project.groupId}", readonly = true)
    private String groupId;
    @Parameter(defaultValue = "${project.artifactId}", readonly = true)
    private String artifactId;
    @Parameter(defaultValue = "${project.version}", readonly = true)
    private String version;
    /**
     * 用来输出日志
     */
    private final Log log = getLog();

    @Override
    public void execute() {
        // 判断一下钩子地址是否为空  还可以判断一下地址格式是否合法,这个可以自己加一个正则
        if (url.trim().isEmpty()) {
            if (log.isErrorEnabled()) {
                log.error("钩子地址为空");
            }
            return;
        }
        // 拼接要发送的消息
        final String message = groupId + ":" + artifactId + ":" + version + " deploy到nexus";
        final Map<String, Object> body = new HashMap<>(2);
        // text类型
        body.put("msgtype", "text");
        body.put("text", Collections.singletonMap("content", message));
        try {
            //todo 发送通知,响应可以自己处理一下,比如判断是否含有正确响应的字符来判断是否发送成功
            // {"errcode":0,"errmsg":"ok"} 这个是目前请求钩子地址正常的响应
            String response = HttpUtil.sendPostRequest(url, body);
        } catch (Exception e) {
            // 如果异常了,就提示
            if (log.isErrorEnabled()) {
                log.error("发送异常,异常信息:" + e.getMessage(), e);
            }
        }
    }
}

很简单,就这两个类,然后install安装到本地仓库,可以mvn clean install,或者直接在Idea中点install
在这里插入图片描述

项目里面引入通知插件,配置企业微信机器人钩子地址

configuration标签里面的url标签配置企业微信机器人钩子地址,其次就是配置一个execution让他在deploy的时候调用我们这个插件(其实@Mojo注解里面可以配置默认阶段defaultPhase = LifecyclePhase.DEPLOY,这样在depoly的时候就会自动执行,但是不知道为什么在我本地配置这个并没有用,所以用了这种execution的方式来配置)。
在这里插入图片描述
创建企业微信机器人的步骤,创建完把这个Webhook地址配置在url属性
在这里插入图片描述
引入完之后,在Idea里面,查看项目的Plugins,就可以看到我们的插件了,如果我们插件有问题(比如packaging没有配置成maven-plugin),他是会爆红色波浪线的
在这里插入图片描述

deploy测试插件是否可用

可以先双击Plugins里面的wechat-notify-deploy:wechat看一下,这样就会直接调用我们的插件,没有问题再deploy测试
双击之后,企业微信成功收到通知。除了用Idea直接点击调用,还可以通过mvn命令的方式调用和配置参数,有兴趣的可以问一下GPT
,
再测试deploy,同样正常收到通知。如果想给其他人使用这个插件,可以把插件deploy到私服。
注意: 插件deploy到私服之后,其他人要想拉取,项目里面需要在pluginRepositories标签配置仓库地址,和仓库地址标签repositories不是共用的。没有配置插件仓库地址的话,拉取的时候会报解析错误,在本地仓库查看是没有拉取下来的。
可以pom.xml里面配置,也可以settings.xml里面配置:

    <pluginRepositories>
        <pluginRepository>
            <id>c-nexus</id>
            <url>http://xxx.xxx.xxx.xxx:port/repository/maven-public/</url>
            <layout>default</layout>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
            <releases>
                <enabled>true</enabled>
            </releases>
        </pluginRepository>
    </pluginRepositories>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2118185.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于vue框架的车辆维修管理系统的设计与实现pvno9(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目管理&#xff1a;普管,驾驶员,维修员,维修出库,采购入库,配件信息,车辆信息,维修申请,维修费用 开题报告内容 基于Vue框架的车辆维修管理系统的设计与实现开题报告 一、项目背景与意义 随着汽车保有量的不断增加&#xff0c;车辆维修行业面临着前所未…

计算机毕业设计选题推荐-流浪动物领养管理系统-Java/Python项目实战(亮点:数据可视化分析、智能推荐)

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

Node.js构建千万级高可用企业级应用:‌深入六大核心业务场景

Node.js构建千万级高可用企业级应用&#xff1a;‌深入六大核心业务场景 Node.js&#xff0c;‌作为一种基于Chrome V8 JavaScript引擎构建的开源运行时环境&#xff0c;‌已经在企业级应用中展现出其独特的优势。‌特别是在处理高并发、‌实时性要求高的应用场景中&#xff0…

解码数字化转型顶层规划(附236页PPT:xx企业数字化转型项目顶层规划方案)

写在前面&#xff1a;PPT分享见后文~ 企业数字化转型顶层规划的制定是一个系统性的过程&#xff0c;需要综合考虑多个方面。以下是制定企业数字化转型顶层规划的一些关键步骤和要点&#xff0c;以供参考&#xff1a; 1、明确数字化转型战略定位&#xff1a; 将数字化转型作为…

分布式共识(一致性)算法(协议) Paxos 简介

分布式共识&#xff1a;Paxos算法简介 需求背景 在分布式系统中&#xff0c;确保各节点间的数据一致性是核心挑战之一。Paxos算法&#xff0c;作为解决此问题的经典方法&#xff0c;通过分布式共识机制允许网络中的多数节点就某值达成一致&#xff0c;即便面对消息延迟、节点…

京东图标点选验证码识别代码

如上图所示&#xff0c;京东会让你根据小图中的图案&#xff0c;在大图中点击对应的图标。 识别代码如下&#xff1a; 需要两张图片&#xff0c;可以是原图2张&#xff0c;或者是截图2张。运行下面代码可以看到点击的位置。 import base64 import requests import datetime …

python-新冠病毒

题目描述 假设我们掌握了特定时间段内特定城市的新冠病毒感染病例的信息。在排名 i 的当天有 i 个案例&#xff0c;即&#xff1a; 第一天有一例感染第二天有两例感染第三天有三例感染以此类推...... 请计算 n 天内的感染总数和每天平均感染数。 输入 整数 n 表示天数&…

【脊线图】:附Origin详细画图流程

目录 No.1 理解脊线图 No.2 画图流程 1 导入数据&#xff0c;绘制图形 2 设置绘图细节 3 设置颜色标尺并进行色阶控制 4 设置坐标轴 5 效果图 No.1 理解脊线图 脊线图&#xff0c;在统计学和数据分析领域&#xff0c;是一种高级且专业的可视化工具&#xff0c;用于展示…

如何摸透大模型?看完《实战AI大模型》你算是懂了!

今天&#xff0c;人工智能技术的快速发展和广泛应用已经引起了大众的关注和兴趣&#xff0c;它不仅成为技术发展的核心驱动力&#xff0c;更是推动着社会生活的全方位变革。特别是作为AI重要分支的深度学习&#xff0c;通过不断刷新的表现力已引领并定义了一场科技革命。大型深…

酸奶刺客打折,瑜伽裤冲锋衣熄火…中产消费正全线崩溃?

如果把消费市场这两个月的热搜放在一起看&#xff0c;你会发现中产好像越来越抠了&#xff0c;消费市场的天要变了……‍‍‍‍‍‍ 比如几十块钱一支的钟薛高降价降到几块钱也没多少人买了&#xff0c;创始人更是放下身段&#xff0c;直播卖起了红薯……‍ 还有前不久冲上热搜…

1比25万基础电子地图(辽宁版)

我们为你分享过四川、云南、江西、贵州、重庆、青海、西藏、新疆、甘肃、黑龙江、吉林、湖北、内蒙古、广东、广西、浙江、河南、湖南、宁夏、山西、陕西、天津、山东、河北、江苏和福建的1比25万基础电子地图&#xff0c;现在再为你分享辽宁版的电子地图。 如果你需要这些省份…

哈希表的底层实现(2)---C++版

目录 链地址法Separate Chaining——哈希桶的模拟实现 超大重点分析&#xff1a; 两种方法对比 由于在上次的哈希表的底层实现(1)---C版已经详细的阐述了相关的结构和原理&#xff0c;哈希表的实现方法主要分为链地址法和开放定址法。开放定址法上次已经实现过了&#xff0c…

MySQL record 04 part

高级查询&#xff1a; order by 对查询结果排序&#xff0c; 注意&#xff0c;使用order by的时候&#xff0c;如果某条记录的order by 指定的字段值是 null&#xff0c;那么包含 null 的这条记录会排在第一位&#xff0c;因为 null 被认为是最小值。 group by 对字段的值进行…

【系统分析师】-软件设计

目录 1、概要设计 1&#xff09;层次图&#xff08;H图&#xff09; 2&#xff09;HIPO图 2、详细设计 1&#xff09;流程图 2&#xff09;盒图&#xff08;N-S图&#xff09; 3&#xff09;PAD 问题分析图 4&#xff09;PDL伪代码图 3、软件设计过程 4、软件设计活动…

MQTT工业网关的工作原理及其在实际生产中的重要作用

在智能制造与工业4.0的浪潮中&#xff0c;MQTT工业网关作为连接传统工业设备与现代物联网技术的桥梁&#xff0c;正发挥着不可或缺的作用。MQTT协议以其轻量级、开放性和可靠性&#xff0c;在工业物联网领域得到了广泛应用。本文将通过一个实际应用案例&#xff0c;解析MQTT工业…

网络安全工程师填补人才缺口

近年来&#xff0c;新兴技术如人工智能、5G和量子信息技术等的迅猛发展&#xff0c;极大地推动了互联网技术的革新。 然而&#xff0c;随之而来的网络安全威胁也日益增多&#xff0c;对国家、企业及个人安全构成了严重挑战。 网络安全问题就在我们身边&#xff0c;因此&#…

关于电影票api接口你了解多少?

电影票API接口是连接第三方平台与电影院票务系统的一种技术手段&#xff0c;它允许第三方应用程序如网站、移动应用或小程序集成电影票购买服务。通过API&#xff0c;用户可以在第三方平台上查询电影信息、影院排期、选择座位并完成购票支付。 电影票API接口的主要功能通常包括…

智能头盔语音识别声控芯片,AI离线语音识别ic方案,NRK3301

头盔是交通事故中保护电动车车主安全的最后一道屏障。为了增加骑行用户的安全保护&#xff0c;改善骑行用户的出行体验&#xff0c;让用户从被动使用头盔到主动佩戴头盔&#xff0c;头盔厂家与九芯电子合作&#xff0c;推出了语音智能头盔&#xff0c;它具备首家骑行专用的智能…

关于SpringBoot项目yml配置数据库、redis、mq等中间件的用户密码敏感信息加密问题的解决方案

一、问题描述 一般情况下,yml里边的配置信息 都是在项目部署时动态管理的,一般不存在泄密或者不安全的情况,但是,不凡有一些脑袋有泡的客户,要对你项目源码进行安全性检测。故提供如下解决方案: 二、关于中间件Redis、MQ等对用户名或密码进行加密。 一般可在其对应的配…

【.NET 8 实战--孢子记账--从单体到微服务】--用户(登录/注册/Token)

从这篇文章开始&#xff0c;我们就进入到了项目开发阶段。我们的项目是面向用户的&#xff0c;因此我们首先要做的是和用户相关的逻辑代码。 一、需求 首先&#xff0c;我们来看一下服务端的需求&#xff1a; 编号需求标题需求内容1登录传入参数用户名、密码和验证码&#x…