Java采用Netty实现基于DTU的TCP服务器 + 多端口 + 多协议

前一篇文章我以经实现了基于java原生的socket来实现TCP服务器,并可以解析数据,可以说是一个比较简单的结构。后来我通过研究Netty发出,Netty是一个很好的框架,比较稳定。

1,还是那个拓扑结构

Java采用Netty实现基于DTU的TCP服务器 + 多端口 + 多协议_第1张图片

2.后台流程图

Java采用Netty实现基于DTU的TCP服务器 + 多端口 + 多协议_第2张图片

3.代码

1)MainPrl.java

main函数实现了设备动态加载,可以通过配置文件很灵活的设置设备的增减。

package qx.drc.main;

import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import qx.drc.ser.DataRecvServer;
import qx.drc.utils.CommTool;
import qx.drc.utils.MyPath;

public class MainPrl {
	private static final Logger logger = LoggerFactory.getLogger(MainPrl.class);
	private static DataReceiveConfig cfg=DataReceiveConfig.getInstance();
	
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		
		List list=cfg.listDrcPros;		
		for (DrcProInfo drcProInfo : list) {			 
		    try {	   
		    	logger.info("初始化程序:"+drcProInfo.getParseDataName()); 
		    	CommTool.printInfo("初始化程序:"+drcProInfo.getParseDataName());
		    	
		    	CommTool.printInfo( drcProInfo.getJarPath());
		    	
		    	URL url=new URL("file:"+ drcProInfo.getJarPath());
		        URLClassLoader myClassLoader=new URLClassLoader(new URL[]{url},
		        		Thread.currentThread().getContextClassLoader());
				Class myClass=null;
		        ParseData parseData=null;
				try {
					myClass = myClassLoader.loadClass(drcProInfo.getJarClassFullName());
				    parseData=(ParseData)myClass.newInstance();
				    parseData.setDrcProInfo(drcProInfo);				 
					 
				} catch (ClassNotFoundException e) {					
					e.printStackTrace();
					continue;
				}
				catch (InstantiationException e) {					
					e.printStackTrace();
					continue;
				} catch (IllegalAccessException e) {					
					e.printStackTrace();
					continue;
				}  
				DataRecvServer server = new DataRecvServer(drcProInfo.getPort(),
						drcProInfo.getParseDataName(),parseData);
				try {
					server.start();
				} catch (Exception e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}
				myClassLoader.close();
			} catch (IOException e) {			
				logger.error(e.getMessage()); 
				e.printStackTrace();
			}  
		}

	}

}

 

2) DataRecvServer.java

DataRecvServer类主要实现了新建一个服务器,并初始化服务器设置

import java.io.IOException;

import javax.xml.stream.events.StartDocument;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import qx.drc.main.ParseData;


public class DataRecvServer {
	private static final Logger logger = LoggerFactory.getLogger(DataRecvServer.class);
	private int port; //接收数据端口
	private String proName; // 接收数据名称
	private ParseData parseData; //解析数据对象
	
	EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workerGroup = new NioEventLoopGroup();
	
	public DataRecvServer(int port,String proName,ParseData parseData){
		this.port=port;
		this.proName=proName;
		this.parseData=parseData;
	}
	
    public void start() throws Exception{ 
    	EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        
        //创建ServerBootstrap实例
        ServerBootstrap serverBootstrap=new ServerBootstrap();
        //初始化ServerBootstrap的线程组
        serverBootstrap.group(bossGroup,workerGroup);
        //设置将要被实例化的ServerChannel类
        serverBootstrap.channel(NioServerSocketChannel.class);
        //serverBootstrap.handler(new LoggingHandler(LogLevel.ERROR));
        //在ServerChannelInitializer中初始化ChannelPipeline责任链,并添加到serverBootstrap中
        serverBootstrap.childHandler(new ServerChannelInitializer(this.parseData));
        //标识当服务器请求处理线程全满时,用于临时存放已完成三次握手的请求的队列的最大长度
        serverBootstrap.option(ChannelOption.SO_BACKLOG, 1024);
        // 是否启用心跳保活机机制
        serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);    
        //绑定端口后,开启监听
        /*ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
        if(channelFuture.isSuccess()){
            System.out.println("TCP服务启动 成功---------------");
        }*/
        
