前言:这段时间做了一个课程设计,内容是将温湿度传感器采集到的温湿度数据上传到web服务器并以表格或者折线图的方式可视化展示出来。话不多说:上代码!!!
①Netty服务器搭建
NettyServer.java
/**
* @author cx
* @Time 2020/6/29 22:00
* @Description netty 服务器配置
*/
public class NettyServer {
public void start(InetSocketAddress socketAddress){
/**new 一个主线程组*/
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
/**new 一个工作线程组*/
EventLoopGroup workGroup = new NioEventLoopGroup(200);
ServerBootstrap bootstrap = new ServerBootstrap()
.group(bossGroup,workGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ServerChannelInitializer())
.localAddress(socketAddress)
/**设置队列的大小*/
.option(ChannelOption.SO_BACKLOG,1024)
/**两小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文*/
.childOption(ChannelOption.SO_KEEPALIVE,true);
/**绑定端口,开始接收进来的连接*/
try{
ChannelFuture future = bootstrap.bind(socketAddress).sync();
System.out.println("服务器ip为:"+socketAddress.getHostName());
System.out.println("服务器端口号为:"+socketAddress.getPort());
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
/**关闭主线程组*/
bossGroup.shutdownGracefully();
/**关闭工作线程组*/
workGroup.shutdownGracefully();
}
}
}
NettyServerHandler.java
/**
* @author cx
* @Time 2020/6/29 22:23
* @Description 服务端业务处理
*/
@Component
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
/**获取实例化对象*/
@Autowired
protected IHumitureService humitureService;
private static NettyServerHandler serverHandler;
/**配合@Component注解获取service层的bean*/
@PostConstruct
public void init(){
serverHandler = this;
serverHandler.humitureService = this.humitureService;
}
/**
* 客户端连接会触发
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("客户端发起连接!!!!");
}
/**
* 客户端发消息会触发
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
/**获取客户端的IP*/
InetSocketAddress insocket = (InetSocketAddress)ctx.channel().remoteAddress();
String ip = insocket.getAddress().getHostAddress();
/**将温湿度数据处理*/
String tem = msg.toString();
String[] arr = tem.split(",");
Humiture humiture = new Humiture();
humiture.setTemp(arr[0]);
humiture.setHumidity(arr[1]);
humiture.setIp(ip);
/**调用业务层方法将数据写入数据库*/
serverHandler.humitureService.insertData(humiture);
System.out.println("服务器接收到客户端的温度,湿度---"+msg.toString());
System.out.println("温湿度写入数据库成功!!!!");
ctx.write("receive OK!");
ctx.flush();
}
/**
* 发生异常触发
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
注意:上面代码解决了一个问题,就是如何在controller层外获得bean,然后调用业务层方法将获得的数据写入数据库。方法是在handler类上加一个@Component注解,然后写一个init()方法,init()方法上面加一个@PostConstruct注解将bean实例化
ServerChannelInitializer .java
/**
* @author cx
* @Time 2020/6/29 22:06
* @Description 初始化编码器
*/
public class ServerChannelInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
/**添加编解码*/
socketChannel.pipeline().addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
socketChannel.pipeline().addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
socketChannel.pipeline().addLast(new NettyServerHandler());
}
}
②controller层代码
HumitureController .java
/**
* @author cx
* @Time 2020/6/28 15:32
* @Description 温湿度采集 控制层
*/
@Controller
public class HumitureController {
@Autowired
private IHumitureService iHumitureService;
@GetMapping("/test")
@ResponseBody
public List<Humiture> list()
{
return iHumitureService.listHumiture();
}
@GetMapping("/list")
@ResponseBody
public Map<String,Object> selectAll()
{
Map<String,Object> map = new HashMap<>();
List<Humiture> data = iHumitureService.listHumiture();
map.put("code",0);
map.put("msg","随便写点东西");
map.put("count",10);
map.put("data",data);
return map;
}
}
IndexController .java
/**
* @author cx
* @Time 2020/6/28 10:22
* @Description 页面信息展示 控制层
*/
@Controller
public class IndexController {
@Autowired
private IHumitureService iHumitureService;
@GetMapping("/")
public String hello(ModelMap modelMap)
{
List<Humiture> list = iHumitureService.listHumiture();
modelMap.addAttribute("message",list);
return "index";
}
@GetMapping("/humiture")
public String humiture(ModelMap modelMap)
{
List<Humiture> list = iHumitureService.listHumiture();
modelMap.addAttribute("value",list);
return "humiture";
}
}
③实体层
/**
* @author cx
* @Time 2020/6/28 15:11
* @Description 温湿度检测 实体
*/
public class Humiture {
/**数据编号*/
private int id;
/**温度*/
private String temp;
/**湿度*/
private String humidity;
/**ip地址*/
private String ip;
/**采集时间*/
private String time;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTemp() {
return temp;
}
public void setTemp(String temp) {
this.temp = temp;
}
public String getHumidity() {
return humidity;
}
public void setHumidity(String humidity) {
this.humidity = humidity;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
④mapper层
HumitureMapper .java
/**
* @author cx
* @Time 2020/6/28 15:18
* @Description 温湿度采集 数据层
*/
@Repository
public interface HumitureMapper {
/**
* @description 温湿度采集 查询
*
* @param
* @return 温湿度采集 列表
*/
public List<Humiture> listHumiture();
/**
* @description 温湿度采集 存库
*
* @param
* @return 温湿度采集 存库
*/
public int insertData(Humiture humiture);
}
⑤service层代码
IHumitureService .java
/**
* @author cx
* @Time 2020/6/28 15:22
* @Description 温湿度采集 业务层接口
*/
public interface IHumitureService {
/**
* @description 温湿度采集 查询
*
* @param
* @return 温湿度采集 列表
*/
public List<Humiture> listHumiture();
/**
* @description 温湿度采集 存库
*
* @param
* @return 温湿度采集 存库
*/
public int insertData(Humiture humiture);
}
HumitureServiceImpl .java
/**
* @author cx
* @Time 2020/6/28 15:23
* @Description 温湿度采集 业务层实现
*/
@Service
public class HumitureServiceImpl implements IHumitureService {
@Autowired
private HumitureMapper humitureMapper;
/**
* @description 温湿度采集 查询
*
* @param
* @return 温湿度采集 列表
*/
@Override
public List<Humiture> listHumiture()
{
return humitureMapper.listHumiture();
}
/**
* @description 温湿度采集 存库
*
* @param
* @return 温湿度采集 存库
*/
@Override
public int insertData(Humiture humiture){
return humitureMapper.insertData(humiture);
}
}
⑥resource下的mapper
HumitureMapper .xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hunau.springboot.mapper.HumitureMapper">
<resultMap id="HumitureResult" type="Humiture">
<result property="id" column="id"/>
<result property="temp" column="temp"/>
<result property="humidity" column="humidity"/>
<result property="ip" column="ip"/>
<result property="time" column="time"/>
</resultMap>
<select id="listHumiture" resultMap="HumitureResult">
select * from tb_humiture
</select>
<insert id="insertData" parameterType="Humiture">
insert into tb_humiture
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="temp != null and temp != '' ">temp,</if>
<if test="humidity != null and humidity != '' ">humidity,</if>
<if test="ip != null and ip != '' ">ip,</if>
<if test="time != null and time != '' ">time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="temp != null and temp != '' ">#{temp},</if>
<if test="humidity != null and humidity != '' ">#{humidity},</if>
<if test="ip != null and ip != '' ">#{ip},</if>
<if test="time != null and time != '' ">#{time},</if>
</trim>
</insert>
</mapper>
⑦前端代码
humiture.html
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>testtitle>
<script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/echarts-all-3.js">script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
head>
<body>
<div id="main" style="width: 600px;height:400px;position: absolute; top:50%; left: 50%; margin-top: -200px;margin-left: -300px">div>
<script th:inline="javascript">
/**基于准备好的dom,初始化echarts实例*/
var myChart = echarts.init(document.getElementById('main'));
var data = [[${value}]];
console.log(data);
/**温度*/
var temperature = [];
/**湿度*/
var humidity = [];
/**采集时间*/
var coltime = [];
/**获取温度打包为数组*/
for (i in data)
temperature.push(data[i].temp);
console.log(temperature);
/**获取湿度打包为数组*/
for (i in data)
humidity.push(data[i].humidity);
console.log(humidity);
for (i in data)
coltime.push(data[i].time);
console.log(coltime);
/**指定图表的配置项和数据*/
option = {
title: {
text: '温湿度动态图'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['温度', '湿度']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: coltime
},
yAxis: {
type: 'value'
},
series: [
{
name: '温度',
type: 'line',
stack: '总量',
data: temperature
},
{
name: '湿度',
type: 'line',
stack: '总量',
data: humidity
}
]
};
/**使用刚指定的配置项和数据显示图表*/
myChart.setOption(option);
script>
body>
html>
index.html
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>testtitle>
<script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/echarts-all-3.js">script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
head>
<body>
<div id="main" style="width: 600px;height:400px;position: absolute; top:50%; left: 50%; margin-top: -200px;margin-left: -300px">div>
<script th:inline="javascript">
/**基于准备好的dom,初始化echarts实例*/
var myChart = echarts.init(document.getElementById('main'));
var data = [[${value}]];
console.log(data);
/**温度*/
var temperature = [];
/**湿度*/
var humidity = [];
/**采集时间*/
var coltime = [];
/**获取温度打包为数组*/
for (i in data)
temperature.push(data[i].temp);
console.log(temperature);
/**获取湿度打包为数组*/
for (i in data)
humidity.push(data[i].humidity);
console.log(humidity);
for (i in data)
coltime.push(data[i].time);
console.log(coltime);
/**指定图表的配置项和数据*/
option = {
title: {
text: '温湿度动态图'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['温度', '湿度']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: coltime
},
yAxis: {
type: 'value'
},
series: [
{
name: '温度',
type: 'line',
stack: '总量',
data: temperature
},
{
name: '湿度',
type: 'line',
stack: '总量',
data: humidity
}
]
};
/**使用刚指定的配置项和数据显示图表*/
myChart.setOption(option);
script>
body>
html>
代码到此结束
下面上效果图
客户端发送温湿度格式为 字符串,中间以逗号隔开例如“29,88”
(温度,湿度)服务器就会接收到对应的温湿度信息并且存入数据库!
如果觉得总结得还OK的话,不妨点个赞,创作不易,不想被白嫖,求点赞,奥利给!!!