准备一个可以接收的数据接口,用来实现对话。当然你有更好的欢迎下面留言~我用的是下面这个接口,附上传送门:

青云客智能聊天机器人

这个接口的调用url是:http://api.qingyunke.com/api.php?key=free&appid=0&msg=关键词

手写js了好多次ajax请求,皆因跨域失败告终。没办法,想到了springboot做一个中转请求处理吧,请求发送到私服上的springboot程序,springboot再请求这个接口,emmm虽然挺麻烦,但是这个思路可以实现,开始撸码!

不想手写前端,遂找了一些框架,最终选择framework7,一个和原生应用很像的HTML,js框架,里面有个massage的例子,刚好就是对话框的主题。看一下最终效果吧:

调用对话web接口并借助framework7和springboot做一个简单对话机器人

 先理解一下原理:前端发起ajax请求到springboot程序,springboot再请求接口实现消息返回,最后显示在页面上。具体代码如下:从页面开始:

<!DOCTYPE html>
<html>
<head>
  <!-- Required meta tags-->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <!-- Your app title -->
  <title>My App</title>
  <!-- 使用bootcdn进行在线加速 -->
  <link href="https://cdn.bootcss.com/framework7/4.2.2/css/framework7.min.css" rel="stylesheet">
  <link href="https://cdn.bootcss.com/framework7/4.2.2/css/framework7.bundle.min.css" rel="stylesheet">
  <!-- 本地示例运行请参考:https://blog.csdn.net/qq_38815953/article/details/81984863 -->
</head>
<body>
  <div class="page">
    <div class="navbar">
      <div class="navbar-inner">
        <div class="title">消息列表</div>
      </div>
    </div>
    <div class="toolbar messagebar">
      <div class="toolbar-inner">
        <div class="messagebar-area">
          <textarea class="resizable" placeholder="输入"></textarea>
        </div><a class="link send-link" href="#">发送</a>
      </div>
    </div>
    <div class="page-content messages-content">
      <div class="messages">
        <!-- 消息标题,初始化为时间 -->
        <div class="messages-title" id="messages-title_top"></div>
        <!-- 完整的发送消息布局 -->
        <!-- <div class="message message-sent">
          <div class="message-avatar" style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-7.jpg);"></div>
          <div class="message-content">
            <div class="message-name">约翰</div>
            <div class="message-header">消息头</div>
            <div class="message-bubble">
              <div class="message-text-header">消息描述</div>
              <div class="message-text">苍茫的天涯是我的爱.</div>
              <div class="message-text-footer">注脚</div>
            </div>
            <div class="message-footer">消息脚</div>
          </div>
        </div> -->
        <!-- 完整接收布局消息 -->
        <div class="message message-received">
          <div class="message-avatar" style="background-image:url(https://头像url.png);"></div>
          <div class="message-content">
            <div class="message-name">菲菲</div>
            <div class="message-bubble">
              <div class="message-text">Hello,我是潜伏在网页里的智能客服菲菲,今天咱们唠点啥尼?</div>
            </div>
            <div class="message-footer">自动回复</div>
          </div>
        </div>        
          


        </div>
      </div>
    </div>
    <!-- 主js文件和web支持 -->
    <script src="https://cdn.bootcss.com/framework7/4.2.2/js/framework7.min.js"></script>
    <script src="https://cdn.bootcss.com/framework7/4.2.2/js/framework7.bundle.min.js"></script>
    <!-- jq -->
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script>
    $(function(){
      var date = new Date();
      $('#messages-title_top').text(date.toLocaleString());
    });

    // app初始化
    var app = new Framework7();

    var $$ = Dom7;  //为了防止与jq冲突,实际上,借助framework7的dom操作与jq一样

    // 初始化消息对象
    var messages = app.messages.create({
      el: '.messages',

      // 第一条消息规则
      firstMessageRule: function(message, previousMessage, nextMessage) {
        // 跳过标题
        if (message.isTitle) return false;
        /* if:
          - 如果之前没有消息
          - 或以前的消息类型(发送/接收)不同
          - 或者以前的邮件发件人名称不同
        */
        if (!previousMessage || previousMessage.type !== message.type || previousMessage.name !== message.name) return true;
        return false;
      },
      // Last message rule
      lastMessageRule: function(message, previousMessage, nextMessage) {
        // Skip if title
        if (message.isTitle) return false;
        /* if:
          - there is no next message
          - or next message type (send/received) is different
          - or next message sender name is different
        */
        if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
        return false;
      },
      // Last message rule
      tailMessageRule: function(message, previousMessage, nextMessage) {
        // Skip if title
        if (message.isTitle) return false;
        /* if (bascially same as lastMessageRule):
      - there is no next message
      - or next message type (send/received) is different
      - or next message sender name is different
    */
        if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
        return false;
      }
    });

    // 初始化消息栏
    var messagebar = app.messagebar.create({
      el: '.messagebar'
    });

    // 响应
    var responseInProgress = false;
    var msg_info = "";    // 全局保存发送消息
    // 发送消息
    $$('.send-link').on('click', function() {
      var text = messagebar.getValue().replace(/\n/g, '<br>').trim();
      // 空消息返回不做处理
      if (!text.length) return;
      msg_info = text;
      // 发送成功则清除描述
      messagebar.clear();

      // 将焦点返回到区域
      messagebar.focus();

      // 向邮件添加邮件
      messages.addMessage({
        text: text,
      });

      if (responseInProgress) return;
      // 接收虚拟消息
      receiveMessage();
    });