        ChannelFuture f = serverBootstrap.bind(port);
        f.addListener(future -> {
            if (future.isSuccess()) {
                System.out.printf("%s 开启端口 %s 成功\n",proName, port);
            } else {
                System.out.printf("%s 开启端口 %s 失败\n", proName,port);
            }
        });
    	
    }

	public void setPort(int port) {
		this.port = port;
	}
	
	public void setProName(String proName) {
		this.proName = proName;
	} 
	
	public void setParseData(ParseData parseData) {
		this.parseData = parseData;
	}


}

 

4)ServerChannelInitializer.java

ServerChannelInitializer类主要实现了,初化服务器通道的,即加载编码器,解码器及数据解析

import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import qx.drc.main.ParseData;


public class ServerChannelInitializer extends ChannelInitializer {
	private static final Logger logger = LoggerFactory.getLogger(ServerChannelInitializer.class);
    static final EventExecutorGroup group = new DefaultEventExecutorGroup(2);
    private ParseData parseData;
     
    public ServerChannelInitializer(ParseData parseData) throws InterruptedException {
    	this.parseData = parseData;
    }
    
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {    
        ChannelPipeline pipeline = socketChannel.pipeline();
        //IdleStateHandler心跳机制,如果超时触发Handle中userEventTrigger()方法
        pipeline.addLast("idleStateHandler",new IdleStateHandler(15, 0, 0, TimeUnit.MINUTES));

        pipeline.addLast(new ByteArrayEncoder());

        pipeline.addLast(new DataDecoder(this.parseData));
        pipeline.addLast(new DataServerHandler(this.parseData));
    }
}

5)DataDecoder.java

DataDecoder是一个公共解码类,解码方式传递接口的方式结出。


import java.util.List;

import org.apache.log4j.lf5.PassingLogRecordFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import qx.drc.main.ParseData;
import qx.drc.utils.ByteUtils;
import qx.drc.utils.CommTool;
/**
 * 解码器
 * @author 70910
 *
 */
public class DataDecoder extends ByteToMessageDecoder{
	protected final Logger log = LoggerFactory.getLogger(getClass());
	private ParseData parseData;
	
	public DataDecoder(ParseData parseData) {
		this.parseData = parseData;
	}

	@Override
	protected void decode(ChannelHandlerContext arg0, ByteBuf in, List list) throws Exception {
		// TODO 自动生成的方法存根
		//System.err.println(parseData.getDrcProInfo().getParseDataName() + "--------解码器正在解码----------");
		try {
			in.retain();
			parseData.decoder(in,list);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	@Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }
}
 
  

6)DataServerHandler.java

公共解析类,通过传递的接口类,实现数据解析与存储


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import qx.drc.main.ParseData;
import qx.drc.utils.ByteUtils;
import qx.drc.utils.CommTool;

public class DataServerHandler extends ChannelInboundHandlerAdapter{
	protected final Logger log = LoggerFactory.getLogger(getClass());
	private ParseData parseData;
	
	public DataServerHandler(ParseData parseData) {
		this.parseData = parseData;
	}

