【SpringBoot】教你写个QQ机器人(2)搭建项目框架

news/2024/7/3 14:33:57 标签: 酷Q, qq机器人, 垃圾分类, 群关键词监控, CQHTTP

                             教你写个QQ机器人(2)搭建项目框架


开始SpringBoot之旅

2019/7/5 18:05 未完待续.....(其实是下班了,回去再写)

目前项目的目录(可能会有所改动),详细代码见我的GithubSunAlwaysOnline/kq


以下是我用到的依赖

MyBatis-plus:是MyBatis的增强版,封装了一些常用的sql方法,我们设置可以不用在dao、service与mapper文件编写方法。

Redis:内存型数据库,我把查询出来的垃圾分类存储在Redis中,提高查询效率。

Jsoup:请求外部的垃圾分类接口时,返回的是Html页面,因此需要对页面进行抓取数据。

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.sun</groupId>
    <artifactId>kq</artifactId>
    <version>1.0</version>
    <name>kq</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>

        <!--Redis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.11.3</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

配置MyBatis-plus与RestTemplate(SpringBoot中用来发送HTTP请求)

MybatisPlusConfig.java(分页暂时没用到,但在数据量过多时会用到,先给配置上)

package com.sun.kq.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("com.sun.kq.dao")
public class MybatisPlusConfig {

	/**
	 * 分页插件
	 *
	 * @return PaginationInterceptor
	 */
	@Bean
	public PaginationInterceptor paginationInterceptor() {
		PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
		paginationInterceptor.setDialectType(DbType.MYSQL.getDb());
		return paginationInterceptor;
	}

	/**
	 * 逻辑删除插件
	 *
	 * @return LogicSqlInjector
	 */
	@Bean
	public ISqlInjector sqlInjector() {
		return new LogicSqlInjector();
	}

}
RestTemplateConfig.java
package com.sun.kq.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/**
 * RestTemplate配置类
 */
@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        return new RestTemplate(factory);
    }

    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(5000);//ms
        factory.setConnectTimeout(15000);//ms
        return factory;
    }
}

常量类(主要保存请求地址)

URLConst.java

package com.sun.kq.constant;

public class URLConst {

    /**
     * HTTP服务器地址
     */
    public static final String URL = "http://127.0.0.1:5700";

    /**
     * 发送私聊消息
     */
    public static final String SEND_PRIVATE_MSG = "/send_private_msg";

    /**
     * 获取群列表
     */
    public static final String GET_GROUP_LIST = "/get_group_list";


    /**
     * 获取该垃圾的分类,后面加垃圾名称的URL编码
     */
    public static final String GET_RUBBISH_TYPE = "https://lajifenleiapp.com/sk/";
}

编写消息上报的接口,用来接收QQ里收到的消息

MsgController.java(主要是看/receive接口)

/msg/receive接口我们在插件中已经配置过,酷Q收到消息后,cqhhtp插件调用其sdk获取消息,然后像本机的8080/msg/receive接口上报酷Q收到的消息,这种方式实现了跨语言使用酷Q的方式。

package com.sun.kq.controller;

import com.sun.kq.model.PrivateMsg;
import com.sun.kq.model.ReplyMsg;
import com.sun.kq.model.Result;
import com.sun.kq.service.MsgService;
import com.sun.kq.service.PrivateMsgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/msg")
public class MsgController {

    @Autowired
    MsgService msgService;


    /**
     * 消息上报接口
     *
     * @param request
     */
    @RequestMapping("/receive")
    public ReplyMsg receive(HttpServletRequest request) {
        return msgService.receive(request);
    }

}

MsgService.java

package com.sun.kq.service;

import com.sun.kq.model.PrivateMsg;
import com.sun.kq.model.ReplyMsg;
import com.sun.kq.model.Result;

import javax.servlet.http.HttpServletRequest;

public interface MsgService {


    /**
     * 接收消息(私聊、群、讨论组、其他)并响应
     *
     * @param request
     * @return
     */
    ReplyMsg receive(HttpServletRequest request);
}

他的实现类MsgServiceImpl.java(主要看recevie方法)

package com.sun.kq.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.kq.entity.Keyword;
import com.sun.kq.entity.Rubbish;
import com.sun.kq.model.PrivateMsg;
import com.sun.kq.model.ReceiveMsg;
import com.sun.kq.model.ReplyMsg;
import com.sun.kq.model.Result;
import com.sun.kq.service.*;
import com.sun.kq.util.KeywordsUtil;
import com.sun.kq.util.MsgUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.stream.Collectors;

import static com.sun.kq.constant.URLConst.*;

@Service
public class MsgServiceImpl implements MsgService {

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    RubbishService rubbishService;

    @Autowired
    KeywordService keywordService;

    @Autowired
    PrivateMsgService privateMsgService;

    @Autowired
    GroupMsgService groupMsgService;