// 随机生成虚拟消息
    function receiveMessage() {
      responseInProgress = true;
      setTimeout(function() {
        // 得到随机答案和随机人

        // 显示载入指示
        messages.showTyping({
          header: '菲菲 正在输入',
          avatar: 'https://这里是头像的路径.png'
        });
        // 向我的服务器发起ajax请求
        var url = "http://请求服务的路径/520" + "?msg=" + msg_info;
          $.ajax({
            type: 'get',
            url: url,
            success: function(data){
              console.log(data);
              messages.addMessage({
                text: data.content,
                type: 'received',
                name: '菲菲',
                avatar: 'https://这里是头像的url'
              });
              // 隐藏输入指示
              messages.hideTyping();
              responseInProgress = false;
            },
            error: function(data){
              // console.log(data);
            }
          });
        setTimeout(function() {
        }, 4000);
      }, 1000);
    }
    </script>
</body>

</html>

直接copy过来demo改的,js资源取自bootcdn的加速

然后是主角springboot了,使用的是在线初始化的一个boot程序,pom.xml如下

<?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.4.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.lvfeng</groupId>
	<artifactId>lvfeng</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>lvfeng</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-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!--<dependency>-->
			<!--<groupId>org.mybatis.spring.boot</groupId>-->
			<!--<artifactId>mybatis-spring-boot-starter</artifactId>-->
			<!--<version>2.0.0</version>-->
		<!--</dependency>-->

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<!--<scope>runtime</scope>-->
		</dependency>
		<!-- json处理 -->
<!-- 		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.7.4</version>
		</dependency> -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.47</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<!--maven打包时跳过单元测试 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.22.1</version>
				<configuration>
					<skip>true</skip>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

接下来是控制器

/**
     * 跨域对话机器人请求
     * 青云客:http://api.qingyunke.com/
     * 接口:http://api.qingyunke.com/api.php?key=free&appid=0&msg=关键词
     */
    @ResponseBody
    @CrossOrigin
    @GetMapping("/talk/{id}")
    public Map getTalk(@PathVariable(name = "id") Long id, @RequestParam(name = "msg") String msg) throws Exception{
        System.out.println("请求内容:" + msg);
        String url = "http://api.qingyunke.com/api.php";
        Map param = new HashMap();  // 配置
        param.put("key","free");
        param.put("appid","0");
        param.put("msg",msg);
        String res = NetTool.getNetData(url, param, "GET");     // 执行请求
        JSONObject object = JSONObject.parseObject(res);
        Map map = object.getInnerMap();    // 结果集转map
        return map;
    }

为了用着方便,参考了nowAPI的一些写法,封装了一下静态方法,以便之后更多接口的方便使用:

    public static final String userAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36";
    public static final int DEF_CONN_TIMEOUT = 30000;
    public static final int DEF_READ_TIMEOUT = 30000;
    public static final String DEF_CHATSET = "UTF-8";

    /**
     * 创建Http连接并调用接口数据
     */
    public static String getNetData(String strUrl, Map param, String method) throws Exception{
        HttpURLConnection conn = null;
        BufferedReader reader = null;
        String res = null;
        try {
            StringBuffer sb = new StringBuffer();
            if(null == method || "GET".equals(method)){
                strUrl = strUrl + "?" + urlEncode(param);
            }
            URL url = new URL(strUrl);
            conn = (HttpURLConnection) url.openConnection();
            if(null == method || "GET".equals(method)){
                conn.setRequestMethod("GET");
            }else{
                conn.setRequestMethod("POST");
                conn.setDoOutput(true);
            }
            conn.setRequestProperty("User-agent",userAgent);
            conn.setUseCaches(false);
            conn.setConnectTimeout(DEF_CONN_TIMEOUT);
            conn.setReadTimeout(DEF_READ_TIMEOUT);
            conn.setInstanceFollowRedirects(false);
            conn.connect();
            if (null != param && "POST".equals(method)){
                try {
                    DataOutputStream dos =new DataOutputStream(conn.getOutputStream());
                    dos.writeBytes(urlEncode(param));
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
            InputStream is = conn.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, DEF_CHATSET));
            String strRead = null;
            while (null != (strRead = reader.readLine())){
                sb.append(strRead);
            }
            res = sb.toString();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if (null != reader){
                reader.close();
            }
            if (null != conn){
                conn.disconnect();
            }
        }
        return res;
    }

    /**
     * 转码
     */
    public static String urlEncode(Map<String,Object>data){
        StringBuilder sb = new StringBuilder();
        for (Map.Entry i : data.entrySet()) {
            try {
                sb.append(i.getKey()).append("=").append(URLEncoder.encode(i.getValue()+"","UTF-8")).append("&");
            } catch (UnsupportedEncodingException e){
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

然后springboot打个jar包并上传在Linux上运行起来就欧克啦!

当然其中会遇到打包不顺利的情况,可以参考咱之前文章或者百度一下。

相关文章:

  • 2021-10-26
  • 2021-04-07
  • 2021-12-08
  • 2021-07-21
  • 2022-12-23
  • 2021-06-22
  • 2021-09-12
  • 2022-12-23
猜你喜欢
  • 2022-01-21
  • 2021-09-19
  • 2021-10-03
  • 2021-07-16
  • 2021-10-18
  • 2021-12-08
  • 2022-12-23
相关资源
相似解决方案