	/**
     * 当我们通道进行激活的时候 触发的监听方法
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {

        System.err.println(parseData.getDrcProInfo().getParseDataName() + "--------通道激活------------");
    }

    /**
     * 当我们的通道里有数据进行读取的时候 触发的监听方法
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx /*NETTY服务上下文*/, Object msg /*实际的传输数据*/) throws Exception {
    	if(msg instanceof byte[]){
    		byte[] bytes = (byte[]) msg;
            	CommTool.printInfo(parseData.getDrcProInfo().getParseDataName()+",接收到数据 " + bytes.length + " bytes");	
        		
                //解析 ,需要判定是否是心跳包               
                if(!parseData.parse(bytes)){
                	log.info(parseData.getDrcProInfo().getParseDataName()+",接收数据解析失败");
                	CommTool.printInfo(parseData.getDrcProInfo().getParseDataName()+",数据解析失败");
                	return;
                }
                
              //存储	
                if(!parseData.save()){
                	log.info(parseData.getDrcProInfo().getParseDataName()+",数据存储失败");
                	CommTool.printInfo(parseData.getDrcProInfo().getParseDataName()+",数据存储失败");
                	return;
                } 
              
                if(!parseData.save2Txt()){
                	log.info(parseData.getDrcProInfo().getParseDataName()+",数据存储到TXT失败");
                	CommTool.printInfo(parseData.getDrcProInfo().getParseDataName()+",数据存储到TXT失败");
                	return;
                } 
                
            	CommTool.printInfo(parseData.getDrcProInfo().getParseDataName()+",数据解析存储成功");
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.err.println(parseData.getDrcProInfo().getParseDataName() + "--------数据读取完毕----------");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        System.err.println(parseData.getDrcProInfo().getParseDataName() + "--------数据读异常----------: ");
        cause.printStackTrace();
        ctx.close();
    }
}

7) ParseData.java

解码,解析接口类,通过继承可以实现具体的解码和解析功能

import java.util.Date;
import java.util.List;

import io.netty.buffer.ByteBuf;

/**
 * 解析接口 
 * @author yangze
 *
 */
public interface ParseData {
	//解析
	boolean parse(byte[] bytes);
	//解码
	boolean decoder(ByteBuf in,List list);
	//保存
	boolean save();  
	//保存文本
	public boolean save2Txt();
	//设置项目信息
	void setDrcProInfo(DrcProInfo drcProInfo);  
	//获取项目信息
	DrcProInfo getDrcProInfo();
	//是否是心跳包
	boolean isHeartPack();
	//获取最后心跳时间
	Date getLastHeartPackDate();
} 
  

8)实现解码与解析类,关注decoder与parse两个方法即可

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import io.netty.buffer.ByteBuf;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;

import qx.drc.main.DeviceInfo;
import qx.drc.main.DrcProInfo;
import qx.drc.main.ParamInfo;
import qx.drc.main.ParseData;
import qx.drc.utils.ByteUtils;
import qx.drc.utils.CRC16_Modbus;
import qx.drc.utils.CommTool;
import qx.drc.utils.DateUtils;
import qx.drc.utils.MyPath;

/**
 * 解析负氧离子数据
 * @author yangze
 * 2019-08-21
 *
 */
public class AnionSensorDataParse implements ParseData {
	private static Logger logger = Logger.getLogger(AnionSensorDataParse.class); 
	public DrcProInfo drcProInfo;	
	private int deviAddr;	//设备地址
	private int funcCode;	//功能码
	private int dataLength; //数据长度
	private int anionData; 
	private String typeOfPk;
	private byte[] srcData;
	
	private DeviceInfo deviceInfo = new DeviceInfo();
	private Map name2ParamInfoMap= new HashMap();
	
	private static Connection conn = null;
	private Date lastDataTime = new Date();
	private boolean isHeartPk = false;
	
    public AnionSensorDataParse(){
    	
    }
    
