当前位置:首页 » 《资源分享》 » 正文

智能家居项目总结_EVANY1234的博客

0 人参与  2021年10月15日 11:43  分类 : 《资源分享》  评论

点击全文阅读


目录

(一)项目概述​

(二)开始阶段

        问题1:如何创建一个可以连接数据库的JavaWeb项目?

        问题2:如何向前端传输想要的信息?

        问题3:如何读取数据库中想要得到的数据?

        问题4:如何将后端的信息发送给前端页面?

        问题5:前端如何向服务端发送带有行为特征的信息?

(三)整合阶段

        问题1:如何在不同的IP地址共用同一个数据库?

        问题2:如何实现MQTT云端与管理员和硬件功能块之间的互通?

        预备方案:

(四)完善阶段

        问题1:如何实现jsp页面局部的实时刷新?

(五)结语


(一)项目概述

        该项目以三个功能块(Javaweb(智能家居数据显示)、管理员UI(家居设备管理)、Ardurino(家居本居))和两个传输块(Mysql、Mqtt)实现。 笔者在此项目中主要负责编辑JavaWeb前后端语句以及实现JavaWeb功能块与Mysql的数据传输接收。笔者在下文将以整个项目分为三个阶段展开,主要谈谈在各个阶段中遇到的问题和解决的方案。

        发开工具:IDEA

(二)开始阶段

        笔者所在团队分为三个小组,分别对应实现三个功能块的内容,以下针对JavaWeb功能块提出一些问题。

        问题1:如何创建一个可以连接数据库的JavaWeb项目?

        在安装完IDEA后,我们新建一个Web模块项目。之后,我们需要添加mysql-connector-java-8.0.25.jar在项目lib中,再编辑Tomcat本地服务器(笔者使用的是8.0.70版本,如果版本过低好像会对项目产生影响)以方便测试项目。

        问题2:如何向前端传输想要的信息?

        搭建Servlet服务端,在web.xml文件中进行映射匹配。

<servlet>
    <servlet-name>loginServlet</servlet-name>
    <servlet-class>jspservlet.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>loginServlet</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>

        问题3:如何读取数据库中想要得到的数据?

        必须先建立类与其产生连接,之后在服务端后台利用sql语句对数据库进行查询。

package jspservlet.db;

import java.sql.Connection;
import java.sql.DriverManager;

public class DBConnect {  
	    private final String DBDRIVER = "com.mysql.cj.jdbc.Driver" ;   
	    private final String DBURL =  "jdbc:mysql://localhost:3306/smarthome2?useSSL=false&serverTimezone=UTC" ;
	    private final String DBUSER = "本地账号" ;
	    private final String DBPASSWORD = "密码" ;

	    private Connection conn = null ;   
	  
	    public DBConnect()   {
	        try{   
	            Class.forName(DBDRIVER) ;   
	            this.conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD) ;  
	        }catch (Exception e){ 
	        	System.out.println(e.getMessage());  
	        	}   
	    }   
	  
	      
	    public Connection getConnection(){   
	        return this.conn ;   
	    }   
	  
	 
	    public void close(){   
	        try{   
	            this.conn.close() ;   
	        }catch (Exception e){ }          
	    }   
}  
String sql = "需要的sql语句";
PreparedStatement pstmt = null ;
DBConnect dbc = null;
try{    
    dbc = new DBConnect() ;   
    pstmt = dbc.getConnection().prepareStatement(sql) ;//运行sql语句
    ResultSet rs = pstmt.executeQuery();
    while(rs.next()){
            	
         rs.getString("根据自己的填写"));//得到select语句对应的内容
    }   
    rs.close() ; 
    pstmt.close() ;   
    }
catch (SQLException e){   
        System.out.println(e.getMessage());   
    }
finally{ 
        dbc.close() ;   
    }   

        问题4:如何将后端的信息发送给前端页面?

        在服务端读取到数据库的信息后,完善服务器的doGet方法(页面打开时会自动执行)——利用session.setAttribute或request.setAttribute的方法提供一个类似键值对的信息,之后再重定向以显示指定的某个jsp页面。在该jsp中,可以使用<% %>隐藏域去接收服务器的响应,再以<%= %>的形式打印在jsp的任何位置(可以实现在循环中呈现多个设备,即html语句嵌套在域中)。

后端语句----------------------------------------------------------------------------
public void doGet(HttpServletRequest req,HttpServletResponse res) {

		LightDAO dao=new LightDAOImpl();//创建后台实现类,为实现数据查询功能
		HttpSession session=req.getSession();
		ArrayList<Light> linfo=new ArrayList<Light>();
		ArrayList<String> ltype=new ArrayList<>();
		try {
			session.setAttribute("随便取个名字", 想传的内容);
            linfo=dao.allLightid();//后端实现的方法(自己写去)
			ltype=dao.allLightType();
			session.setAttribute("linfo", linfo);
			session.setAttribute("ltype",ltype);
			res.sendRedirect("./light.jsp");//将响应交给前端页面

		}
		catch(Exception e){
			e.printStackTrace();
		}
	}

