# 自定义额外监听 > 自版本 `0.9-BETA-1.9`后,存在了类`MsgOnManager`后开始支持 ## **简介** CQ HTTP API组件支持你以`CQ HTTP API`插件的上报信息格式为标准,来新建一套自定义的监听类型。 什么意思呢,举个例子。 **假如**:你想要通过http上报一个叫做`"新用户"`的事件,然后在你自己的一个web应用中,一个用户在你的网站中注册了,并点击了你网站的`"注册"`按钮,你想要将这个按钮的表单提交的数据上报给你的机器人,并作为一个监听消息来处理; 这时候,你就需要用到自定义的额外监听了。 ## **准备** 在使用自定义额外监听的时候,首先你要明白: * 尽可能保证JDK为JDK8版本。过高的版本也可能会出现异常。(曾出现过JDK11无法使用此类功能的事件) * 如果JDK8也出现无法创建新的枚举实例的情况,则试着换成JDK8中的稳定版本。 * 下文中,CQ HTTP API组件的`BaseMsg`类型与`@MsgOn`注解仅允许在`CQ HTTP API组件`内使用,无法在其他组件内使用。 ## **开始** ### **1. 提出假设** 首先,以下示例中,我将假设你想要的新的监听类型为`"新用户"`,想要的消息字段为: | 字段名称 | 字段含义 | | --- | --- | | name | 昵称 | | age | 年龄 | ### **2. 写封装类** 写个监听消息用的封装类,并继承`com.forte.component.forcoolqhttpapi.beans.msg.BaseMsg`抽象类,并标注`@MsgOn`注解: ```java /** * 新用户监听消息 */ @MsgOn(type = PostType.meta_event, messageType = NewUserMsg.NEW_USER_MESSAGE_TYPE) public class NewUserMsg extends BaseMsg { /** 监听的事件的子分类 */ public static final String NEW_USER_MESSAGE_TYPE = "new_user"; // 姓名 private String name; // 年龄 private Integer age; //**************** getter & setter & toString ****************// // 示例中省略 //**************** 抽象方法的实现 ****************// // 示例中省略 } ``` 其中,注解`@MsgOn`的两个参数分别是: | 参数名称 | 类型 | 含义 | | --- | --- | --- | | type | PostType | PostType枚举类型,指定此监听消息对应的事件大分类的分类字段 | | messageType | String | 指定此监听消息对应的事件子分类 | 至于大分类的分类字段和子分类是什么意思,首先你需要去参考一下CQ HTTP的官方文档:[https://cqhttp.cc/docs/4.14/#/Post](https://cqhttp.cc/docs/4.14/#/Post),以其中的 **`"私聊消息"`** 为例,`post_type`就是大分类的分类字段,`message_type`中的值`private`就是子分类。 ### **3. 注册** 你有两个需要注册的东西: * 监听类型注册 >[success] `MsgGetTypeFactory`是数属于核心的类,它的使用可以不仅限于CQ HTTP API组件 ```java // 注册一个叫做“NEW_USER_MSG”的监听类型,类型为NewUserMsg MsgGetTypeFactory.registerType("NEW_USER_MSG", NewUserMsg.class); ``` * 封装类型注册 ```java // 注册一个CQ HTTP API的监听消息封装类类型,需要标注@MsgOn注解并继承BaseMsg类 MsgOnManager.register(NewUserMsg.class); ``` >[warning] 以上注册过程需要在框架启动 **之前** 执行。 根据上述`NewUserMsg`的注解参数与字段,以下给出一个对应这个监听消息的上报的json数据示例: ```json { "post_type": "meta_event", "meta_event_type": "new_user", "name": "姓名", "age": 20 } ``` ### **4. 使用** 写一个监听器来使用这个新的监听类型。 >[success] 使用`@Listen.byName`来指定监听类型, 参数为你注册的枚举类型的名称。 ```java @Listen.ByName("NEW_USER_MSG") public void listenTest(NewUserMsg newUserMsg){ System.out.println(newUserMsg); } ```