当前位置:   article > 正文

智能家居项目总结_编写智能家电后端要点

编写智能家电后端要点

目录

(一)项目概述​

(二)开始阶段

        问题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文件中进行映射匹配。

  1. <servlet>
  2. <servlet-name>loginServlet</servlet-name>
  3. <servlet-class>jspservlet.servlet.LoginServlet</servlet-class>
  4. </servlet>
  5. <servlet-mapping>
  6. <servlet-name>loginServlet</servlet-name>
  7. <url-pattern>/login</url-pattern>
  8. </servlet-mapping>

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

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

  1. package jspservlet.db;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. public class DBConnect {
  5. private final String DBDRIVER = "com.mysql.cj.jdbc.Driver" ;
  6. private final String DBURL = "jdbc:mysql://localhost:3306/smarthome2?useSSL=false&serverTimezone=UTC" ;
  7. private final String DBUSER = "本地账号" ;
  8. private final String DBPASSWORD = "密码" ;
  9. private Connection conn = null ;
  10. public DBConnect() {
  11. try{
  12. Class.forName(DBDRIVER) ;
  13. this.conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD) ;
  14. }catch (Exception e){
  15. System.out.println(e.getMessage());
  16. }
  17. }
  18. public Connection getConnection(){
  19. return this.conn ;
  20. }
  21. public void close(){
  22. try{
  23. this.conn.close() ;
  24. }catch (Exception e){ }
  25. }
  26. }
  1. String sql = "需要的sql语句";
  2. PreparedStatement pstmt = null ;
  3. DBConnect dbc = null;
  4. try{
  5. dbc = new DBConnect() ;
  6. pstmt = dbc.getConnection().prepareStatement(sql) ;//运行sql语句
  7. ResultSet rs = pstmt.executeQuery();
  8. while(rs.next()){
  9. rs.getString("根据自己的填写"));//得到select语句对应的内容
  10. }
  11. rs.close() ;
  12. pstmt.close() ;
  13. }
  14. catch (SQLException e){
  15. System.out.println(e.getMessage());
  16. }
  17. finally{
  18. dbc.close() ;
  19. }

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

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

  1. 后端语句----------------------------------------------------------------------------
  2. public void doGet(HttpServletRequest req,HttpServletResponse res) {
  3. LightDAO dao=new LightDAOImpl();//创建后台实现类,为实现数据查询功能
  4. HttpSession session=req.getSession();
  5. ArrayList<Light> linfo=new ArrayList<Light>();
  6. ArrayList<String> ltype=new ArrayList<>();
  7. try {
  8. session.setAttribute("随便取个名字", 想传的内容);
  9. linfo=dao.allLightid();//后端实现的方法(自己写去)
  10. ltype=dao.allLightType();
  11. session.setAttribute("linfo", linfo);
  12. session.setAttribute("ltype",ltype);
  13. res.sendRedirect("./light.jsp");//将响应交给前端页面
  14. }
  15. catch(Exception e){
  16. e.printStackTrace();
  17. }
  18. }
  19. 前端语句----------------------------------------------------------------------------
  20. <% ArrayList<Light> l = (ArrayList<Light>)session.getAttribute("linfo"); %>
  21. <% int i=0;%>
  22. <% while (i<l.size()){ %>
  23. <% Light k=l.get(i); %>
  24. <% String cl=k.getType(); %>
  25. <% for (j=0;j<type.size();j++){ %>
  26. <% String t=type.get(j); %>
  27. <% if (cl.equals(t)){ %>
  28. <div class= "col-lg-4 col-md-6 col-sm-12 single_project cat<%=j+1%>">
  29. <div class="grid_item">
  30. <div class="deneb_img">
  31. <img src=<%= l.get(i).getImg() %> class="img-fluid" alt="">
  32. </div>
  33. <div class="deneb_info">
  34. <h4><a href="./inf?action=light&id=<%=k.getId() %>"><%= l.get(i).getType() %></a></h4>
  35. <p id="zz">brightness:<%= l.get(i).getState() %></p>
  36. </div>
  37. </div>
  38. </div>
  39. <% }}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>
  1. String judge=req.getParameter("action");
  2. if (judge!=null) {
  3. if (judge.equals("changeon")) {
  4. }
  5. if (judge.equals("changeoff")) {
  6. }
  7. if (judge.equals("delete")) {
  8. }
  9. }

(三)整合阶段

        在笔者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~~!

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

(五)结语

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

        

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/893481
推荐阅读
相关标签
  

闽ICP备14008679号