前端语句----------------------------------------------------------------------------
    <% ArrayList<Light> l = (ArrayList<Light>)session.getAttribute("linfo"); %>
	<% int i=0;%>
	<% while (i<l.size()){ %>
	<% Light k=l.get(i); %>
	<% String cl=k.getType(); %>
	<% for (j=0;j<type.size();j++){ %>
	<% String t=type.get(j); %>
	<% if (cl.equals(t)){ %>
		<div class= "col-lg-4 col-md-6 col-sm-12 single_project cat<%=j+1%>">
			<div class="grid_item">
				<div class="deneb_img">
					<img src=<%= l.get(i).getImg() %> class="img-fluid" alt="">
				</div>
				<div class="deneb_info">
					<h4><a href="./inf?action=light&id=<%=k.getId() %>"><%= l.get(i).getType() %></a></h4>
					<p id="zz">brightness:<%= l.get(i).getState() %></p>
				</div>
			</div>
		</div>
   <% }}i++;} %>

        问题5:前端如何向服务端发送带有行为特征的信息?

        这个问题主要是因为想要查询某个具体设备(在Mysql中的id唯一)的响应信息,所以该请求必须携带带有特征的信息,让服务器进行响应。实现方法是使用<a href=""?id=xxx&...>这种形式的超链接请求语句,然后再服务端利用req.getParameter("id")的形式获取id(当然可以取别的名字)后的内容。

<a href="./inf?action=light&id=<%=k.getId() %>"><%= l.get(i).getType() %></a>
String judge=req.getParameter("action");
			
	if (judge!=null) {
			if (judge.equals("changeon")) {
					
			}
			if (judge.equals("changeoff")) {
					
			}
			if (judge.equals("delete")) {
					
			}
	}

(三)整合阶段

        在笔者JavaWeb功能块与本地Mysql连接可以单独实现之后,笔者开始与另外两个功能块的内容进行对接:首先就是与管理员功能块统一数据库的内容形式(如何利用ip共用同一数据库在后面会讲到),然后就是了解了硬件功能块的运作形式(Arduino单开线程发送和接收信息),最后组员提供了利用WIFI模块实现云端服务器通讯(MQTT传输块)的方法。以下是在讨论时提出的几个问题和相应的解决方式。

        问题1:如何在不同的IP地址共用同一个数据库?

        在提供数据库的设备上以管理员身份打开Mysql控制台,输入use mysql连接用户表,利用create函数创建一个新的用于连接的用户(记得用flush privileges是操作有效),最后利用grant函数给用户授权,@后的内容可以用‘%’,即任何IP都可以连接。

        之后将运行JavaWeb的设备中connect的语句中的localhost替换为提供数据库设备的无线互联网v4IP地址并更改下方用户名和密码的字符串。(运行项目可能会有一个数据库无法连接的报错,在IP地址后加上&allowPublicKeyRetrieval=true可以实现联通。)

        注意:在测试之前先用cmd ping下对应的IP,如果ping不进可能要关掉防火墙!!

        问题2:如何实现MQTT云端与管理员和硬件功能块之间的互通?

        在讨论这个问题之前需要先弄清楚各个功能块之间的逻辑关系,JavaWeb只需要读取Mysql中的内容,管理员需要不断接收云端上发布的内容并将内容写进共用的Mysql中,硬件需要不断向云端发送各个智能家居的传感器当前的数据,可见管理员后台和硬件方面是两条不同的线程,以云端为连接的桥梁。

        所以只需要解决桥梁的搭建问题就能实现互通——

        在硬件方面,利用WIFI模块和Arduino的语句可以开辟一条线程向MQTT服务器发送带有topic标签的内容(订阅MQTT后可以在网页上实时看到发送过来的数据噢^^),发送的消息会被存在一个broker(类似地址的感觉,互联网这块知识不怎么了解)里。管理员通过MQTT官网提供的资源包在新建Maven架构项目里添加依赖项,然后官方提供的java连接的API,再开辟一条保持连接服务器的新线程(注意要将broker改成自己的),就可以定时获取MQTT云端上的数据啦!

        效果图:

         重新连接的问题可能是运行太快导致的,可以用sleep减慢速度。

        预备方案:

        利用蓝牙模块的蓝牙配对与主机产生关联,相当于管理员直接与硬件进行沟通,不经过云端。(存在问题:蓝牙距离较短,大概只有10米远)

        做法:

        家居启动后,蓝牙会进入持续配对的状态(红灯闪烁),打开管理员设备蓝牙与家居进行配对,之后利用java的bluetooth类在后台发送和接收语句(原理和云端连接相同)。

        实物效果图(这里还是用手机连的):发送指令BlueLight_5后的结果

(四)完善阶段

        在以上阶段有序进行完之后,笔者想到Mysql数据库实时更新会对JavaWeb的前端会产生一定的影响(数据无法统一)。

        问题1:如何实现jsp页面局部的实时刷新?

       笔者上网查阅很多的资料(其实是踩了很多坑)之后,钻研出了一个属实有点生硬的方法:

        想到js语言可以在后台不断反复运行,那么就可以利用js语句向服务器定时发送请求并接收响应,果然在网上发现了js下的ajax功能,该功能与jsp+servlet原理类似,但是是在js环境下运行,不需要时刻手动点击刷新页面产生事件令页面发生反应。最后只需要在成功收到一次响应的语句后修改一次当前jsp页面标签内的内容,再将整个过程放到一个时刻运行的循环里就可以实现实时刷新啦!wuhu~~!

        目前还在修改这部分的代码,所以没法提供源码,见谅。

(五)结语

        如果大家在做这个项目的时候遇到什么新的问题,或者对某些问题有更好的更快捷的做法,可以在文章下方评论或者直接私信笔者,文章还会持续更新,谢谢大家!

        


点击全文阅读


本文链接:http://zhangshiyu.com/post/29899.html

语句  功能  云端  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1