    // 初始化数据库
 	private boolean iniDB() {
 		if (conn != null){
 			try {
 				if(conn.isClosed()){
 					conn = DriverManager.getConnection(drcProInfo.getDbConnUrl());									
 				}
 				return true;
 			} catch (SQLException ex) {
 				logger.error(drcProInfo.getParseDataName()+","+ex.getMessage());
 	         	CommTool.printInfo(drcProInfo.getParseDataName()+",数据库链接失败");
 				ex.printStackTrace();
 			}					
 		}
 		
 		try {
 			Class.forName("com.mysql.jdbc.Driver").newInstance();
 		} catch (Exception ex) {
 			logger.error(drcProInfo.getParseDataName()+","+ex.getMessage());
          	CommTool.printInfo(drcProInfo.getParseDataName()+",数据库驱动载入失败");
 			return false;
 		}
 		try {
 			conn = DriverManager.getConnection(drcProInfo.getDbConnUrl());
 			return true;
 		} catch (SQLException ex) {
 			logger.error(drcProInfo.getParseDataName()+","+ex.getMessage());
 			CommTool.printInfo(drcProInfo.getParseDataName()+","+ex.toString());
 			return false;
 		}
 	}
	
 	
 	/**
 	 * 获取设备信息
 	 * @return
 	 */
 	private boolean getDeviceInfo() {
 		if(iniDB()){
 			
 			try{
 				Statement stmt = conn.createStatement(); //创建Statement对象

 	            String sql = "select devi_id,devi_code,devi_name from device_info where devi_code='"+ drcProInfo.getDeviceCode()+"'" ;	     
 	            
 	            ResultSet rs = stmt.executeQuery(sql);//创建数据对象
 	            ResultSetMetaData rsmd = rs.getMetaData() ;
 	            int columnCount = rsmd.getColumnCount();
 	            if(columnCount <= 0) return false;
 	            
 	            while (rs.next()){
 	            	deviceInfo.setDeviId(rs.getString(1));
 	            	deviceInfo.setDeviCode(rs.getString(2));
 	            	deviceInfo.setDeviName(rs.getString(3));
 	            }
 	            rs.close();
 	            stmt.close();
 	            return true;
 			}catch(Exception e){
 				logger.error(drcProInfo.getParseDataName()+",error:"+e.getMessage());
			    CommTool.printInfo(drcProInfo.getParseDataName()+",获取设备信息错误");
				return false;
	        }
		}
		else
			return false;  
 	}
 	
 	/**
 	 * 获取设备监测指标信息
 	 * @return
 	 */
 	private boolean getDeviceParamsInfo() {
 		if(iniDB()){
 			try{
 				Statement stmt = conn.createStatement(); //创建Statement对象

 	           String sql = "SELECT p.para_id,p.para_name,p.para_unit FROM devi_para_rel d " + 
 	   				"LEFT JOIN param_info p ON p.para_id = d.para_id " + 
 	   				"where d.devi_id='" + deviceInfo.getDeviId() + "'";
 	           
 	            ResultSet rs = stmt.executeQuery(sql);//创建数据对象
 	            ResultSetMetaData rsmd = rs.getMetaData() ;
	            int columnCount = rsmd.getColumnCount();
	            if(columnCount <= 0) return false;
	            
 	            while (rs.next()){
 	            	ParamInfo paramInfo = new ParamInfo();
 	            	paramInfo.setParaId(rs.getString(1));
 	            	paramInfo.setParaName(rs.getString(2));
 	            	paramInfo.setParaUnit(rs.getString(3));
 	            	name2ParamInfoMap.put(paramInfo.getParaName(), paramInfo);
 	            }
 	            rs.close();
 	            stmt.close();
 	            return true;
 			}catch(Exception e){
 				logger.error(drcProInfo.getParseDataName()+",error:"+e.getMessage());
			    CommTool.printInfo(drcProInfo.getParseDataName()+",获取设备信息错误");
				return false;
	        }
		}
		else
			return false;  
 	}
 	
