36 changed files with 0 additions and 2151 deletions
@ -1,42 +0,0 @@ |
|||||
package com.xr.device_car.config.common; |
|
||||
|
|
||||
import com.alibaba.excel.converters.Converter; |
|
||||
import com.alibaba.excel.enums.CellDataTypeEnum; |
|
||||
import com.alibaba.excel.metadata.GlobalConfiguration; |
|
||||
import com.alibaba.excel.metadata.data.ReadCellData; |
|
||||
import com.alibaba.excel.metadata.data.WriteCellData; |
|
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
|
||||
|
|
||||
import java.time.LocalDate; |
|
||||
import java.time.format.DateTimeFormatter; |
|
||||
|
|
||||
/** |
|
||||
* @Author: ChenTaoTao |
|
||||
* @Date: 2022/3/28 10:07 |
|
||||
* @Describe: |
|
||||
*/ |
|
||||
public class LocalDateConverter implements Converter<LocalDate> { |
|
||||
|
|
||||
@Override |
|
||||
public Class<LocalDate> supportJavaTypeKey() { |
|
||||
return LocalDate.class; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public CellDataTypeEnum supportExcelTypeKey() { |
|
||||
return CellDataTypeEnum.STRING; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
@Override |
|
||||
public LocalDate convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
|
||||
return LocalDate.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd")); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public WriteCellData<String> convertToExcelData(LocalDate value, ExcelContentProperty contentProperty, |
|
||||
GlobalConfiguration globalConfiguration) { |
|
||||
return new WriteCellData<>(value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,41 +0,0 @@ |
|||||
package com.xr.device_car.config.common; |
|
||||
|
|
||||
import com.alibaba.excel.converters.Converter; |
|
||||
import com.alibaba.excel.enums.CellDataTypeEnum; |
|
||||
import com.alibaba.excel.metadata.GlobalConfiguration; |
|
||||
import com.alibaba.excel.metadata.data.ReadCellData; |
|
||||
import com.alibaba.excel.metadata.data.WriteCellData; |
|
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
|
||||
|
|
||||
import java.time.LocalDateTime; |
|
||||
import java.time.format.DateTimeFormatter; |
|
||||
|
|
||||
/** |
|
||||
* @Author: ChenTaoTao |
|
||||
* @Date: 2022/3/28 10:07 |
|
||||
* @Describe: |
|
||||
*/ |
|
||||
public class LocalDateTimeConverter implements Converter<LocalDateTime> { |
|
||||
@Override |
|
||||
public Class<LocalDateTime> supportJavaTypeKey() { |
|
||||
return LocalDateTime.class; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public CellDataTypeEnum supportExcelTypeKey() { |
|
||||
return CellDataTypeEnum.STRING; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
@Override |
|
||||
public LocalDateTime convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
|
||||
return LocalDateTime.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public WriteCellData<String> convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty, |
|
||||
GlobalConfiguration globalConfiguration) { |
|
||||
return new WriteCellData<>(value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,281 +0,0 @@ |
|||||
package com.xr.device_car.config.common; |
|
||||
|
|
||||
import com.xr.device_car.config.utils.HttpResponseBean; |
|
||||
import org.apache.http.*; |
|
||||
import org.apache.http.client.HttpRequestRetryHandler; |
|
||||
import org.apache.http.client.config.CookieSpecs; |
|
||||
import org.apache.http.client.config.RequestConfig; |
|
||||
import org.apache.http.client.methods.HttpPost; |
|
||||
import org.apache.http.client.protocol.HttpClientContext; |
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier; |
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
|
||||
import org.apache.http.entity.ContentType; |
|
||||
import org.apache.http.entity.StringEntity; |
|
||||
import org.apache.http.impl.client.CloseableHttpClient; |
|
||||
import org.apache.http.impl.client.HttpClients; |
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
|
||||
import org.apache.http.protocol.HttpContext; |
|
||||
import org.apache.http.ssl.SSLContextBuilder; |
|
||||
import org.apache.http.util.EntityUtils; |
|
||||
import org.slf4j.Logger; |
|
||||
import org.slf4j.LoggerFactory; |
|
||||
import org.springframework.util.StringUtils; |
|
||||
|
|
||||
import javax.net.ssl.HostnameVerifier; |
|
||||
import javax.net.ssl.SSLContext; |
|
||||
import javax.net.ssl.SSLHandshakeException; |
|
||||
import java.io.IOException; |
|
||||
import java.net.ConnectException; |
|
||||
import java.util.Arrays; |
|
||||
import java.util.regex.Matcher; |
|
||||
import java.util.regex.Pattern; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* Http请求客户端 |
|
||||
* @author ChenYongHeng |
|
||||
* @since 2019/5/27 |
|
||||
*/ |
|
||||
public class RESTClient { |
|
||||
|
|
||||
|
|
||||
private static Logger log = LoggerFactory.getLogger(RESTClient.class); |
|
||||
|
|
||||
|
|
||||
|
|
||||
private volatile static RESTClient HttpClientConnectionPool; |
|
||||
|
|
||||
private static final String USERAGENT = "SZ-JAVA"; |
|
||||
private static final String CHARSET = "UTF-8"; |
|
||||
|
|
||||
private static final int MAX_TOTAL_CONNECTIONS = 200; |
|
||||
private static final int MAX_ROUTE_CONNECTIONS = 100; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 连接时间 |
|
||||
*/ |
|
||||
private static final int CONNECT_TIMEOUT = 5000; |
|
||||
/** |
|
||||
* 获取内容时间 |
|
||||
*/ |
|
||||
private static final int SOCKET_TIMEOUT = 30000; |
|
||||
|
|
||||
private static PoolingHttpClientConnectionManager cm = null; |
|
||||
|
|
||||
|
|
||||
private static CloseableHttpClient HTTP_CLIENTS; |
|
||||
|
|
||||
/** |
|
||||
* 初始化连接池 |
|
||||
*/ |
|
||||
static{ |
|
||||
try { |
|
||||
cm = new PoolingHttpClientConnectionManager(); |
|
||||
cm.setMaxTotal(MAX_TOTAL_CONNECTIONS); |
|
||||
// 默认设置为2
|
|
||||
cm.setDefaultMaxPerRoute(MAX_ROUTE_CONNECTIONS); |
|
||||
// 客户端请求的默认设置
|
|
||||
RequestConfig defaultRequestConfig = RequestConfig.custom() |
|
||||
.setSocketTimeout(SOCKET_TIMEOUT) |
|
||||
.setConnectTimeout(CONNECT_TIMEOUT) |
|
||||
.setConnectionRequestTimeout(CONNECT_TIMEOUT) |
|
||||
.setRedirectsEnabled(false) |
|
||||
.setCookieSpec(CookieSpecs.STANDARD_STRICT) |
|
||||
.build(); |
|
||||
|
|
||||
// 请求重试处理
|
|
||||
HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() { |
|
||||
@Override |
|
||||
public boolean retryRequest(IOException exception, |
|
||||
int executionCount, HttpContext context) { |
|
||||
// 如果超过最大重试次数,那么就不要继续了
|
|
||||
if (executionCount >= 2) { |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
// 如果服务器丢掉了连接,那么就重试
|
|
||||
if (exception instanceof NoHttpResponseException) { |
|
||||
return true; |
|
||||
} |
|
||||
// 不要重试SSL握手异常
|
|
||||
if (exception instanceof SSLHandshakeException) { |
|
||||
return false; |
|
||||
} |
|
||||
HttpRequest request = (HttpRequest) context.getAttribute(HttpClientContext.HTTP_REQUEST); |
|
||||
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); |
|
||||
// 如果请求被认为是幂等的,那么就重试
|
|
||||
if (idempotent) { |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
}; |
|
||||
// https 信任所有
|
|
||||
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -> true).build(); |
|
||||
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; |
|
||||
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); |
|
||||
|
|
||||
HTTP_CLIENTS = HttpClients.custom() |
|
||||
.setConnectionManager(cm) |
|
||||
.setDefaultRequestConfig(defaultRequestConfig) |
|
||||
.setRetryHandler(httpRequestRetryHandler) |
|
||||
//https
|
|
||||
.setSSLSocketFactory(sslSocketFactory) |
|
||||
.build(); |
|
||||
} catch (Exception e) { |
|
||||
e.printStackTrace(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
private RESTClient(){} |
|
||||
|
|
||||
/** |
|
||||
* 获取HttpClientConnectionPool对象,这是单例方法 |
|
||||
* |
|
||||
* @return |
|
||||
*/ |
|
||||
public static RESTClient getClientConnectionPool() { |
|
||||
if (HttpClientConnectionPool == null) { |
|
||||
synchronized (RESTClient.class) { |
|
||||
if (HttpClientConnectionPool == null) { |
|
||||
HttpClientConnectionPool = new RESTClient(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return HttpClientConnectionPool; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 一般情况下是AuthToken使用 |
|
||||
* @param url |
|
||||
* @param xmlFileName |
|
||||
* @return |
|
||||
*/ |
|
||||
public HttpResponseBean postXML(String url, String xmlFileName){ |
|
||||
return postXML( url, xmlFileName,""); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 一般情况下是DigestBean使用 |
|
||||
* @param url |
|
||||
* @param xmlFileName |
|
||||
* @param auth |
|
||||
* @return |
|
||||
*/ |
|
||||
public HttpResponseBean postXML(String url,String xmlFileName,String auth){ |
|
||||
HttpPost httpPost = new HttpPost(url); |
|
||||
String seqNum = String.valueOf(System.currentTimeMillis()); |
|
||||
httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/soap+xml; charset=utf-8"); |
|
||||
if(StringUtils.hasLength(xmlFileName))httpPost.setEntity(new StringEntity(xmlFileName, ContentType.APPLICATION_JSON)); |
|
||||
if(StringUtils.hasLength(auth)) httpPost.setHeader("Authorization",auth); |
|
||||
log.info(seqNum+">>> "+httpPost.toString()); |
|
||||
log.info(seqNum+"Body>>> " +xmlFileName); |
|
||||
return httpPost(httpPost,seqNum); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Post方法封装,发送post请求,获取响应内容 |
|
||||
*/ |
|
||||
public String fetchByPostMethod(String url, String jsonStr) { |
|
||||
String resultStr = null; |
|
||||
HttpPost httpPost = httpPostAddHeader(url, jsonStr); |
|
||||
String seqNum = String.valueOf(System.currentTimeMillis()); |
|
||||
log.info(seqNum + ">>> " + httpPost.toString()); |
|
||||
log.info(seqNum + "Body>>> " + jsonStr); |
|
||||
HttpResponse response; |
|
||||
try { |
|
||||
response = HTTP_CLIENTS.execute(httpPost); |
|
||||
HttpEntity entity = response.getEntity(); |
|
||||
resultStr = EntityUtils.toString(entity, CHARSET); |
|
||||
EntityUtils.consume(entity); |
|
||||
} catch (IOException ce) {// 服务器请求失败
|
|
||||
log.error(ce.getMessage()); |
|
||||
} finally { |
|
||||
httpPost.abort(); |
|
||||
} |
|
||||
log.info(seqNum + "<<< " + resultStr); |
|
||||
return resultStr; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 添加头部信息 |
|
||||
* @param url |
|
||||
* @param jsonStr |
|
||||
* @return |
|
||||
*/ |
|
||||
private HttpPost httpPostAddHeader(String url, String jsonStr){ |
|
||||
HttpPost httpPost = new HttpPost(url); |
|
||||
httpPost.setEntity(new StringEntity(jsonStr, ContentType.APPLICATION_JSON)); |
|
||||
httpPost.addHeader(HttpHeaders.USER_AGENT, USERAGENT); |
|
||||
httpPost.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()); |
|
||||
return httpPost; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* httppost |
|
||||
* @param httpPost |
|
||||
* @param seqNum |
|
||||
* @return |
|
||||
*/ |
|
||||
private HttpResponseBean httpPost(HttpPost httpPost,String seqNum ) { |
|
||||
String resultStr = null; |
|
||||
HttpResponse response = null; |
|
||||
try{ |
|
||||
response = HTTP_CLIENTS.execute(httpPost); |
|
||||
int statusCode = response.getStatusLine().getStatusCode(); |
|
||||
if(statusCode == HttpStatus.SC_UNAUTHORIZED) { |
|
||||
//如果是401直接返回
|
|
||||
return new HttpResponseBean(null, Arrays.asList(response.getAllHeaders()),response.getStatusLine().getStatusCode()); |
|
||||
} |
|
||||
HttpEntity entity = response.getEntity(); |
|
||||
resultStr = EntityUtils.toString(entity,CHARSET); |
|
||||
EntityUtils.consume(entity); |
|
||||
}catch (ConnectException ce){// 服务器请求失败
|
|
||||
log.error("ConnectException fetchByPostMethod---->>>{}",ce.getMessage()); |
|
||||
} catch (IOException e) { |
|
||||
log.error("IOException fetchByPostMethod---->>>{}",e.getMessage()); |
|
||||
}finally { |
|
||||
httpPost.abort(); |
|
||||
} |
|
||||
log.info(seqNum+"<<< "+resultStr); |
|
||||
if(response != null) return new HttpResponseBean(resultStr, Arrays.asList(response.getAllHeaders()),response.getStatusLine().getStatusCode()); |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 正则获取字符编码 |
|
||||
* @param content_type |
|
||||
* @return |
|
||||
*/ |
|
||||
private static String getCharSetFromContentType(String content_type){ |
|
||||
String regex = "charset=\\s*(\\S*[^;])"; |
|
||||
Pattern pattern = Pattern.compile(regex,Pattern.DOTALL); |
|
||||
Matcher matcher = pattern.matcher(content_type); |
|
||||
if(matcher.find()){ |
|
||||
return matcher.group(1); |
|
||||
|
|
||||
}else{ |
|
||||
return null; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
} |
|
||||
@ -1,33 +0,0 @@ |
|||||
package com.xr.device_car.config.udp; |
|
||||
|
|
||||
import com.xr.device_car.modules.analysis.entity.MeterConfig; |
|
||||
import com.xr.device_car.modules.analysis.entity.MeterReadingRecord; |
|
||||
import lombok.Data; |
|
||||
|
|
||||
import java.text.SimpleDateFormat; |
|
||||
import java.util.Date; |
|
||||
import java.util.List; |
|
||||
import java.util.Random; |
|
||||
|
|
||||
@Data |
|
||||
public class UdbConfig { |
|
||||
|
|
||||
//获取资源信息配置报文
|
|
||||
public static String getUdbConfig(List<MeterConfig> list){ |
|
||||
StringBuffer buffer=new StringBuffer(); |
|
||||
SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
|
||||
buffer.append(new Date().getTime()+ new Random().nextInt(9000)+1000).append("\t"); |
|
||||
buffer.append("<!Entity=表计识别信息转发配置 ver='V1.0' time='"+sdf.format(new Date())+"'(文件最新时间)!>"); |
|
||||
buffer.append("<DeviceInfo::设备资源信息>"); |
|
||||
for(MeterConfig config:list){ |
|
||||
buffer.append("站序号").append("\t");//站序号
|
|
||||
buffer.append(config.getId()).append("\t");//监控索引号
|
|
||||
buffer.append("中山站").append("/").append(config.getOwningInterval()).append("/").append(config.getDeviceName()).append("/").append(config.getMeterName()).append("\t");//设备名称=站名称+间隔名称+设备名称+开关名称
|
|
||||
buffer.append(config.getMeterCode()).append("\t");//实物ID目前取表计ID
|
|
||||
buffer.append("否").append(";");//是否联动信号目前取否,目前结尾符号位;
|
|
||||
} |
|
||||
buffer.append("</DeviceInfo::设备资源信息>"); |
|
||||
return buffer.toString(); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,68 +0,0 @@ |
|||||
package com.xr.device_car.config.udp; |
|
||||
|
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
|
||||
import com.xr.device_car.config.utils.StaticPropUtil; |
|
||||
import com.xr.device_car.modules.analysis.entity.SendUdpLog; |
|
||||
import com.xr.device_car.modules.analysis.service.SendUdpLogService; |
|
||||
import io.netty.bootstrap.Bootstrap; |
|
||||
import io.netty.channel.ChannelHandlerContext; |
|
||||
import io.netty.channel.ChannelOption; |
|
||||
import io.netty.channel.EventLoopGroup; |
|
||||
import io.netty.channel.SimpleChannelInboundHandler; |
|
||||
import io.netty.channel.nio.NioEventLoopGroup; |
|
||||
import io.netty.channel.socket.DatagramChannel; |
|
||||
import io.netty.channel.socket.DatagramPacket; |
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel; |
|
||||
import io.netty.util.CharsetUtil; |
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
|
||||
import org.springframework.context.annotation.Bean; |
|
||||
import org.springframework.context.annotation.Configuration; |
|
||||
|
|
||||
import java.net.InetSocketAddress; |
|
||||
import java.text.SimpleDateFormat; |
|
||||
import java.util.Date; |
|
||||
|
|
||||
@Configuration |
|
||||
public class UdpClientConfig { |
|
||||
|
|
||||
@Autowired |
|
||||
private SendUdpLogService sendUdpLogService; |
|
||||
|
|
||||
@Bean |
|
||||
public DatagramChannel udpChannel() { |
|
||||
EventLoopGroup group = new NioEventLoopGroup(); |
|
||||
try { |
|
||||
Bootstrap bootstrap = new Bootstrap(); |
|
||||
bootstrap.group(group) |
|
||||
.channel(NioDatagramChannel.class) |
|
||||
.option(ChannelOption.SO_BROADCAST, true) |
|
||||
.handler(new SimpleChannelInboundHandler<DatagramPacket>() { |
|
||||
@Override |
|
||||
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { |
|
||||
// 处理接收到的数据
|
|
||||
String data = msg.content().toString(CharsetUtil.UTF_8); |
|
||||
QueryWrapper<SendUdpLog> queryWrapper=new QueryWrapper(); |
|
||||
queryWrapper.eq("message_id",data.split(":")[0]); |
|
||||
SendUdpLog sendUdpLog = sendUdpLogService.getOne(queryWrapper); |
|
||||
if(sendUdpLog !=null){ |
|
||||
sendUdpLog.setResTime(new Date()); |
|
||||
sendUdpLog.setResMsg(data); |
|
||||
sendUdpLogService.updateById(sendUdpLog); |
|
||||
} |
|
||||
System.out.println("Received data: " + data); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
return (DatagramChannel) bootstrap.bind(0).sync().channel(); |
|
||||
} catch (Exception e) { |
|
||||
e.printStackTrace(); |
|
||||
return null; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@Bean |
|
||||
public InetSocketAddress udpServerAddress() { |
|
||||
return new InetSocketAddress(StaticPropUtil.udpHost, StaticPropUtil.udpPort); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,139 +0,0 @@ |
|||||
package com.xr.device_car.config.utils; |
|
||||
|
|
||||
import com.alibaba.excel.EasyExcel; |
|
||||
import com.alibaba.excel.metadata.Head; |
|
||||
import com.alibaba.excel.write.handler.CellWriteHandler; |
|
||||
import com.alibaba.excel.write.handler.RowWriteHandler; |
|
||||
import com.alibaba.excel.write.handler.SheetWriteHandler; |
|
||||
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext; |
|
||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; |
|
||||
import com.alibaba.excel.write.metadata.holder.WriteTableHolder; |
|
||||
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; |
|
||||
import com.alibaba.excel.write.metadata.style.WriteCellStyle; |
|
||||
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; |
|
||||
import com.alibaba.fastjson.JSON; |
|
||||
import com.baomidou.mybatisplus.extension.api.R; |
|
||||
import com.xr.device_car.config.common.LocalDateConverter; |
|
||||
import com.xr.device_car.config.common.LocalDateTimeConverter; |
|
||||
import com.xr.device_car.modules.analysis.entity.xslx.SendUdpLogXslx; |
|
||||
import lombok.extern.slf4j.Slf4j; |
|
||||
import org.apache.poi.ss.usermodel.*; |
|
||||
|
|
||||
import javax.servlet.http.HttpServletRequest; |
|
||||
import javax.servlet.http.HttpServletResponse; |
|
||||
import java.io.IOException; |
|
||||
import java.lang.reflect.Field; |
|
||||
import java.lang.reflect.InvocationTargetException; |
|
||||
import java.text.ParseException; |
|
||||
import java.text.SimpleDateFormat; |
|
||||
import java.time.LocalDateTime; |
|
||||
import java.time.format.DateTimeFormatter; |
|
||||
import java.util.ArrayList; |
|
||||
import java.util.Date; |
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* @Author: ChenTaoTao |
|
||||
* @Date: 2022/3/19 16:51 |
|
||||
* @Describe: 文件导出 |
|
||||
*/ |
|
||||
@Slf4j |
|
||||
public class EasyExcelUtil { |
|
||||
public static <T> void writeExcel(HttpServletResponse response, List<T> data, Class tClass, String name){ |
|
||||
try { |
|
||||
List<Class> list=convertList(data,tClass); |
|
||||
String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); |
|
||||
name = name+dateStr; |
|
||||
//防止下载时中文乱码
|
|
||||
name = new String(name.getBytes("UTF-8"), "ISO-8859-1"); |
|
||||
response.setContentType("application/vnd.ms-excel"); |
|
||||
response.setCharacterEncoding("utf-8"); |
|
||||
//添加这个是防止前端拿不到Content-disposition
|
|
||||
response.setHeader("Content-Disposition", "attachment;filename=" + name+".xlsx"); |
|
||||
response.setHeader("Access-Control-Expose-Headers","Content-disposition"); |
|
||||
// 这里需要设置不关闭流
|
|
||||
EasyExcel.write(response.getOutputStream(), tClass).autoCloseStream(Boolean.FALSE).sheet(name).registerConverter(new LocalDateConverter()).registerConverter(new LocalDateTimeConverter()) |
|
||||
.registerWriteHandler(getCellStyleStrategy()).doWrite(list); |
|
||||
} catch (Exception e) { |
|
||||
log.error("文件导出失败,错误信息{}",e); |
|
||||
// 重置response
|
|
||||
response.reset(); |
|
||||
response.setContentType("application/json"); |
|
||||
response.setCharacterEncoding("utf-8"); |
|
||||
R r = R.failed("文件下载失败"); |
|
||||
try { |
|
||||
response.getWriter().println(JSON.toJSONString(r)); |
|
||||
} catch (IOException ioException) { |
|
||||
ioException.printStackTrace(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
private static HorizontalCellStyleStrategy getCellStyleStrategy() { |
|
||||
// 创建标题样式和内容样式
|
|
||||
WriteCellStyle headerStyle = new WriteCellStyle(); |
|
||||
headerStyle.setBorderLeft(BorderStyle.THIN); |
|
||||
headerStyle.setBorderTop(BorderStyle.THIN); |
|
||||
headerStyle.setBorderRight(BorderStyle.THIN); |
|
||||
headerStyle.setBorderBottom(BorderStyle.THIN); |
|
||||
|
|
||||
WriteCellStyle contentStyle = new WriteCellStyle(); |
|
||||
contentStyle.setBorderLeft(BorderStyle.THIN); |
|
||||
contentStyle.setBorderTop(BorderStyle.THIN); |
|
||||
contentStyle.setBorderRight(BorderStyle.THIN); |
|
||||
contentStyle.setBorderBottom(BorderStyle.THIN); |
|
||||
|
|
||||
return new HorizontalCellStyleStrategy(headerStyle,contentStyle); |
|
||||
} |
|
||||
|
|
||||
public static <T, S> List<S> convertList(List<T> list, Class<S> targetClass) throws NoSuchFieldException, IllegalAccessException, ParseException, NoSuchMethodException, InvocationTargetException, InstantiationException { |
|
||||
List<S> resultList = new ArrayList<>(); |
|
||||
|
|
||||
for (T sourceObj : list) { |
|
||||
S targetObj = targetClass.getDeclaredConstructor().newInstance(); |
|
||||
Field[] sourceFields = sourceObj.getClass().getDeclaredFields(); |
|
||||
Field[] targetFields = targetClass.getDeclaredFields(); |
|
||||
|
|
||||
for (Field sourceField : sourceFields) { |
|
||||
Field targetField = getField(targetFields, sourceField.getName()); |
|
||||
if (targetField != null) { |
|
||||
sourceField.setAccessible(true); |
|
||||
targetField.setAccessible(true); |
|
||||
|
|
||||
Object sourceValue = sourceField.get(sourceObj); |
|
||||
Object targetValue = convertFieldValue(sourceValue, targetField.getType(),sourceField.getType()); |
|
||||
|
|
||||
targetField.set(targetObj, targetValue); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
resultList.add(targetObj); |
|
||||
} |
|
||||
|
|
||||
return resultList; |
|
||||
} |
|
||||
|
|
||||
private static Field getField(Field[] fields, String fieldName) { |
|
||||
for (Field field : fields) { |
|
||||
if (field.getName().equals(fieldName)) { |
|
||||
return field; |
|
||||
} |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
private static Object convertFieldValue(Object value, Class<?> targetType,Class<?> type1) throws ParseException { |
|
||||
if (type1 == String.class) { |
|
||||
return value.toString(); |
|
||||
} else if (targetType == String.class && value instanceof Date) { |
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
|
||||
return dateFormat.format(value); |
|
||||
} |
|
||||
return value; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
} |
|
||||
@ -1,52 +0,0 @@ |
|||||
package com.xr.device_car.config.utils; |
|
||||
|
|
||||
import com.xr.device_car.modules.analysis.entity.BallheadPT; |
|
||||
import com.xr.device_car.modules.analysis.entity.DeviceCamera; |
|
||||
import com.xr.device_car.modules.analysis.entity.OnvifAuthBean; |
|
||||
import com.xr.device_car.modules.analysis.entity.OnvifBean; |
|
||||
import org.springframework.util.CollectionUtils; |
|
||||
|
|
||||
import java.awt.image.BufferedImage; |
|
||||
import java.util.List; |
|
||||
|
|
||||
public class HkComUtil { |
|
||||
|
|
||||
public static BufferedImage getBole(DeviceCamera device) throws Exception{ //拉取枪机图片
|
|
||||
OnvifAuthBean onvifBean= new OnvifAuthBean(device.getDeviceIp(),80,device.getAccount(),device.getPassword()); |
|
||||
String url= OnvifBean.getRequestUrl(onvifBean); |
|
||||
String auth = OnvifUtils.getAuthorization("digest",onvifBean,"digest/GetProfiles.wsdl", url); |
|
||||
System.out.println("鉴权:"+auth); |
|
||||
//获取Token
|
|
||||
List<String> profileTokens = OnvifUtils.getProfileTokens(onvifBean,auth); |
|
||||
System.out.println("Token:"+profileTokens); |
|
||||
onvifBean.setAuth(auth); |
|
||||
if(!CollectionUtils.isEmpty(profileTokens)){ |
|
||||
String snapshotUrl=null; |
|
||||
String token = profileTokens.get(0); |
|
||||
BallheadPT ballheadPT=OnvifUtils.getPtzStatus(token,onvifBean); |
|
||||
//如果类型是球机转换指定点位
|
|
||||
if(device.getDeviceType().equals("3") && OnvifUtils.ptzCamera(token,onvifBean,device.getX(),device.getY(),device.getZ())){ |
|
||||
Thread.sleep(1000); |
|
||||
//拉取图片
|
|
||||
snapshotUrl = OnvifUtils.getSnapshotUrl(token,onvifBean); |
|
||||
if(snapshotUrl!=null){ |
|
||||
//转回原来位置
|
|
||||
OnvifUtils.ptzCamera(token,onvifBean,ballheadPT.getX(),ballheadPT.getY(),ballheadPT.getZ()); |
|
||||
} |
|
||||
//如果类型是固定枪机,直接获取图片
|
|
||||
}else{ |
|
||||
snapshotUrl = OnvifUtils.getSnapshotUrl(token,onvifBean); |
|
||||
} |
|
||||
//返回图片地址
|
|
||||
return Files.urlByImages(snapshotUrl,device.getAccount(),device.getPassword()); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
@ -1,55 +0,0 @@ |
|||||
package com.xr.device_car.config.utils; |
|
||||
|
|
||||
import lombok.AllArgsConstructor; |
|
||||
import lombok.Getter; |
|
||||
import lombok.NoArgsConstructor; |
|
||||
import lombok.Setter; |
|
||||
import org.apache.http.Header; |
|
||||
import org.apache.http.HttpStatus; |
|
||||
|
|
||||
import java.util.List; |
|
||||
|
|
||||
@Setter |
|
||||
@Getter |
|
||||
@AllArgsConstructor |
|
||||
@NoArgsConstructor |
|
||||
public class HttpResponseBean { |
|
||||
private String body; |
|
||||
private List<Header> headers; |
|
||||
private Integer status; |
|
||||
|
|
||||
/** |
|
||||
* 获取头部信息。 |
|
||||
* @param name |
|
||||
* @return |
|
||||
*/ |
|
||||
public Header getFirstHeader(final String name) { |
|
||||
for (int i = 0; i < this.headers.size(); i++) { |
|
||||
final Header header = this.headers.get(i); |
|
||||
if (header.getName().equalsIgnoreCase(name)) { |
|
||||
return header; |
|
||||
} |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
/*** |
|
||||
* 判断是否成功 |
|
||||
*/ |
|
||||
public static boolean isSuccess(HttpResponseBean httpResponseBean){ |
|
||||
return httpResponseBean!= null && HttpStatus.SC_OK ==httpResponseBean.getStatus(); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/*** |
|
||||
* 判断是否是401 |
|
||||
*/ |
|
||||
public static boolean isUnAuthorzied(HttpResponseBean httpResponseBean){ |
|
||||
return httpResponseBean!= null && HttpStatus.SC_UNAUTHORIZED ==httpResponseBean.getStatus(); |
|
||||
} |
|
||||
|
|
||||
public HttpResponseBean(String body) { |
|
||||
this.body = body; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@ -1,72 +0,0 @@ |
|||||
package com.xr.device_car.config.utils; |
|
||||
|
|
||||
import io.minio.MinioClient; |
|
||||
import io.minio.errors.*; |
|
||||
import org.slf4j.Logger; |
|
||||
import org.slf4j.LoggerFactory; |
|
||||
import org.springframework.web.multipart.MultipartFile; |
|
||||
import org.xmlpull.v1.XmlPullParserException; |
|
||||
|
|
||||
import java.io.*; |
|
||||
import java.security.InvalidKeyException; |
|
||||
import java.security.NoSuchAlgorithmException; |
|
||||
import java.util.UUID; |
|
||||
|
|
||||
public class MinioUtil { |
|
||||
|
|
||||
private final static Logger log= LoggerFactory.getLogger(MinioUtil.class); |
|
||||
|
|
||||
private static MinioClient minioClient; |
|
||||
|
|
||||
private static MinioClient minioInit(){ |
|
||||
try { |
|
||||
if(minioClient == null){ |
|
||||
minioClient = new MinioClient(StaticPropUtil.minioUrl, StaticPropUtil.minioAccess, StaticPropUtil.minioSecret); |
|
||||
} |
|
||||
} catch (InvalidEndpointException e) { |
|
||||
throw new RuntimeException(e); |
|
||||
} catch (InvalidPortException e) { |
|
||||
throw new RuntimeException(e); |
|
||||
} |
|
||||
return minioClient; |
|
||||
} |
|
||||
|
|
||||
public static String uploadMultipartFile(MultipartFile file) throws Exception { |
|
||||
MinioClient minioClient = minioInit(); |
|
||||
InputStream is = file.getInputStream(); |
|
||||
//使用uuid生成新的唯一文件名
|
|
||||
String fileName = UUID.randomUUID().toString().replace("-", "") + file.getOriginalFilename(); |
|
||||
//获取文件类型
|
|
||||
String contentType = file.getContentType();//把文件放置Minio桶
|
|
||||
minioClient.putObject("meter", fileName, is, contentType); |
|
||||
//获取访问路径
|
|
||||
String url = minioClient.presignedGetObject("meter", fileName); |
|
||||
if (url != null) { |
|
||||
//返回路径不为空,即上传文件成功
|
|
||||
return url.split("\\?")[0]; |
|
||||
} else { |
|
||||
//上传失败
|
|
||||
return"上传失败"; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public static String uploadFile(File file) throws IOException, InvalidArgumentException, InvalidBucketNameException, InsufficientDataException, XmlPullParserException, ErrorResponseException, NoSuchAlgorithmException, NoResponseException, InvalidKeyException, InternalException, InvalidExpiresRangeException { |
|
||||
MinioClient minioClient = minioInit(); |
|
||||
InputStream is = new FileInputStream(file); |
|
||||
//使用uuid生成新的唯一文件名
|
|
||||
String fileName = UUID.randomUUID().toString().replace("-", "") + file.getName(); |
|
||||
//获取文件类型
|
|
||||
String contentType = fileName.substring(fileName.lastIndexOf(".")+1);//把文件放置Minio桶
|
|
||||
minioClient.putObject("meter", fileName, is, contentType); |
|
||||
//获取访问路径
|
|
||||
String url = minioClient.presignedGetObject("meter", fileName); |
|
||||
if (url != null) { |
|
||||
//返回路径不为空,即上传文件成功
|
|
||||
return url.split("\\?")[0]; |
|
||||
} else { |
|
||||
//上传失败
|
|
||||
return"上传失败"; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
@ -1,141 +0,0 @@ |
|||||
package com.xr.device_car.config.utils; |
|
||||
|
|
||||
import com.xr.device_car.config.common.RESTClient; |
|
||||
import com.xr.device_car.modules.analysis.entity.BallheadPT; |
|
||||
import com.xr.device_car.modules.analysis.entity.DigestBean; |
|
||||
import com.xr.device_car.modules.analysis.entity.OnvifAuthBean; |
|
||||
import com.xr.device_car.modules.analysis.entity.OnvifBean; |
|
||||
import org.springframework.core.io.ClassPathResource; |
|
||||
import org.springframework.util.StringUtils; |
|
||||
|
|
||||
import java.util.List; |
|
||||
|
|
||||
import static com.xr.device_car.config.common.Const.HEADERS_ONVIF_WWW_AUTHENTICATE; |
|
||||
|
|
||||
|
|
||||
public class OnvifUtils { |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 获取鉴权 |
|
||||
* @param authType |
|
||||
* @param requestOnvifBean |
|
||||
* @param wsdl |
|
||||
* @param requestUrl |
|
||||
* @return |
|
||||
*/ |
|
||||
public static String getAuthorization(String authType, OnvifBean requestOnvifBean, String wsdl, String requestUrl) { |
|
||||
//参数
|
|
||||
// 读取GetProfiles.wsdl
|
|
||||
String getProfiles = FileUtil.fileReader(new ClassPathResource(wsdl)); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, getProfiles); |
|
||||
//如果是401的话 获取WWW-Authenticate 重新请求
|
|
||||
if (HttpResponseBean.isUnAuthorzied(httpResponseBean)) { |
|
||||
DigestBean digestBean = new DigestBean().getDigestBean(authType,requestOnvifBean, httpResponseBean.getFirstHeader(HEADERS_ONVIF_WWW_AUTHENTICATE).getValue()); |
|
||||
return digestBean.getToken(); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 获取Token |
|
||||
* @param requestOnvifBean |
|
||||
* @param auth |
|
||||
* @return |
|
||||
*/ |
|
||||
public static List<String> getProfileTokens(OnvifBean requestOnvifBean, String auth) { |
|
||||
//请求url
|
|
||||
String requestUrl = OnvifBean.getRequestUrl(requestOnvifBean); |
|
||||
//参数
|
|
||||
// 读取GetProfiles.wsdl
|
|
||||
String getProfiles = FileUtil.fileReader(new ClassPathResource("digest/GetProfiles.wsdl")); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, getProfiles,auth); |
|
||||
if(httpResponseBean != null) { |
|
||||
String resultStr = httpResponseBean.getBody(); |
|
||||
if (HttpResponseBean.isSuccess(httpResponseBean) && StringUtils.hasLength(resultStr)) { |
|
||||
return AnalysisXml.analysisTokens(resultStr); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 获取截图地址 |
|
||||
* @param profileToken token |
|
||||
* @param requestOnvifBean |
|
||||
* @return |
|
||||
*/ |
|
||||
public static String getSnapshotUrl(String profileToken, OnvifAuthBean requestOnvifBean) { |
|
||||
String requestUrl = OnvifBean.getRequestUrl(requestOnvifBean); |
|
||||
//参数
|
|
||||
// 读取GetProfiles.wsdl
|
|
||||
String snapshotUrlWsdl = FileUtil.fileReader(new ClassPathResource("digest/GetSnapshotUrl.wsdl")); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, String.format(snapshotUrlWsdl,profileToken),requestOnvifBean.getAuth()); |
|
||||
String resultStr = httpResponseBean.getBody(); |
|
||||
if(StringUtils.hasLength(resultStr) && HttpResponseBean.isSuccess(httpResponseBean)) { |
|
||||
return AnalysisXml.analysisSnapshotUrl(resultStr); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
//绝对位置转动球机
|
|
||||
public static boolean ptzCamera(String profileToken,OnvifAuthBean requestOnvifBean,String x,String y,String z){ |
|
||||
String requestUrl = OnvifBean.getRequestUrl(requestOnvifBean); |
|
||||
String snapshotUrlWsdl = FileUtil.fileReader(new ClassPathResource("digest/AbsoluteMove.wsdl")); |
|
||||
String wsdl = String.format(snapshotUrlWsdl,profileToken,x,y,z); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, wsdl,requestOnvifBean.getAuth()); |
|
||||
String resultStr = httpResponseBean.getBody(); |
|
||||
if(StringUtils.hasLength(resultStr) && HttpResponseBean.isSuccess(httpResponseBean)) { |
|
||||
return true; |
|
||||
} |
|
||||
return false; |
|
||||
} |
|
||||
//获取球机当前位置
|
|
||||
public static BallheadPT getPtzStatus(String token,OnvifAuthBean requestOnvifBean){ |
|
||||
String requestUrl = OnvifBean.getRequestUrl(requestOnvifBean); |
|
||||
String snap = FileUtil.fileReader(new ClassPathResource("digest/GetStatus.wsdl")); |
|
||||
String wsdl = String.format(snap,token); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, wsdl,requestOnvifBean.getAuth()); |
|
||||
String resultStr = httpResponseBean.getBody(); |
|
||||
if(StringUtils.hasLength(resultStr) && HttpResponseBean.isSuccess(httpResponseBean)) { |
|
||||
return AnalysisXml.getStatus(resultStr); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
//获取所有预置点
|
|
||||
public static List<BallheadPT> getBallHeadPts(String profileToken,OnvifAuthBean requestOnvifBean){ |
|
||||
String requestUrl = OnvifBean.getRequestUrl(requestOnvifBean); |
|
||||
String snapshotUrlWsdl = FileUtil.fileReader(new ClassPathResource("digest/GetPresets.wsdl")); |
|
||||
String wsdl = String.format(snapshotUrlWsdl,profileToken); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, wsdl,requestOnvifBean.getAuth()); |
|
||||
String resultStr = httpResponseBean.getBody(); |
|
||||
if(StringUtils.hasLength(resultStr) && HttpResponseBean.isSuccess(httpResponseBean)) { |
|
||||
return AnalysisXml.getBallheadPTs(resultStr); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
//前往指定预置点
|
|
||||
public static boolean gotoBallHeadPts(String profileToken, OnvifAuthBean requestOnvifBean, BallheadPT ballheadPT){ |
|
||||
String requestUrl = OnvifBean.getRequestUrl(requestOnvifBean); |
|
||||
String snapshotUrlWsdl = FileUtil.fileReader(new ClassPathResource("digest/GotoPreset.wsdl")); |
|
||||
String wsdl = String.format(snapshotUrlWsdl,profileToken,ballheadPT.getId()); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, wsdl,requestOnvifBean.getAuth()); |
|
||||
String resultStr = httpResponseBean.getBody(); |
|
||||
if(StringUtils.hasLength(resultStr) && HttpResponseBean.isSuccess(httpResponseBean)) { |
|
||||
return true; |
|
||||
} |
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
@ -1,231 +0,0 @@ |
|||||
package com.xr.device_car.config.utils; |
|
||||
|
|
||||
import cn.hutool.extra.spring.SpringUtil; |
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
|
||||
import com.xr.device_car.modules.analysis.entity.MeterInitialization; |
|
||||
import com.xr.device_car.modules.analysis.service.IMeterInitializationService; |
|
||||
import com.xr.device_car.modules.analysis.service.MeterConfigService; |
|
||||
import com.xr.device_car.modules.analysis.service.impl.MeterInitializationServiceImpl; |
|
||||
|
|
||||
import java.io.*; |
|
||||
import java.util.ArrayList; |
|
||||
import java.util.Arrays; |
|
||||
import java.util.List; |
|
||||
import java.util.stream.Collectors; |
|
||||
|
|
||||
public class PythonExecutor { |
|
||||
|
|
||||
|
|
||||
public static void main(String[] args) throws Exception { |
|
||||
try { |
|
||||
String pythonPath = StaticPropUtil.pythonPath; |
|
||||
|
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(pythonPath); |
|
||||
// 启动子进程
|
|
||||
Process process = processBuilder.start(); |
|
||||
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); |
|
||||
bw.write("import sys\n"); |
|
||||
bw.write("sys.path.append(\"D:\\smartGrid\\smartGrid\\models\")\n"); |
|
||||
bw.write("import indicatorLightStatus as ils\n"); |
|
||||
bw.write("import switchRecognition as sr\n"); |
|
||||
bw.write("import liquidLevel as ll\n"); |
|
||||
bw.write("liquid_level_image_path = 'D:\\smartGrid\\smartGrid\\weights\\DIGITAL_METER (41).JPG'\n"); |
|
||||
bw.write("ll.calculate_rgb_min_max([[112,\"D:\\smartGrid\\smartGrid\\weights\\DIGITAL_METER (41).JPG\"]])\n"); |
|
||||
bw.write("print(\"Liquid level weights initialized.\")\n"); |
|
||||
bw.write("liquid_level_image_path = 'D:\\smartGrid\\smartGrid\\weights\\DIGITAL_METER (10).JPG'\n"); |
|
||||
bw.write("liquid_level = ll.calculate_liquid_level([112,liquid_level_image_path])\n"); |
|
||||
bw.write("print(f\"Liquid level: {liquid_level}\")\n"); |
|
||||
|
|
||||
bw.close(); |
|
||||
|
|
||||
|
|
||||
// 获取子进程的输出流
|
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); |
|
||||
|
|
||||
String line; |
|
||||
// 读取输出
|
|
||||
while ((line = reader.readLine()) != null) { |
|
||||
System.out.println(line); |
|
||||
} |
|
||||
|
|
||||
// 等待进程执行完成
|
|
||||
int exitCode = process.waitFor(); |
|
||||
System.out.println("Exit Code: " + exitCode); |
|
||||
|
|
||||
} catch (IOException | InterruptedException e) { |
|
||||
e.printStackTrace(); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
private static boolean meterInit(String code) throws Exception { |
|
||||
String pythonPath = StaticPropUtil.pythonPath; |
|
||||
String modelPath = StaticPropUtil.modelPath; |
|
||||
|
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(pythonPath); |
|
||||
// 启动子进程
|
|
||||
Process process = processBuilder.start(); |
|
||||
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); |
|
||||
bw.write("import sys\n"); |
|
||||
String imports = "sys.path.append(\"%s\")\n"; |
|
||||
bw.write(String.format(imports, modelPath)); |
|
||||
bw.write("import indicatorLightStatus as ils\n"); |
|
||||
bw.write("import switchRecognition as sr\n"); |
|
||||
bw.write("import liquidLevel as ll\n"); |
|
||||
bw.write(code); |
|
||||
bw.write("print(\"success\")\n"); |
|
||||
bw.close(); |
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); |
|
||||
|
|
||||
List<String> list = new ArrayList<>(); |
|
||||
String line; |
|
||||
// 读取输出
|
|
||||
while ((line = reader.readLine()) != null) { |
|
||||
list.add(line); |
|
||||
System.out.println(line); |
|
||||
} |
|
||||
|
|
||||
BufferedReader exception = new BufferedReader(new InputStreamReader(process.getErrorStream())); |
|
||||
List<String> list1 = new ArrayList<>(); |
|
||||
String line1; |
|
||||
// 读取输出
|
|
||||
while ((line1 = exception.readLine()) != null) { |
|
||||
list1.add(line1); |
|
||||
System.out.println(line1); |
|
||||
} |
|
||||
|
|
||||
// 等待进程执行完成
|
|
||||
int exitCode = process.waitFor(); |
|
||||
System.out.println("Exit Code: " + exitCode); |
|
||||
if (list.contains("success") && list1.isEmpty()) { |
|
||||
return true; |
|
||||
} |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 初始化算法 |
|
||||
* id 表计配置ID |
|
||||
* sfType 4 灯光 3 开关 5 液位计 |
|
||||
*/ |
|
||||
public static boolean meterInit(Integer id, String sfType) throws Exception { |
|
||||
IMeterInitializationService meterInitializationService = SpringUtil.getBean(MeterInitializationServiceImpl.class); |
|
||||
QueryWrapper<MeterInitialization> query = new QueryWrapper<>(); |
|
||||
query.eq("meter_id", id); |
|
||||
query.orderByAsc("serial"); |
|
||||
List<MeterInitialization> list = meterInitializationService.list(query); |
|
||||
List<String> path = list.stream().map(n -> n.getImgAddress()).collect(Collectors.toList()); |
|
||||
String ph = ""; |
|
||||
for (String str : path) { |
|
||||
str = str.replace("\\", "\\\\"); |
|
||||
ph += "\"" + str + "\"" + ","; |
|
||||
} |
|
||||
ph = ph.substring(0, ph.length() - 1); |
|
||||
String code = ""; |
|
||||
if (sfType.equals("4")) { |
|
||||
List<List<Object>> list1 = new ArrayList<>(); |
|
||||
List<Object> list2 = new ArrayList<>(); |
|
||||
list2.add(id); |
|
||||
List<String> list3 = new ArrayList<>(); |
|
||||
list3.add(ph); |
|
||||
list2.add(list3); |
|
||||
list1.add(list2); |
|
||||
code = "ils.calculate_luminance_threshold(" + Arrays.toString(list1.toArray()) + ")\n"; |
|
||||
} |
|
||||
if (sfType.equals("3")) { |
|
||||
List<String> list1 = new ArrayList<>(); |
|
||||
path.add(0, id + ""); |
|
||||
list1.add(ph); |
|
||||
code = "sr.initialize(" + Arrays.toString(list1.toArray()) + ")\n"; |
|
||||
} |
|
||||
if (sfType.equals("5")) { |
|
||||
List<String> list1 = new ArrayList<>(); |
|
||||
// list1.add(id.toString());
|
|
||||
//path.add(0, id + "");
|
|
||||
list1.add(ph); |
|
||||
// String params = String.join( list1);
|
|
||||
//Arrays.toString(list1.toArray())
|
|
||||
code = "ll.calculate_rgb_min_max("+"[["+id+ ","+ ph +"]]"+")\n"; |
|
||||
} |
|
||||
return meterInit(code); |
|
||||
|
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 读取结果 |
|
||||
* id 表计id |
|
||||
* path 图片路径 |
|
||||
* sfType 1 灯光 2 开关 3 液位计 4 指针 |
|
||||
*/ |
|
||||
public static String readNumber(Integer id, String path, String sfType) throws Exception { |
|
||||
String pythonPath = StaticPropUtil.pythonPath; |
|
||||
String modelPath = StaticPropUtil.modelPath; |
|
||||
|
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(pythonPath); |
|
||||
// 启动子进程
|
|
||||
Process process = processBuilder.start(); |
|
||||
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); |
|
||||
bw.write("import sys\n"); |
|
||||
String imports = "sys.path.append(\"%s\")\n"; |
|
||||
bw.write(String.format(imports, modelPath)); |
|
||||
bw.write("import indicatorLightStatus as ils\n"); |
|
||||
bw.write("import switchRecognition as sr\n"); |
|
||||
bw.write("import liquidLevel as ll\n"); |
|
||||
bw.write("indicator_light_image_path = '" + path + "'\n"); |
|
||||
if (sfType.equals("4")) { |
|
||||
bw.write("value = ils.check_indicator_light_status(" + id + ",indicator_light_image_path)\n"); |
|
||||
} |
|
||||
if (sfType.equals("3")) { |
|
||||
bw.write("value = sr.read_numbers(" + id + ",indicator_light_image_path)\n"); |
|
||||
} |
|
||||
if (sfType.equals("5")) { |
|
||||
bw.write("value = ll.calculate_liquid_level([" + id + ",indicator_light_image_path,\"down\"])\n"); |
|
||||
} |
|
||||
if (sfType.equals("0")) { |
|
||||
bw.write("rotate_angle, value = pr.getPointerAngleAndNum(" + id + ", indicator_light_image_path)\n"); |
|
||||
} |
|
||||
bw.write("print(f\"value:{value}\")"); |
|
||||
bw.close(); |
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); |
|
||||
List<String> list = new ArrayList<>(); |
|
||||
String line; |
|
||||
// 读取输出
|
|
||||
while ((line = reader.readLine()) != null) { |
|
||||
list.add(line); |
|
||||
} |
|
||||
|
|
||||
BufferedReader exception = new BufferedReader(new InputStreamReader(process.getErrorStream())); |
|
||||
List<String> list1 = new ArrayList<>(); |
|
||||
String line1; |
|
||||
// 读取输出
|
|
||||
while ((line1 = exception.readLine()) != null) { |
|
||||
list.add(line1); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
// if(list.contains("value")){
|
|
||||
// String value = list.get(list.indexOf("value")).split(":")[1];
|
|
||||
// File file = new File(path);
|
|
||||
// if(file.exists()){
|
|
||||
// file.delete();
|
|
||||
// }
|
|
||||
// return value;
|
|
||||
// }
|
|
||||
for (String element : list) { |
|
||||
if (element.contains("value")) { |
|
||||
String[] parts = element.split(":"); |
|
||||
File file = new File(path); |
|
||||
if (file.exists()) { |
|
||||
file.delete(); |
|
||||
} |
|
||||
if (parts.length > 1) { |
|
||||
String result = parts[1].trim(); |
|
||||
return result; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
} |
|
||||
@ -1,177 +0,0 @@ |
|||||
package com.xr.device_car.modules.analysis.controller; |
|
||||
|
|
||||
|
|
||||
import cn.hutool.core.util.ObjectUtil; |
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
|
||||
import com.xr.device_car.config.common.Result; |
|
||||
import com.xr.device_car.config.utils.*; |
|
||||
import com.xr.device_car.modules.analysis.entity.DeviceCamera; |
|
||||
import com.xr.device_car.modules.analysis.entity.MeterConfig; |
|
||||
import com.xr.device_car.modules.analysis.entity.MeterInitialization; |
|
||||
import com.xr.device_car.modules.analysis.entity.MeterType; |
|
||||
import com.xr.device_car.modules.analysis.service.DeviceCameraService; |
|
||||
import com.xr.device_car.modules.analysis.service.IMeterInitializationService; |
|
||||
import com.xr.device_car.modules.analysis.service.MeterConfigService; |
|
||||
import com.xr.device_car.modules.analysis.service.MeterTypeService; |
|
||||
import io.minio.MinioClient; |
|
||||
import lombok.RequiredArgsConstructor; |
|
||||
import org.springframework.web.bind.annotation.RequestMapping; |
|
||||
import org.springframework.beans.factory.annotation.Value; |
|
||||
import org.springframework.web.bind.annotation.*; |
|
||||
|
|
||||
import org.springframework.web.multipart.MultipartFile; |
|
||||
|
|
||||
import javax.servlet.http.HttpServletRequest; |
|
||||
import java.io.File; |
|
||||
import java.io.InputStream; |
|
||||
import java.util.*; |
|
||||
|
|
||||
import java.awt.image.BufferedImage; |
|
||||
|
|
||||
/** |
|
||||
* <p> |
|
||||
* 表计算法初始化 前端控制器 |
|
||||
* </p> |
|
||||
* |
|
||||
* @author gaoby |
|
||||
* @since 2023-11-20 |
|
||||
*/ |
|
||||
@RestController |
|
||||
@RequestMapping("/meterInitialization") |
|
||||
@RequiredArgsConstructor |
|
||||
public class MeterInitializationController { |
|
||||
@Value("${upLoad.file}") |
|
||||
private String uploadDir; |
|
||||
|
|
||||
private final MeterConfigService meterConfigService; |
|
||||
|
|
||||
private final DeviceCameraService deviceCameraService; |
|
||||
|
|
||||
private final IMeterInitializationService iMeterInitializationService; |
|
||||
|
|
||||
private final MeterTypeService meterTypeService; |
|
||||
|
|
||||
@PostMapping("pullImages") |
|
||||
public Result<?> pullImages(MeterInitialization meterInitialization){ |
|
||||
MeterConfig config=meterConfigService.getById(meterInitialization.getMeterId()); |
|
||||
DeviceCamera deviceCamera = deviceCameraService.getById(config.getCameraId()); |
|
||||
BufferedImage bufferedImage=null; |
|
||||
try { |
|
||||
if(deviceCamera.getDeviceType().equals("1")|| deviceCamera.getDeviceType().equals("2")){ |
|
||||
bufferedImage= AdbUtil.getCamDevice(); |
|
||||
} |
|
||||
if(deviceCamera.getDeviceType().equals("3") || deviceCamera.getDeviceType().equals("4")){ // 拉取球机
|
|
||||
bufferedImage= HkComUtil.getBole(deviceCamera); |
|
||||
} |
|
||||
long l = new Date().getTime(); |
|
||||
String path = StaticPropUtil.imagePath +l+".png"; |
|
||||
File file=Files.saveImageForPath(bufferedImage,path); |
|
||||
String url = MinioUtil.uploadFile(file); |
|
||||
|
|
||||
QueryWrapper<MeterInitialization> queryWrapper=new QueryWrapper<>(); |
|
||||
queryWrapper.eq("meter_id",meterInitialization.getMeterId()); |
|
||||
queryWrapper.orderByDesc("serial"); |
|
||||
List<MeterInitialization> meterInitialization1=iMeterInitializationService.list(queryWrapper); |
|
||||
MeterInitialization meterInitialization2 = getMeterInitialization(meterInitialization, meterInitialization1, path,url); |
|
||||
iMeterInitializationService.save(meterInitialization2); |
|
||||
}catch (Exception e){ |
|
||||
e.printStackTrace(); |
|
||||
return Result.error(e.getMessage()); |
|
||||
} |
|
||||
return Result.OK("拉取成功!"); |
|
||||
} |
|
||||
|
|
||||
private static MeterInitialization getMeterInitialization(MeterInitialization meterInitialization, List<MeterInitialization> meterInitialization1, String path,String url) { |
|
||||
MeterInitialization meterInitialization2=new MeterInitialization(); |
|
||||
meterInitialization2.setMeterId(meterInitialization.getMeterId()); |
|
||||
if(meterInitialization1.isEmpty()){ |
|
||||
meterInitialization2.setSerial(0); |
|
||||
}else{ |
|
||||
meterInitialization2.setSerial(meterInitialization1.get(0).getSerial()+1); |
|
||||
} |
|
||||
meterInitialization2.setValue(meterInitialization.getValue()); |
|
||||
meterInitialization2.setImgAddress(path); |
|
||||
meterInitialization2.setImg(url); |
|
||||
return meterInitialization2; |
|
||||
} |
|
||||
|
|
||||
@PostMapping("/uploadImg") |
|
||||
public Result<?> uploadImg(@RequestParam("imgFile") MultipartFile imgFile,@RequestParam("value") String value,@RequestParam("serial") String serial,@RequestParam("meterId") String meterId) throws Exception { |
|
||||
if (!imgFile.isEmpty()) { |
|
||||
// 获取文件名
|
|
||||
String fileName = Objects.requireNonNull(imgFile.getOriginalFilename()); |
|
||||
File folder = new File(StaticPropUtil.imagePath); |
|
||||
// 检查文件夹是否存在,如果不存在就创建它
|
|
||||
if (!folder.exists()) { |
|
||||
folder.mkdirs(); // 创建文件夹及其父文件夹(如果不存在)
|
|
||||
} |
|
||||
// 构建上传路径
|
|
||||
String filePath = StaticPropUtil.imagePath + File.separator + fileName; |
|
||||
String imgAddress = StaticPropUtil.imagePath + fileName; |
|
||||
// 保存文件
|
|
||||
File dest = new File(filePath); |
|
||||
imgFile.transferTo(dest); |
|
||||
// 上传至minIo服务器
|
|
||||
String url = MinioUtil.uploadMultipartFile(imgFile); |
|
||||
if (url.equals("上传失败")){ |
|
||||
Result.error("图片上传至服务器异常"); |
|
||||
} |
|
||||
MeterInitialization meterInitialization = new MeterInitialization(); |
|
||||
meterInitialization.setImg(url); |
|
||||
meterInitialization.setImgAddress(imgAddress); |
|
||||
meterInitialization.setMeterId(Integer.valueOf(meterId)); |
|
||||
meterInitialization.setSerial(Integer.valueOf(serial)); |
|
||||
meterInitialization.setValue(value); |
|
||||
QueryWrapper<MeterInitialization> wrapper = new QueryWrapper<>(); |
|
||||
wrapper.eq("meter_id",meterInitialization.getMeterId()); |
|
||||
iMeterInitializationService.save(meterInitialization); |
|
||||
return Result.OK("上传成功!"); |
|
||||
} |
|
||||
return Result.error("上传图片异常,请联系管理员"); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
@PostMapping(value = "/queryPageList") |
|
||||
public Result<?> queryPageList(MeterInitialization meterInitialization, HttpServletRequest req)throws Exception{ |
|
||||
// Page<MeterInitialization> pg = StringFormatterUtil.returnPage(req);
|
|
||||
QueryWrapper<MeterInitialization> wrapper = StringFormatterUtil.returnQuery(req); |
|
||||
// meterId
|
|
||||
if (ObjectUtil.isNotEmpty(meterInitialization.getMeterId())){ |
|
||||
wrapper.eq("meter_id",meterInitialization.getMeterId()); |
|
||||
} |
|
||||
wrapper.orderByAsc("serial"); |
|
||||
List<MeterInitialization> meterInitializationList = iMeterInitializationService.list(wrapper); |
|
||||
return Result.OK(meterInitializationList); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
@PostMapping(value = "/delImg") |
|
||||
public Result<?> delImg(Integer id) throws Exception { |
|
||||
iMeterInitializationService.removeById(id); |
|
||||
return Result.OK("删除成功!"); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 初始化算法 |
|
||||
*/ |
|
||||
@PostMapping("initMeter") |
|
||||
public Result<?> initMeter(Integer meterId){ |
|
||||
try{ |
|
||||
MeterConfig meterConfig=meterConfigService.getById(meterId); |
|
||||
MeterType meterType = meterTypeService.getById(meterConfig.getTypeId()); |
|
||||
if(PythonExecutor.meterInit(meterId,meterType.getMeterShape())){ |
|
||||
meterConfig.setInitStatus("1"); |
|
||||
meterConfigService.updateById(meterConfig); |
|
||||
}else{ |
|
||||
return Result.error("初始化失败"); |
|
||||
} |
|
||||
}catch (Exception e){ |
|
||||
e.printStackTrace(); |
|
||||
return Result.error(e.getMessage()); |
|
||||
} |
|
||||
return Result.OK("初始化完成"); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
@ -1,12 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<s:Body> |
|
||||
<tptz:AbsoluteMove> |
|
||||
<tptz:ProfileToken>%s</tptz:ProfileToken> |
|
||||
<tptz:Position> |
|
||||
<tt:PanTilt y="%s" x="%s" space="http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace" /> |
|
||||
<tt:Zoom x="%s" space="http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace" /> |
|
||||
</tptz:Position> |
|
||||
</tptz:AbsoluteMove> |
|
||||
</s:Body> |
|
||||
</s:Envelope> |
|
||||
@ -1,6 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<soap:Body> |
|
||||
<tds:GetOnvifInformation /> |
|
||||
</soap:Body> |
|
||||
</soap:Envelope> |
|
||||
@ -1,6 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl"> |
|
||||
<s:Body> |
|
||||
<tptz:GetConfigurations /> |
|
||||
</s:Body> |
|
||||
</s:Envelope> |
|
||||
@ -1,8 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<s:Body> |
|
||||
<tptz:GetPresets> |
|
||||
<tptz:ProfileToken>%s</tptz:ProfileToken> |
|
||||
</tptz:GetPresets> |
|
||||
</s:Body> |
|
||||
</s:Envelope> |
|
||||
@ -1,6 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<soap:Body> |
|
||||
<trt:GetProfiles /> |
|
||||
</soap:Body> |
|
||||
</soap:Envelope> |
|
||||
@ -1,8 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<soap:Body> |
|
||||
<trt:GetSnapshotUri> |
|
||||
<trt:ProfileToken>%s</trt:ProfileToken> |
|
||||
</trt:GetSnapshotUri> |
|
||||
</soap:Body> |
|
||||
</soap:Envelope> |
|
||||
@ -1,8 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<s:Body> |
|
||||
<tptz:GetStatus> |
|
||||
<tptz:ProfileToken>%s</tptz:ProfileToken> |
|
||||
</tptz:GetStatus> |
|
||||
</s:Body> |
|
||||
</s:Envelope> |
|
||||
@ -1,25 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<s:Header xmlns:s="http://www.w3.org/2003/05/soap-envelope"> |
|
||||
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> |
|
||||
<wsse:UsernameToken> |
|
||||
<wsse:Username>%s</wsse:Username> |
|
||||
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">%s</wsse:Password> |
|
||||
<wsse:Nonce>%s</wsse:Nonce> |
|
||||
<wsu:Created>%s</wsu:Created> |
|
||||
</wsse:UsernameToken> |
|
||||
</wsse:Security> |
|
||||
</s:Header> |
|
||||
<soap:Body> |
|
||||
<GetStreamUri xmlns="http://www.onvif.org/ver10/media/wsdl"> |
|
||||
<StreamSetup> |
|
||||
<!-- Attribute Wild card could not be matched. Generated XML may not be valid. --> |
|
||||
<Stream xmlns="http://www.onvif.org/ver10/schema">RTP-Unicast</Stream> |
|
||||
<Transport xmlns="http://www.onvif.org/ver10/schema"> |
|
||||
<Protocol>%s</Protocol> |
|
||||
</Transport> |
|
||||
</StreamSetup> |
|
||||
<ProfileToken>%s</ProfileToken> |
|
||||
</GetStreamUri> |
|
||||
</soap:Body> |
|
||||
</soap:Envelope> |
|
||||
@ -1,9 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<s:Body> |
|
||||
<tptz:GotoPreset> |
|
||||
<tptz:ProfileToken>%s</tptz:ProfileToken> |
|
||||
<tptz:PresetToken>%s</tptz:PresetToken> |
|
||||
</tptz:GotoPreset> |
|
||||
</s:Body> |
|
||||
</s:Envelope> |
|
||||
@ -1,55 +0,0 @@ |
|||||
package com.xr.device_udpclent.common.config; |
|
||||
|
|
||||
import lombok.AllArgsConstructor; |
|
||||
import lombok.Getter; |
|
||||
import lombok.NoArgsConstructor; |
|
||||
import lombok.Setter; |
|
||||
import org.apache.http.Header; |
|
||||
import org.apache.http.HttpStatus; |
|
||||
|
|
||||
import java.util.List; |
|
||||
|
|
||||
@Setter |
|
||||
@Getter |
|
||||
@AllArgsConstructor |
|
||||
@NoArgsConstructor |
|
||||
public class HttpResponseBean { |
|
||||
private String body; |
|
||||
private List<Header> headers; |
|
||||
private Integer status; |
|
||||
|
|
||||
/** |
|
||||
* 获取头部信息。 |
|
||||
* @param name |
|
||||
* @return |
|
||||
*/ |
|
||||
public Header getFirstHeader(final String name) { |
|
||||
for (int i = 0; i < this.headers.size(); i++) { |
|
||||
final Header header = this.headers.get(i); |
|
||||
if (header.getName().equalsIgnoreCase(name)) { |
|
||||
return header; |
|
||||
} |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
/*** |
|
||||
* 判断是否成功 |
|
||||
*/ |
|
||||
public static boolean isSuccess(HttpResponseBean httpResponseBean){ |
|
||||
return httpResponseBean!= null && HttpStatus.SC_OK ==httpResponseBean.getStatus(); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/*** |
|
||||
* 判断是否是401 |
|
||||
*/ |
|
||||
public static boolean isUnAuthorzied(HttpResponseBean httpResponseBean){ |
|
||||
return httpResponseBean!= null && HttpStatus.SC_UNAUTHORIZED ==httpResponseBean.getStatus(); |
|
||||
} |
|
||||
|
|
||||
public HttpResponseBean(String body) { |
|
||||
this.body = body; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@ -1,150 +0,0 @@ |
|||||
package com.xr.device_udpclent.common.utils; |
|
||||
|
|
||||
import com.xr.device_udpclent.models.entity.BallheadPT; |
|
||||
import net.logstash.logback.encoder.org.apache.commons.lang.StringEscapeUtils; |
|
||||
import org.dom4j.Document; |
|
||||
import org.dom4j.Element; |
|
||||
import org.dom4j.io.SAXReader; |
|
||||
|
|
||||
import java.io.ByteArrayInputStream; |
|
||||
import java.nio.charset.StandardCharsets; |
|
||||
import java.util.ArrayList; |
|
||||
import java.util.List; |
|
||||
import java.util.stream.Collectors; |
|
||||
|
|
||||
public class AnalysisXml { |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 解析xml[Profiles] 获取 token |
|
||||
* @param resultStr |
|
||||
* @return |
|
||||
*/ |
|
||||
public static List<String> analysisTokens(String resultStr){ |
|
||||
// 解析body
|
|
||||
// 转换返回结果中的特殊字符,返回的结果中会将xml转义,此处需要反转移
|
|
||||
String xmlStr = StringEscapeUtils.unescapeXml(resultStr); |
|
||||
SAXReader reader = new SAXReader(); |
|
||||
try { |
|
||||
Document document = reader.read(new ByteArrayInputStream(xmlStr.getBytes(StandardCharsets.UTF_8))); |
|
||||
Element root = document.getRootElement(); |
|
||||
List<Element> elements = root.element("Body").element("GetProfilesResponse").elements("Profiles"); |
|
||||
return elements.stream().map(element -> element.attribute("token").getText()).collect(Collectors.toList()); |
|
||||
} catch (Exception e) { |
|
||||
e.printStackTrace(); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
/** |
|
||||
* 解析xml[ProfilesName] 获取 token |
|
||||
* @param resultStr |
|
||||
* @return |
|
||||
*/ |
|
||||
public static List<String> analysisProfiles(String resultStr){ |
|
||||
// 解析body
|
|
||||
// 转换返回结果中的特殊字符,返回的结果中会将xml转义,此处需要反转移
|
|
||||
String xmlStr = StringEscapeUtils.unescapeXml(resultStr); |
|
||||
SAXReader reader = new SAXReader(); |
|
||||
try { |
|
||||
Document document = reader.read(new ByteArrayInputStream(xmlStr.getBytes(StandardCharsets.UTF_8))); |
|
||||
Element root = document.getRootElement(); |
|
||||
List<Element> elements = root.element("Body").element("GetProfilesResponse").elements("Preset"); |
|
||||
return elements.stream().map(element -> element.element("Name").getText() |
|
||||
).collect(Collectors.toList()); |
|
||||
} catch (Exception e) { |
|
||||
e.printStackTrace(); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
/** |
|
||||
* 解析xml[MediaUri] 获取 token |
|
||||
* @param resultStr |
|
||||
* @return |
|
||||
*/ |
|
||||
public static String analysisSnapshotUrl(String resultStr){ |
|
||||
// 解析body
|
|
||||
// 转换返回结果中的特殊字符,返回的结果中会将xml转义,此处需要反转移
|
|
||||
String xmlStr = StringEscapeUtils.unescapeXml(resultStr).replace("&", "&"); |
|
||||
SAXReader reader = new SAXReader(); |
|
||||
try { |
|
||||
Document document = reader.read(new ByteArrayInputStream(xmlStr.getBytes(StandardCharsets.UTF_8))); |
|
||||
Element rootElement = document.getRootElement(); |
|
||||
Element element = rootElement.element("Body").element("GetSnapshotUriResponse").element("MediaUri"); |
|
||||
return String.valueOf(element.elements("Uri").get(0).getData()); |
|
||||
} catch (Exception e) { |
|
||||
e.printStackTrace(); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 解析xml[MediaUri] 获取 streamUrl |
|
||||
* @param resultStr |
|
||||
* @return |
|
||||
*/ |
|
||||
public static String analysisStreamUrl(String resultStr){ |
|
||||
// 解析body
|
|
||||
// 转换返回结果中的特殊字符,返回的结果中会将xml转义,此处需要反转移
|
|
||||
String xmlStr = StringEscapeUtils.unescapeXml(resultStr).replace("&", "&"); |
|
||||
SAXReader reader = new SAXReader(); |
|
||||
try { |
|
||||
Document document = reader.read(new ByteArrayInputStream(xmlStr.getBytes(StandardCharsets.UTF_8))); |
|
||||
Element rootElement = document.getRootElement(); |
|
||||
Element element = rootElement.element("Body").element("GetStreamUriResponse").element("MediaUri"); |
|
||||
return String.valueOf(element.elements("Uri").get(0).getData()); |
|
||||
} catch (Exception e) { |
|
||||
e.printStackTrace(); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
public static List<BallheadPT> getBallheadPTs(String resultStr){ |
|
||||
List<BallheadPT> ballheadPTS=new ArrayList<>(); |
|
||||
String xmlStr = StringEscapeUtils.unescapeXml(resultStr).replace("&", "&"); |
|
||||
SAXReader reader = new SAXReader(); |
|
||||
try { |
|
||||
Document document = reader.read(new ByteArrayInputStream(xmlStr.getBytes(StandardCharsets.UTF_8))); |
|
||||
Element root = document.getRootElement(); |
|
||||
List<Element> elements = root.element("Body").element("GetPresetsResponse").elements("Preset"); |
|
||||
for(Element element:elements){ |
|
||||
BallheadPT pt=new BallheadPT(); |
|
||||
String id = element.attribute(0).getValue(); |
|
||||
pt.setId(id); |
|
||||
String name = String.valueOf(element.element("Name").getText()); |
|
||||
pt.setName(name); |
|
||||
List<Element> ele=element.elements("PTZPosition"); |
|
||||
pt.setX(String.valueOf(ele.get(0).element("PanTilt").attribute(0).getValue())); |
|
||||
pt.setY(String.valueOf(ele.get(0).element("PanTilt").attribute(1).getValue())); |
|
||||
pt.setZ(String.valueOf(ele.get(0).element("Zoom").attribute(0).getValue())); |
|
||||
ballheadPTS.add(pt); |
|
||||
} |
|
||||
} catch (Exception e) { |
|
||||
e.printStackTrace(); |
|
||||
} |
|
||||
return ballheadPTS; |
|
||||
} |
|
||||
|
|
||||
public static BallheadPT getStatus(String resultStr){ |
|
||||
String xmlStr = StringEscapeUtils.unescapeXml(resultStr).replace("&", "&"); |
|
||||
SAXReader reader = new SAXReader(); |
|
||||
try { |
|
||||
Document document = reader.read(new ByteArrayInputStream(xmlStr.getBytes(StandardCharsets.UTF_8))); |
|
||||
Element root = document.getRootElement(); |
|
||||
Element element = root.element("Body").element("GetStatusResponse").element("PTZStatus").element("Position"); |
|
||||
String x=String.valueOf(element.element("PanTilt").attribute(0).getValue()); |
|
||||
String y=String.valueOf(element.element("PanTilt").attribute(1).getValue()); |
|
||||
String z=String.valueOf(element.element("Zoom").attribute(0).getValue()); |
|
||||
BallheadPT pt=new BallheadPT(); |
|
||||
pt.setX(x); |
|
||||
pt.setY(y); |
|
||||
pt.setZ(z); |
|
||||
return pt; |
|
||||
} catch (Exception e) { |
|
||||
e.printStackTrace(); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
} |
|
||||
@ -1,152 +0,0 @@ |
|||||
package com.xr.device_udpclent.common.utils; |
|
||||
|
|
||||
import com.xr.device_udpclent.common.config.HttpResponseBean; |
|
||||
import com.xr.device_udpclent.common.config.OnvifAuthBean; |
|
||||
import com.xr.device_udpclent.models.entity.BallheadPT; |
|
||||
import com.xr.device_udpclent.models.entity.DigestBean; |
|
||||
import com.xr.device_udpclent.models.entity.OnvifBean; |
|
||||
import org.apache.http.auth.AuthScope; |
|
||||
import org.apache.http.auth.UsernamePasswordCredentials; |
|
||||
import org.apache.http.impl.auth.DigestScheme; |
|
||||
import org.apache.http.impl.client.CloseableHttpClient; |
|
||||
import org.apache.http.impl.client.HttpClients; |
|
||||
import org.springframework.core.io.ClassPathResource; |
|
||||
import org.springframework.util.StringUtils; |
|
||||
|
|
||||
import java.io.BufferedReader; |
|
||||
import java.io.InputStreamReader; |
|
||||
import java.io.OutputStream; |
|
||||
import java.net.HttpURLConnection; |
|
||||
import java.net.URL; |
|
||||
import java.nio.charset.StandardCharsets; |
|
||||
import java.util.Base64; |
|
||||
import java.util.List; |
|
||||
|
|
||||
import static com.xr.device_udpclent.common.config.Const.HEADERS_ONVIF_WWW_AUTHENTICATE; |
|
||||
|
|
||||
public class OnvifUtils { |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 获取鉴权 |
|
||||
* @param authType |
|
||||
* @param requestOnvifBean |
|
||||
* @param wsdl |
|
||||
* @param requestUrl |
|
||||
* @return |
|
||||
*/ |
|
||||
public static String getAuthorization(String authType, OnvifBean requestOnvifBean, String wsdl, String requestUrl) { |
|
||||
//参数
|
|
||||
// 读取GetProfiles.wsdl
|
|
||||
String getProfiles = FileUtil.fileReader(new ClassPathResource(wsdl)); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, getProfiles); |
|
||||
//如果是401的话 获取WWW-Authenticate 重新请求
|
|
||||
if (HttpResponseBean.isUnAuthorzied(httpResponseBean)) { |
|
||||
DigestBean digestBean = new DigestBean().getDigestBean(authType,requestOnvifBean, httpResponseBean.getFirstHeader(HEADERS_ONVIF_WWW_AUTHENTICATE).getValue()); |
|
||||
return digestBean.getToken(); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 获取Token |
|
||||
* @param requestOnvifBean |
|
||||
* @param auth |
|
||||
* @return |
|
||||
*/ |
|
||||
public static List<String> getProfileTokens(OnvifBean requestOnvifBean, String auth) { |
|
||||
//请求url
|
|
||||
String requestUrl = OnvifBean.getRequestUrl(requestOnvifBean); |
|
||||
//参数
|
|
||||
// 读取GetProfiles.wsdl
|
|
||||
String getProfiles = FileUtil.fileReader(new ClassPathResource("digest/GetProfiles.wsdl")); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, getProfiles,auth); |
|
||||
if(httpResponseBean != null) { |
|
||||
String resultStr = httpResponseBean.getBody(); |
|
||||
if (HttpResponseBean.isSuccess(httpResponseBean) && StringUtils.hasLength(resultStr)) { |
|
||||
return AnalysisXml.analysisTokens(resultStr); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 获取截图地址 |
|
||||
* @param profileToken token |
|
||||
* @param requestOnvifBean |
|
||||
* @return |
|
||||
*/ |
|
||||
public static String getSnapshotUrl(String profileToken, OnvifAuthBean requestOnvifBean) { |
|
||||
String requestUrl = OnvifBean.getRequestUrl(requestOnvifBean); |
|
||||
//参数
|
|
||||
// 读取GetProfiles.wsdl
|
|
||||
String snapshotUrlWsdl = FileUtil.fileReader(new ClassPathResource("digest/GetSnapshotUrl.wsdl")); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, String.format(snapshotUrlWsdl,profileToken),requestOnvifBean.getAuth()); |
|
||||
String resultStr = httpResponseBean.getBody(); |
|
||||
if(StringUtils.hasLength(resultStr) && HttpResponseBean.isSuccess(httpResponseBean)) { |
|
||||
return AnalysisXml.analysisSnapshotUrl(resultStr); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
//绝对位置转动球机
|
|
||||
public static boolean ptzCamera(String profileToken,OnvifAuthBean requestOnvifBean,String x,String y,String z){ |
|
||||
String requestUrl = OnvifBean.getRequestUrl(requestOnvifBean); |
|
||||
String snapshotUrlWsdl = FileUtil.fileReader(new ClassPathResource("digest/AbsoluteMove.wsdl")); |
|
||||
String wsdl = String.format(snapshotUrlWsdl,profileToken,x,y,z); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, wsdl,requestOnvifBean.getAuth()); |
|
||||
String resultStr = httpResponseBean.getBody(); |
|
||||
if(StringUtils.hasLength(resultStr) && HttpResponseBean.isSuccess(httpResponseBean)) { |
|
||||
return true; |
|
||||
} |
|
||||
return false; |
|
||||
} |
|
||||
//获取球机当前位置
|
|
||||
public static BallheadPT getPtzStatus(String token,OnvifAuthBean requestOnvifBean){ |
|
||||
String requestUrl = OnvifBean.getRequestUrl(requestOnvifBean); |
|
||||
String snap = FileUtil.fileReader(new ClassPathResource("digest/GetStatus.wsdl")); |
|
||||
String wsdl = String.format(snap,token); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, wsdl,requestOnvifBean.getAuth()); |
|
||||
String resultStr = httpResponseBean.getBody(); |
|
||||
if(StringUtils.hasLength(resultStr) && HttpResponseBean.isSuccess(httpResponseBean)) { |
|
||||
return AnalysisXml.getStatus(resultStr); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
//获取所有预置点
|
|
||||
public static List<BallheadPT> getBallHeadPts(String profileToken,OnvifAuthBean requestOnvifBean){ |
|
||||
String requestUrl = OnvifBean.getRequestUrl(requestOnvifBean); |
|
||||
String snapshotUrlWsdl = FileUtil.fileReader(new ClassPathResource("digest/GetPresets.wsdl")); |
|
||||
String wsdl = String.format(snapshotUrlWsdl,profileToken); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, wsdl,requestOnvifBean.getAuth()); |
|
||||
String resultStr = httpResponseBean.getBody(); |
|
||||
if(StringUtils.hasLength(resultStr) && HttpResponseBean.isSuccess(httpResponseBean)) { |
|
||||
return AnalysisXml.getBallheadPTs(resultStr); |
|
||||
} |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
//前往指定预置点
|
|
||||
public static boolean gotoBallHeadPts(String profileToken,OnvifAuthBean requestOnvifBean,BallheadPT ballheadPT){ |
|
||||
String requestUrl = OnvifBean.getRequestUrl(requestOnvifBean); |
|
||||
String snapshotUrlWsdl = FileUtil.fileReader(new ClassPathResource("digest/GotoPreset.wsdl")); |
|
||||
String wsdl = String.format(snapshotUrlWsdl,profileToken,ballheadPT.getId()); |
|
||||
HttpResponseBean httpResponseBean = RESTClient.getClientConnectionPool() |
|
||||
.postXML(requestUrl, wsdl,requestOnvifBean.getAuth()); |
|
||||
String resultStr = httpResponseBean.getBody(); |
|
||||
if(StringUtils.hasLength(resultStr) && HttpResponseBean.isSuccess(httpResponseBean)) { |
|
||||
return true; |
|
||||
} |
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
@ -1,281 +0,0 @@ |
|||||
package com.xr.device_udpclent.common.utils; |
|
||||
|
|
||||
import com.xr.device_udpclent.common.config.HttpResponseBean; |
|
||||
import org.apache.http.*; |
|
||||
import org.apache.http.client.HttpRequestRetryHandler; |
|
||||
import org.apache.http.client.config.CookieSpecs; |
|
||||
import org.apache.http.client.config.RequestConfig; |
|
||||
import org.apache.http.client.methods.HttpPost; |
|
||||
import org.apache.http.client.protocol.HttpClientContext; |
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier; |
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
|
||||
import org.apache.http.entity.ContentType; |
|
||||
import org.apache.http.entity.StringEntity; |
|
||||
import org.apache.http.impl.client.CloseableHttpClient; |
|
||||
import org.apache.http.impl.client.HttpClients; |
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
|
||||
import org.apache.http.protocol.HttpContext; |
|
||||
import org.apache.http.ssl.SSLContextBuilder; |
|
||||
import org.apache.http.util.EntityUtils; |
|
||||
import org.slf4j.Logger; |
|
||||
import org.slf4j.LoggerFactory; |
|
||||
import org.springframework.util.StringUtils; |
|
||||
|
|
||||
import javax.net.ssl.HostnameVerifier; |
|
||||
import javax.net.ssl.SSLContext; |
|
||||
import javax.net.ssl.SSLHandshakeException; |
|
||||
import java.io.IOException; |
|
||||
import java.net.ConnectException; |
|
||||
import java.util.Arrays; |
|
||||
import java.util.regex.Matcher; |
|
||||
import java.util.regex.Pattern; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* Http请求客户端 |
|
||||
* @author ChenYongHeng |
|
||||
* @since 2019/5/27 |
|
||||
*/ |
|
||||
public class RESTClient { |
|
||||
|
|
||||
|
|
||||
private static Logger log = LoggerFactory.getLogger(RESTClient.class); |
|
||||
|
|
||||
|
|
||||
|
|
||||
private volatile static RESTClient HttpClientConnectionPool; |
|
||||
|
|
||||
private static final String USERAGENT = "SZ-JAVA"; |
|
||||
private static final String CHARSET = "UTF-8"; |
|
||||
|
|
||||
private static final int MAX_TOTAL_CONNECTIONS = 200; |
|
||||
private static final int MAX_ROUTE_CONNECTIONS = 100; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 连接时间 |
|
||||
*/ |
|
||||
private static final int CONNECT_TIMEOUT = 5000; |
|
||||
/** |
|
||||
* 获取内容时间 |
|
||||
*/ |
|
||||
private static final int SOCKET_TIMEOUT = 30000; |
|
||||
|
|
||||
private static PoolingHttpClientConnectionManager cm = null; |
|
||||
|
|
||||
|
|
||||
private static CloseableHttpClient HTTP_CLIENTS; |
|
||||
|
|
||||
/** |
|
||||
* 初始化连接池 |
|
||||
*/ |
|
||||
static{ |
|
||||
try { |
|
||||
cm = new PoolingHttpClientConnectionManager(); |
|
||||
cm.setMaxTotal(MAX_TOTAL_CONNECTIONS); |
|
||||
// 默认设置为2
|
|
||||
cm.setDefaultMaxPerRoute(MAX_ROUTE_CONNECTIONS); |
|
||||
// 客户端请求的默认设置
|
|
||||
RequestConfig defaultRequestConfig = RequestConfig.custom() |
|
||||
.setSocketTimeout(SOCKET_TIMEOUT) |
|
||||
.setConnectTimeout(CONNECT_TIMEOUT) |
|
||||
.setConnectionRequestTimeout(CONNECT_TIMEOUT) |
|
||||
.setRedirectsEnabled(false) |
|
||||
.setCookieSpec(CookieSpecs.STANDARD_STRICT) |
|
||||
.build(); |
|
||||
|
|
||||
// 请求重试处理
|
|
||||
HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() { |
|
||||
@Override |
|
||||
public boolean retryRequest(IOException exception, |
|
||||
int executionCount, HttpContext context) { |
|
||||
// 如果超过最大重试次数,那么就不要继续了
|
|
||||
if (executionCount >= 2) { |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
// 如果服务器丢掉了连接,那么就重试
|
|
||||
if (exception instanceof NoHttpResponseException) { |
|
||||
return true; |
|
||||
} |
|
||||
// 不要重试SSL握手异常
|
|
||||
if (exception instanceof SSLHandshakeException) { |
|
||||
return false; |
|
||||
} |
|
||||
HttpRequest request = (HttpRequest) context.getAttribute(HttpClientContext.HTTP_REQUEST); |
|
||||
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); |
|
||||
// 如果请求被认为是幂等的,那么就重试
|
|
||||
if (idempotent) { |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
}; |
|
||||
// https 信任所有
|
|
||||
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -> true).build(); |
|
||||
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; |
|
||||
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); |
|
||||
|
|
||||
HTTP_CLIENTS = HttpClients.custom() |
|
||||
.setConnectionManager(cm) |
|
||||
.setDefaultRequestConfig(defaultRequestConfig) |
|
||||
.setRetryHandler(httpRequestRetryHandler) |
|
||||
//https
|
|
||||
.setSSLSocketFactory(sslSocketFactory) |
|
||||
.build(); |
|
||||
} catch (Exception e) { |
|
||||
e.printStackTrace(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
private RESTClient(){} |
|
||||
|
|
||||
/** |
|
||||
* 获取HttpClientConnectionPool对象,这是单例方法 |
|
||||
* |
|
||||
* @return |
|
||||
*/ |
|
||||
public static RESTClient getClientConnectionPool() { |
|
||||
if (HttpClientConnectionPool == null) { |
|
||||
synchronized (RESTClient.class) { |
|
||||
if (HttpClientConnectionPool == null) { |
|
||||
HttpClientConnectionPool = new RESTClient(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return HttpClientConnectionPool; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 一般情况下是AuthToken使用 |
|
||||
* @param url |
|
||||
* @param xmlFileName |
|
||||
* @return |
|
||||
*/ |
|
||||
public HttpResponseBean postXML(String url, String xmlFileName){ |
|
||||
return postXML( url, xmlFileName,""); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 一般情况下是DigestBean使用 |
|
||||
* @param url |
|
||||
* @param xmlFileName |
|
||||
* @param auth |
|
||||
* @return |
|
||||
*/ |
|
||||
public HttpResponseBean postXML(String url,String xmlFileName,String auth){ |
|
||||
HttpPost httpPost = new HttpPost(url); |
|
||||
String seqNum = String.valueOf(System.currentTimeMillis()); |
|
||||
httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/soap+xml; charset=utf-8"); |
|
||||
if(StringUtils.hasLength(xmlFileName))httpPost.setEntity(new StringEntity(xmlFileName, ContentType.APPLICATION_JSON)); |
|
||||
if(StringUtils.hasLength(auth)) httpPost.setHeader("Authorization",auth); |
|
||||
log.info(seqNum+">>> "+httpPost.toString()); |
|
||||
log.info(seqNum+"Body>>> " +xmlFileName); |
|
||||
return httpPost(httpPost,seqNum); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Post方法封装,发送post请求,获取响应内容 |
|
||||
*/ |
|
||||
public String fetchByPostMethod(String url, String jsonStr) { |
|
||||
String resultStr = null; |
|
||||
HttpPost httpPost = httpPostAddHeader(url, jsonStr); |
|
||||
String seqNum = String.valueOf(System.currentTimeMillis()); |
|
||||
log.info(seqNum + ">>> " + httpPost.toString()); |
|
||||
log.info(seqNum + "Body>>> " + jsonStr); |
|
||||
HttpResponse response; |
|
||||
try { |
|
||||
response = HTTP_CLIENTS.execute(httpPost); |
|
||||
HttpEntity entity = response.getEntity(); |
|
||||
resultStr = EntityUtils.toString(entity, CHARSET); |
|
||||
EntityUtils.consume(entity); |
|
||||
} catch (IOException ce) {// 服务器请求失败
|
|
||||
log.error(ce.getMessage()); |
|
||||
} finally { |
|
||||
httpPost.abort(); |
|
||||
} |
|
||||
log.info(seqNum + "<<< " + resultStr); |
|
||||
return resultStr; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 添加头部信息 |
|
||||
* @param url |
|
||||
* @param jsonStr |
|
||||
* @return |
|
||||
*/ |
|
||||
private HttpPost httpPostAddHeader(String url, String jsonStr){ |
|
||||
HttpPost httpPost = new HttpPost(url); |
|
||||
httpPost.setEntity(new StringEntity(jsonStr, ContentType.APPLICATION_JSON)); |
|
||||
httpPost.addHeader(HttpHeaders.USER_AGENT, USERAGENT); |
|
||||
httpPost.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()); |
|
||||
return httpPost; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* httppost |
|
||||
* @param httpPost |
|
||||
* @param seqNum |
|
||||
* @return |
|
||||
*/ |
|
||||
private HttpResponseBean httpPost(HttpPost httpPost,String seqNum ) { |
|
||||
String resultStr = null; |
|
||||
HttpResponse response = null; |
|
||||
try{ |
|
||||
response = HTTP_CLIENTS.execute(httpPost); |
|
||||
int statusCode = response.getStatusLine().getStatusCode(); |
|
||||
if(statusCode == HttpStatus.SC_UNAUTHORIZED) { |
|
||||
//如果是401直接返回
|
|
||||
return new HttpResponseBean(null, Arrays.asList(response.getAllHeaders()),response.getStatusLine().getStatusCode()); |
|
||||
} |
|
||||
HttpEntity entity = response.getEntity(); |
|
||||
resultStr = EntityUtils.toString(entity,CHARSET); |
|
||||
EntityUtils.consume(entity); |
|
||||
}catch (ConnectException ce){// 服务器请求失败
|
|
||||
log.error("ConnectException fetchByPostMethod---->>>{}",ce.getMessage()); |
|
||||
} catch (IOException e) { |
|
||||
log.error("IOException fetchByPostMethod---->>>{}",e.getMessage()); |
|
||||
}finally { |
|
||||
httpPost.abort(); |
|
||||
} |
|
||||
log.info(seqNum+"<<< "+resultStr); |
|
||||
if(response != null) return new HttpResponseBean(resultStr, Arrays.asList(response.getAllHeaders()),response.getStatusLine().getStatusCode()); |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* 正则获取字符编码 |
|
||||
* @param content_type |
|
||||
* @return |
|
||||
*/ |
|
||||
private static String getCharSetFromContentType(String content_type){ |
|
||||
String regex = "charset=\\s*(\\S*[^;])"; |
|
||||
Pattern pattern = Pattern.compile(regex,Pattern.DOTALL); |
|
||||
Matcher matcher = pattern.matcher(content_type); |
|
||||
if(matcher.find()){ |
|
||||
return matcher.group(1); |
|
||||
|
|
||||
}else{ |
|
||||
return null; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
} |
|
||||
@ -1,12 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<s:Body> |
|
||||
<tptz:AbsoluteMove> |
|
||||
<tptz:ProfileToken>%s</tptz:ProfileToken> |
|
||||
<tptz:Position> |
|
||||
<tt:PanTilt y="%s" x="%s" space="http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace" /> |
|
||||
<tt:Zoom x="%s" space="http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace" /> |
|
||||
</tptz:Position> |
|
||||
</tptz:AbsoluteMove> |
|
||||
</s:Body> |
|
||||
</s:Envelope> |
|
||||
@ -1,6 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<soap:Body> |
|
||||
<tds:GetOnvifInformation /> |
|
||||
</soap:Body> |
|
||||
</soap:Envelope> |
|
||||
@ -1,6 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl"> |
|
||||
<s:Body> |
|
||||
<tptz:GetConfigurations /> |
|
||||
</s:Body> |
|
||||
</s:Envelope> |
|
||||
@ -1,8 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<s:Body> |
|
||||
<tptz:GetPresets> |
|
||||
<tptz:ProfileToken>%s</tptz:ProfileToken> |
|
||||
</tptz:GetPresets> |
|
||||
</s:Body> |
|
||||
</s:Envelope> |
|
||||
@ -1,6 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<soap:Body> |
|
||||
<trt:GetProfiles /> |
|
||||
</soap:Body> |
|
||||
</soap:Envelope> |
|
||||
@ -1,8 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<soap:Body> |
|
||||
<trt:GetSnapshotUri> |
|
||||
<trt:ProfileToken>%s</trt:ProfileToken> |
|
||||
</trt:GetSnapshotUri> |
|
||||
</soap:Body> |
|
||||
</soap:Envelope> |
|
||||
@ -1,8 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<s:Body> |
|
||||
<tptz:GetStatus> |
|
||||
<tptz:ProfileToken>%s</tptz:ProfileToken> |
|
||||
</tptz:GetStatus> |
|
||||
</s:Body> |
|
||||
</s:Envelope> |
|
||||
@ -1,25 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<s:Header xmlns:s="http://www.w3.org/2003/05/soap-envelope"> |
|
||||
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> |
|
||||
<wsse:UsernameToken> |
|
||||
<wsse:Username>%s</wsse:Username> |
|
||||
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">%s</wsse:Password> |
|
||||
<wsse:Nonce>%s</wsse:Nonce> |
|
||||
<wsu:Created>%s</wsu:Created> |
|
||||
</wsse:UsernameToken> |
|
||||
</wsse:Security> |
|
||||
</s:Header> |
|
||||
<soap:Body> |
|
||||
<GetStreamUri xmlns="http://www.onvif.org/ver10/media/wsdl"> |
|
||||
<StreamSetup> |
|
||||
<!-- Attribute Wild card could not be matched. Generated XML may not be valid. --> |
|
||||
<Stream xmlns="http://www.onvif.org/ver10/schema">RTP-Unicast</Stream> |
|
||||
<Transport xmlns="http://www.onvif.org/ver10/schema"> |
|
||||
<Protocol>%s</Protocol> |
|
||||
</Transport> |
|
||||
</StreamSetup> |
|
||||
<ProfileToken>%s</ProfileToken> |
|
||||
</GetStreamUri> |
|
||||
</soap:Body> |
|
||||
</soap:Envelope> |
|
||||
@ -1,9 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema"> |
|
||||
<s:Body> |
|
||||
<tptz:GotoPreset> |
|
||||
<tptz:ProfileToken>%s</tptz:ProfileToken> |
|
||||
<tptz:PresetToken>%s</tptz:PresetToken> |
|
||||
</tptz:GotoPreset> |
|
||||
</s:Body> |
|
||||
</s:Envelope> |
|
||||
Loading…
Reference in new issue