    @Override
    public ReplyMsg receive(HttpServletRequest request) {
        String msg = null;
        try {
            msg = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
            System.out.println(msg);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (msg == null) {
            return null;
        }

        //解析收到的消息
        ReceiveMsg receiveMsg = null;
        try {
            receiveMsg = new ObjectMapper().readValue(msg, ReceiveMsg.class);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return handleReceiveMsg(receiveMsg);


    }


    /**
     * 由收到的讨论组消息的内容转发给特定的方法(暂时用不到,先留着)
     *
     * @param receiveMsg
     */
    private ReplyMsg handleDiscussMsg(ReceiveMsg receiveMsg) {
        return null;
    }


    /**
     * 由收到的消息类型转发给特定的方法
     *
     * @param receiveMsg
     */
    private ReplyMsg handleReceiveMsg(ReceiveMsg receiveMsg) {
        String post_type = receiveMsg.getPost_type();
        switch (post_type) {

            case "message":
                //收到消息
                String message_type = receiveMsg.getMessage_type();
                switch (message_type) {
                    case "private":
                        //私聊消息
                        return privateMsgService.handlePrivateMsg(receiveMsg);
                    case "group":
                        //群消息
                        return groupMsgService.handleGroupMsg(receiveMsg);
                    case "discuss":
                        return handleDiscussMsg(receiveMsg);
                }
                break;

            case "notice":
                //群、讨论组变动等通知类事件
                break;

            case "request":
                //加好友请求、加群请求/邀请
                break;
            case "meta_event":
                //生命周期元事件
                //可以初始化缓存
                //keywordService.getAllDataIntoCache();
                break;
        }

        return null;
    }

}

上方代码中,直接用一行代码获取请求中的数据,接着用jackson中ObjectMapper类来解析生成ReceiveMsg对象,然后转交给handleReceiveMsg方法,handleReceiveMsg方法依据消息类型(私聊、群聊等)转交给不同的方法进行处理。


privateMsgService.handlePrivateMsg方法的内容见下一节教你写个QQ机器人(3)


http://www.niftyadmin.cn/n/1705537.html

相关文章

电子杂志(商刊)迎来在线阅读新时代(无须任何插件或客户端)

<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />在过去的一年里&#xff0c;以多媒体、互动性、阅读器为三大特点的第三代电子杂志&#xff08;商刊、画册、目录&#xff09;让中国的网民了解了电子杂志&#xff08;商刊&#x…

评教系统之我所见

前几天我们对我们的任课教师进行了这个学期的教学评价&#xff0c;帮我们班德几个同学顺便评了几个&#xff0c;顺便学习了一下这个系统的相关功能及了解了一下系统的相关知识。稍后几天对后台看了看&#xff0c;发现这个系统真的不简单。 这个系统主要面向五大群体使用&#x…

【SpringBoot】教你写个QQ机器人(3)让你的机器人学会垃圾分类

教你写个QQ机器人&#xff08;3&#xff09;让你的机器人学会垃圾分类 事前废话 自从上海实行垃圾分类后&#xff0c;上海老百姓生活于水生火热之中&#xff0c;如今战火蔓延到了苏州&#xff0c;身为正义化身的我&#xff0c;决定让我的机器人学会垃圾分类。 我们的需求&…

windows的预加载任务机制及其联想

windows的预加载任务机制及其联想现在的病毒越来越顽固&#xff0c;动不动就是搞个驱动来HOOK一些内核来保护自己&#xff0c;导致一般的用户很难清理这些病源&#xff0c;所以现在的产生了许多删除顽固文件的工具。其实对于电脑熟悉的人来说&#xff0c;删除这些不是很难的一件…

使用ADO.NET 建立适应多种数据库的数据访问层接口

抽象的.NET Framework数据提供最终规则规定的原因&#xff0c;以及如何你应该抽象的。NET Framework数据提供者使用在你的DAL内部。正如我所提到的的&#xff0c;ADO.NET编程模型公开截然不同。NET Framework数据提供包括使用SqlClient&#xff0c;OLEDB和其他MSDN Online网站上…

win 2003 的一些优化、加速整理

前言&#xff1a;Windows 2003 企业推荐号码:JCGMJ-TC669-KCBG7-HB8X2-FXG7M 一、关闭WIN2003关机事件跟踪程序和CTRLALTDEL 1) 关闭WIN2003关机事件跟踪程序 Windows Server 2003 的推出真给我们带来了全新的感受&#xff0c;在设计上更人性化&#xff0c;更体贴。但也给我…

我们是一群和平年代充满浮躁与抱怨的程序员

和很多IT人沟通&#xff0c;发现表现出来更多的是浮躁与抱怨&#xff0c;所以有了本文&#xff0c;其实我们不论是coder&#xff0c;还是架构师或项目经理&#xff0c;都存在同样的心理&#xff0c;只是比较的对像及发展的路线不一样罢了。 现在是一个和平与发展的社会&#xf…

ASP.NET中的那些控件

这十几天来一直再看天轰穿的关于ASP.NET的视频&#xff0c;一个初中毕业的学生&#xff0c;自学成才&#xff0c;对.NET掌握的竟然比我们任何一个人都强很多&#xff0c;还可以作为我们的老师&#xff0c;在网上查了查他得相关资料&#xff0c;田洪川却自信地说&#xff1a;“在…