 	 @Override
 	public boolean decoder(ByteBuf in,List list) {
 		if(in.readableBytes() < 9) {
 			//数据包长度不够,继续接收再处理
 			System.err.println(drcProInfo.getParseDataName() + "-----------数据包不完整,继续读取");
			return false; 
		}
 		else{
 			int headIndex = in.readerIndex();
 			while(in.readableBytes() > 1) {
 				//读两个字节
 				byte[] headArray = new byte[2];
 				in.readBytes(headArray);
 				//重置读取位置
 	            if(headArray[0] == 0x01 && headArray[1] == 0x03) {
 	            	//如果为头,跳出循环
 	            	break;
 	            }
 	           headIndex += 2;
 			}
 			
 			in.readerIndex(headIndex);
 			if(in.readableBytes() < 9) {
 				//余下的数据是否足够一个包
 				System.err.println(drcProInfo.getParseDataName() + "-----------余下的数据不足够一个包,继续接收......");
 				return false;
 			}
 			else {
 				byte[] data = new byte[9];
 				in.readBytes(data);
 	            list.add(data);
 	            System.err.println(drcProInfo.getParseDataName() + "------------解码器解码成功");
 			}
 			
 		}
 	
 		 return true;
 	}
    @Override
    //01 03 04 A1 20 00 07 99 C7
    //报文解释说明:“01”设备地址;“03”读功能码;“04”数据长度;“A1 20 00 07”为寄存器值;“99 C7”校验码。计算负氧离子: 0x0007A120=500000个
    public boolean parse(byte[] data){
    	isHeartPk = false;
    	srcData = Arrays.copyOfRange(data, 0, 9);
    	String preStr=drcProInfo.getParseDataName();
		int indexNow=0;
		//设备地址
		byte[] arr= Arrays.copyOfRange(srcData, indexNow, indexNow+1);
		deviAddr=bytes2Byte255(arr[0]);	
		indexNow+=1;
		
		if(deviAddr != 0x01)
		{
			logger.error(preStr+",数据包:包头错误");
			CommTool.printInfo(preStr+"数据包:包头错误");
			return false;			
		}
		//功能码
		arr=Arrays.copyOfRange(srcData, indexNow,indexNow+ 1);	    	
		funcCode=bytes2Byte255(arr[0]);
		indexNow+=1;
		
		//System.out.println("功能码:"+  CommTool.getHexString(arr));
		
		if(funcCode == 0x03)
		{
			typeOfPk = "读取负氧离子个数";
			arr=Arrays.copyOfRange(srcData, indexNow,indexNow+ 1);	    	
			dataLength=bytes2Byte255(arr[0]);		
	        indexNow++;
	        
	        byte[] anionDataArr =  new byte[4];
	        anionDataArr[1] = (Arrays.copyOfRange(srcData, indexNow, indexNow+1))[0];
	        indexNow++;
	        anionDataArr[0] = (Arrays.copyOfRange(srcData, indexNow, indexNow+1))[0];
	        indexNow++;
	        anionDataArr[3] = (Arrays.copyOfRange(srcData, indexNow, indexNow+1))[0];
	        indexNow++;
	        anionDataArr[2] = (Arrays.copyOfRange(srcData, indexNow, indexNow+1))[0];
	        indexNow++;
	        anionData = ByteUtils.getInt(anionDataArr);
	        
	        //System.out.println("负氧离子16进制:" +  CommTool.getHexString(CommTool.intToByteArray(anionData)));
	        //System.out.println("负氧离子个数:" + anionData);
	               
	        if(!crc16Validate(srcData, 7)){
				byte[] arr_temp=Arrays.copyOfRange(srcData,0,dataLength+2);
				String str=CommTool.getHexString(arr_temp); 
	        	logger.error(preStr+"CRC16校验错误.["+str+"]");
				CommTool.printInfo(preStr+"CRC16校验错误");				
				return false;
			}
	        indexNow+=2;
	        
	        //打印输出
	        if(drcProInfo.isOutputConsole()){
		        System.out.println("**************************");
		        CommTool.printHexString(srcData);
		        System.out.println(" package size (byte): "+String.valueOf(indexNow));
		        System.out.println(" package type: "+typeOfPk);
		        byte[] funcCodeByte = {CommTool.intToByteArray(funcCode)[0]};
		        System.out.println(" function code: "+CommTool.getHexString(funcCodeByte));
		        byte[] deviAddrByte = {CommTool.intToByteArray(deviAddr)[0]};
		        System.out.println(" address of anion sensor: " + CommTool.getHexString(deviAddrByte));
		        System.out.println(" data size: "+ dataLength);
		        System.out.println(" anion num: "+ anionData);
		        System.out.println("**************************");
	        }
	        return true;
		}
		else
		{
		   CommTool.printInfo(preStr+",数据包类型不正确");
		   logger.error(preStr+",数据包类型不正确");
		   return false;
		}
	}
    @Override
 	public boolean isHeartPack() {
 		
 		return this.isHeartPk;
 	}
 	
 	@Override
    public Date getLastHeartPackDate() {
    	return this.lastDataTime;
    }
 	
    private boolean crc16Validate(byte[] byteArr,int datalength){
		byte[] dataArr = new byte[datalength];
		byte[] crc16Arr=new byte[2];
		System.arraycopy(byteArr, 0, dataArr, 0, datalength);
		System.arraycopy(byteArr, datalength, crc16Arr, 0, 2);
		int crc16=CRC16_Modbus.calcCrc16(dataArr,0,dataArr.length);
		int crc16_=(int)ByteUtils.getInt(new byte[]{crc16Arr[0],crc16Arr[1],0,0});
		if(crc16 == crc16_) return true;
		else return false;
	}
	
	private int bytes2Byte255(byte b) {  
	     int num = 0;  	     
	     num |= (b & 0xff);  	      
	     return num;  
	} 
	
	@Override
	public boolean save2Txt() {
		if(drcProInfo.getSave2Txt()) {
			String txtPath = drcProInfo.getSave2TxtPath() +  "/" + DateUtils.getDate("yyyyMMdd") + ".txt";
			String content = CommTool.getHexString(srcData);
			return saveContent2Txt(content,txtPath);
		}
		return true;
	}
	
	
	public boolean saveContent2Txt(String content,String txtPath) {
		File file = new File(txtPath);
		try {
			
			String parentDir =file.getParent();
			if (!MyPath.check2CreatePath(parentDir))      
			{        
				logger.error(drcProInfo.getParseDataName()+",创建路径失败:" + parentDir);
			    CommTool.printInfo(drcProInfo.getParseDataName()+",创建路径失败:" + parentDir);
				return false; 
			}
			
			if(!file.exists()) {
				file.createNewFile();
			}
			OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file,true),"GB2312");
			BufferedWriter bw = new BufferedWriter(osw); 
			bw.write(DateUtils.getDate("yyyy-MM-dd HH:mm:ss") + " " + content+"\r\n");
			bw.close();
			return true;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error(drcProInfo.getParseDataName()+",将数据保存到TXT失败:" + e.getMessage());
		    CommTool.printInfo(drcProInfo.getParseDataName()+",将数据保存到TXT失败:" + e.getMessage());
			return false;
		}
	}
	
	@Override	
    public boolean save() {	
		if(!getDeviceInfo()) return false;
 		if(!getDeviceParamsInfo()) return false;
		if(iniDB()){
			String sql = "insert into data_real(dare_id,devi_id,para_id,dare_value,dare_datetime)"
					+ "values (?,?,?,?,?)";	
			PreparedStatement pstmt;
			
			try {
				pstmt = (PreparedStatement) conn.prepareStatement(sql);
				
				Date da=new Date();	
				pstmt.setString(1, CommTool.uuid());
				pstmt.setString(2, deviceInfo.getDeviId());
				pstmt.setString(3, name2ParamInfoMap.get("负氧离子").getParaId());
				pstmt.setFloat(4, anionData);
				pstmt.setTimestamp(5, new java.sql.Timestamp(da.getTime()));
				
				int res = pstmt.executeUpdate();
				pstmt.close();					
			} catch (SQLException e) {
			    logger.error(drcProInfo.getParseDataName()+",error:"+e.getMessage());
			    CommTool.printInfo(drcProInfo.getParseDataName()+",存储错误");
				return false;
			}
			return true;
		}
		else
			return false;    
	}

	@Override
	public void setDrcProInfo(DrcProInfo drcProInfo) {
		this.drcProInfo=drcProInfo;
	}
	
	@Override
	public DrcProInfo getDrcProInfo() {
		return this.drcProInfo;
	}

	
} 
  

 

你可能感兴趣的:(JAVA)