1.json文件优化 增加配置项:【1.触发点;2.逻辑线程时间间隔】
2.优化处理代码 【1.去除多余日志输出点;2.两个设备json文件进行根据codeId进行关联;3.调整代码先后顺序】
3.json文件路径提出jar包外,可在设备表上配置上配置路径。因原方式修改地址json 后需重新打包,实际调试中传递jar包比较浪费时间
9个文件已添加
2 文件已复制
10个文件已修改
15个文件已删除
2 文件已重命名
| New file |
| | |
| | | { |
| | | "parameters": [ |
| | | { |
| | | "serialNumber": 0, |
| | | "content": "PLC请求", |
| | | "codeId": "plcRequest", |
| | | "plcDataType": "Word", |
| | | "fontLocation": 0, |
| | | "length": 2, |
| | | "ratio": 1, |
| | | "scale": 10, |
| | | "address": "S7.DB8.DBW0", |
| | | "remarks": "" |
| | | }, |
| | | { |
| | | "serialNumber": 1, |
| | | "content": "Mes发送字", |
| | | "codeId": "mesSend", |
| | | "plcDataType": "Word", |
| | | "fontLocation": 18, |
| | | "length": 2, |
| | | "ratio": 1, |
| | | "scale": 10, |
| | | "address": "S7.DB8.DBW2", |
| | | "remarks": "" |
| | | }, |
| | | { |
| | | "serialNumber": 2, |
| | | "content": "MES发送长", |
| | | "codeId": "width", |
| | | "plcDataType": "Word", |
| | | "fontLocation": 20, |
| | | "length": 2, |
| | | "ratio": 11, |
| | | "scale": 11, |
| | | "address": "S7.DB8.DBW4", |
| | | "remarks": "" |
| | | }, |
| | | { |
| | | "serialNumber": 11, |
| | | "content": "MES发送宽", |
| | | "codeId": "height", |
| | | "plcDataType": "Word", |
| | | "fontLocation": 22, |
| | | "length": 2, |
| | | "ratio": 12, |
| | | "scale": 12, |
| | | "address":"S7.DB8.DBW6", |
| | | "remarks": "" |
| | | } |
| | | ] |
| | | } |
| New file |
| | |
| | | { |
| | | "logics": [ |
| | | { |
| | | "name":"请求逻辑", |
| | | "sequence":"1", |
| | | "apiConfigBefore": { |
| | | "codeId": "loadSelect", |
| | | "type": "Http", |
| | | "address": "http://localhost:8082/account/testApi", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcRequest", |
| | | "value": [1] |
| | | }, |
| | | { |
| | | "codeId": "mesSend", |
| | | "value": [0] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesSend", |
| | | "fixed": true, |
| | | "value": 1 |
| | | }, |
| | | { |
| | | "codeId": "width", |
| | | "fixed": false, |
| | | "value": 1 |
| | | } |
| | | , |
| | | { |
| | | "codeId": "height", |
| | | "fixed": false, |
| | | "value": 2 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "name":"请求清空", |
| | | "sequence":"2", |
| | | "apiConfigBefore": { |
| | | "codeId": "", |
| | | "type": "View", |
| | | "address": "viewname", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcRequest", |
| | | "value": [0] |
| | | }, |
| | | { |
| | | "codeId": "mesSend", |
| | | "value": [1] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesSend", |
| | | "fixed": true, |
| | | "value": 0 |
| | | }, |
| | | { |
| | | "codeId": "width", |
| | | "fixed": true, |
| | | "value": 0 |
| | | }, |
| | | { |
| | | "codeId": "height", |
| | | "fixed": true, |
| | | "value": 0 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "name":"完成逻辑", |
| | | "sequence":"3", |
| | | "apiConfigBefore": { |
| | | "codeId": "edgSelect", |
| | | "type": "View", |
| | | "address": "viewname", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcComplete", |
| | | "value": [1] |
| | | }, |
| | | { |
| | | "codeId": "mesComplete", |
| | | "value": [0] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesComplete", |
| | | "fixed": true, |
| | | "value": 1 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "name":"完成清空", |
| | | "sequence":"4", |
| | | "apiConfigBefore": { |
| | | "codeId": "edgSelect", |
| | | "type": "View", |
| | | "address": "viewname", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcComplete", |
| | | "value": [0] |
| | | }, |
| | | { |
| | | "codeId": "mesComplete", |
| | | "value": [1,2,3] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesComplete", |
| | | "fixed": true, |
| | | "value": 0 |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| New file |
| | |
| | | { |
| | | "logics": [ |
| | | { |
| | | "name":"请求逻辑", |
| | | "sequence":"1", |
| | | "apiConfigBefore": { |
| | | "codeId": "edgSelect", |
| | | "type": "Procedure", |
| | | "address": "testProcedure", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcRequest", |
| | | "value": [1] |
| | | }, |
| | | { |
| | | "codeId": "mesSend", |
| | | "value": [0] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesSend", |
| | | "address": "S7.DB8.DBW2", |
| | | "fixed": true, |
| | | "value": 1, |
| | | "plcDataType": "int", |
| | | "length": 2 |
| | | }, |
| | | { |
| | | "codeId": "width", |
| | | "address": "S7.DB8.DBW4", |
| | | "fixed": false, |
| | | "value": 1, |
| | | "plcDataType": "int", |
| | | "length": 2 |
| | | } |
| | | , |
| | | { |
| | | "codeId": "height", |
| | | "address": "S7.DB8.DBW6", |
| | | "fixed": false, |
| | | "value": 2, |
| | | "plcDataType": "int", |
| | | "length": 2 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "name":"请求清空", |
| | | "sequence":"2", |
| | | "apiConfigBefore": { |
| | | "codeId": "edgSelect", |
| | | "type": "View", |
| | | "address": "viewname", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcRequest", |
| | | "value": [0] |
| | | }, |
| | | { |
| | | "codeId": "mesSend", |
| | | "value": [1] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesSend", |
| | | "fixed": true, |
| | | "value": 0 |
| | | }, |
| | | { |
| | | "codeId": "width", |
| | | "fixed": true, |
| | | "value": 0 |
| | | }, |
| | | { |
| | | "codeId": "height", |
| | | "fixed": true, |
| | | "value": 0 |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| New file |
| | |
| | | { |
| | | "logics": [ |
| | | { |
| | | "name":"请求逻辑", |
| | | "sequence":"1", |
| | | "apiConfigBefore": { |
| | | "codeId": "edgSelect", |
| | | "type": "View", |
| | | "address": "viewname" |
| | | }, |
| | | "apiConfigAfter": { |
| | | "codeId": "edgSelect", |
| | | "type": "Http", |
| | | "address": "http://localhost:8082/account/testApi", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcRequest", |
| | | "value": [1] |
| | | }, |
| | | { |
| | | "codeId": "mesSend", |
| | | "value": [0] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesSend", |
| | | "address": "S7.DB8.DBW2", |
| | | "fixed": true, |
| | | "value": 1, |
| | | "plcDataType": "int", |
| | | "length": 2 |
| | | }, |
| | | { |
| | | "codeId": "width", |
| | | "address": "S7.DB8.DBW4", |
| | | "fixed": false, |
| | | "value": 1, |
| | | "plcDataType": "int", |
| | | "length": 2 |
| | | } |
| | | , |
| | | { |
| | | "codeId": "height", |
| | | "address": "S7.DB8.DBW6", |
| | | "fixed": false, |
| | | "value": 2, |
| | | "plcDataType": "int", |
| | | "length": 2 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "name":"请求清空", |
| | | "sequence":"2", |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcRequest", |
| | | "value": [0] |
| | | }, |
| | | { |
| | | "codeId": "mesSend", |
| | | "value": [1] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesSend", |
| | | "fixed": true, |
| | | "value": 0 |
| | | }, |
| | | { |
| | | "codeId": "width", |
| | | "fixed": true, |
| | | "value": 0 |
| | | }, |
| | | { |
| | | "codeId": "height", |
| | | "fixed": true, |
| | | "value": 0 |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
copy from ShangHaiMesParent/moduleService/plcConnectModule/src/main/resources/JsonFile/shelf.json
copy to JsonFile/ShelfModbusTcp.json
copy from ShangHaiMesParent/moduleService/plcConnectModule/src/main/resources/JsonFile/shelfS7.json
copy to JsonFile/ShelfS7.json
| | |
| | | //1.根据数据库设备表加载数据 得到全部 设备信息 |
| | | List<Machine> listMachine = machineService.getMachineConfig(); |
| | | //2.根据设备配置进行加载多线程 |
| | | for (int i = 1; i < listMachine.size(); i++) |
| | | //2.根据设备配置进行加载多线程 |
| | | for (int i = 0; i < listMachine.size(); i++){ |
| | | if("ON".equals(listMachine.get(i).getOpen()) ){ |
| | | try { |
| | | Machine machine = listMachine.get(i); |
| | | Thread thread = new Thread(new MachineThread(machine, api)); |
| | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | import com.alibaba.fastjson.JSONException; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import org.springframework.core.io.ClassPathResource; |
| | | import org.springframework.core.io.Resource; |
| | | |
| | | import java.io.BufferedReader; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.InputStreamReader; |
| | | import java.io.*; |
| | | |
| | | public class ReadFile { |
| | | // 读取Json文件内容 |
| | | public static JSONObject readJson(String fileName) throws IOException { |
| | | public static JSONObject readJson(String fileUrl) throws IOException { |
| | | // 资源路径(相对于resources根目录) |
| | | String resourcePath = "jsonFile/"+fileName; |
| | | //String resourcePath = "jsonFile/"+fileName; |
| | | //String resourcePath = System.getProperty("user.dir") + "/JsonFile/"+fileName; |
| | | String resourcePath = fileUrl; |
| | | // 获取类加载器 |
| | | ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); |
| | | //ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); |
| | | // 读取资源 |
| | | try (InputStream inputStream = classLoader.getResourceAsStream(resourcePath)) { |
| | | |
| | | try (InputStream inputStream = new FileInputStream(resourcePath)) { |
| | | //try (InputStream inputStream = classLoader.getResourceAsStream(resourcePath)) { |
| | | if (inputStream == null) { |
| | | throw new IOException("资源未找到: " + resourcePath); |
| | | } |
| | |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.baomidou.dynamic.datasource.annotation.DS; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.mes.connect.entity.ApiConfig; |
| | | import com.mes.connect.entity.LogicItem; |
| | | import com.mes.connect.entity.PlcParameters; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.http.*; |
| | | import org.springframework.jdbc.core.JdbcTemplate; |
| | |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Slf4j |
| | | @Service |
| | | public class Api implements ApiService { |
| | | |
| | |
| | | this.restTemplate = restTemplate; |
| | | this.jdbcTemplate = jdbcTemplate; |
| | | } |
| | | |
| | | /** |
| | | * 发送调用接口请求 ,根据逻辑配置调用 |
| | | * |
| | | * @param apiConfig 逻辑配置参数 |
| | | * @param plcParameters plc参数 |
| | | * @return 响应内容按行分割的数组 |
| | | */ |
| | | public List<String> callApi(ApiConfig apiConfig, PlcParameters plcParameters){ |
| | | try{ |
| | | List<String> result=new ArrayList<>(); |
| | | String connectType=apiConfig.getType(); |
| | | String connectAddress=apiConfig.getAddress(); |
| | | Map<String,Object> map=new HashMap<String,Object>(); |
| | | map.put("apiConfig",apiConfig); |
| | | map.put("plcParameter",plcParameters); |
| | | switch (connectType) { |
| | | case "Http": |
| | | result= this.httpApi(connectAddress,map); |
| | | break; |
| | | case "View": // 视图/表 |
| | | result= this.viewApi(connectAddress,map); |
| | | break; |
| | | case "Procedure": // 存储过程 |
| | | result= this.procedureAPI(connectAddress,map); |
| | | break; |
| | | default: |
| | | log.warn("不支持的连接类型: {}", connectType); |
| | | return null; // 不支持的方式 |
| | | } |
| | | return result; |
| | | }catch (Exception e){ |
| | | log.error("调用接口失败: {}", e.getMessage(), e); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 发送HTTP请求,支持GET和POST方法 |
| | | * |
| | |
| | | UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url); |
| | | // 处理响应 |
| | | String responseBody; |
| | | String method=data.get("method").toString(); |
| | | data.remove("method"); |
| | | ObjectMapper mapper = new ObjectMapper(); |
| | | Map<String, Object> apiConfig= mapper.convertValue(data.get("apiConfig"), Map.class); |
| | | Map<String, Object> parameters= mapper.convertValue(apiConfig.get("parameters"), Map.class); |
| | | String method=parameters.get("method").toString(); |
| | | data.remove("parameters"); |
| | | if ("GET".equals(method)) { |
| | | // GET请求:将参数添加到URL查询参数中 |
| | | if (data != null) { |
| | |
| | | } |
| | | @DS("mes_machine") |
| | | @Override |
| | | public List<String> viewApi(String viewName, Map<String, Object> params) { |
| | | public List<String> viewApi(String viewName, Map<String, Object> parameters) { |
| | | // 验证视图名是否合法,防止SQL注入 |
| | | if (!isValidViewName(viewName)) { |
| | | throw new IllegalArgumentException("无效的视图名称"); |
| | | } |
| | | |
| | | ObjectMapper mapper = new ObjectMapper(); |
| | | Map<String, Object> apiConfig= mapper.convertValue(parameters.get("apiConfig"), Map.class); |
| | | Map<String, Object> params= mapper.convertValue(apiConfig.get("parameters"), Map.class); |
| | | // 使用预编译语句构建查询 |
| | | StringBuilder sql = new StringBuilder("SELECT * FROM " + viewName); |
| | | MapSqlParameterSource paramSource = new MapSqlParameterSource(); |
| | |
| | | } |
| | | @DS("jiumumes") |
| | | @Override |
| | | public List<String> procedureAPI(String procedureName, Map<String, Object> params,Map<String, Object> outParams) { |
| | | public List<String> procedureAPI(String procedureName, Map<String, Object> params) { |
| | | try { |
| | | if (!isValidProcedureName(procedureName)) { |
| | | throw new IllegalArgumentException("无效的存储过程名称"); |
| | | } |
| | | |
| | | ObjectMapper mapper = new ObjectMapper(); |
| | | Map<String, Object> apiConfig= mapper.convertValue(params.get("apiConfig"), Map.class); |
| | | Map<String, Object> parameters=mapper.convertValue(apiConfig.get("parameters"), Map.class); |
| | | Map<String, Object> inParams= mapper.convertValue(parameters.get("inParams"), Map.class); |
| | | Map<String, Object> outParams= mapper.convertValue(parameters.get("outParams"), Map.class); |
| | | // 创建新的 Map 并合并 |
| | | Map<String, Object> mergedMap = new HashMap<>(inParams); |
| | | mergedMap.putAll(outParams); |
| | | SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate) |
| | | .withProcedureName(procedureName) |
| | | .withoutProcedureColumnMetaDataAccess(); |
| | | |
| | | if (params != null) { |
| | | for (Map.Entry<String, Object> entry : params.entrySet()) { |
| | | // 确定参数类型 |
| | | for (Map.Entry<String, Object> entry : inParams.entrySet()) { |
| | | int sqlType = getSqlType(entry.getValue()); |
| | | |
| | | // 检查是否为输出参数 |
| | | if (outParams != null && outParams.containsKey(entry.getKey())) { |
| | | Object outParamInfo = outParams.get(entry.getKey()); |
| | | int outSqlType; |
| | | |
| | | // 从输出参数信息中获取SQL类型 |
| | | if (outParamInfo instanceof Integer) { |
| | | outSqlType = (Integer) outParamInfo; |
| | | } else if (outParamInfo instanceof Map) { |
| | | // 假设Map中包含"sqlType"键 |
| | | Map<String, Object> outParamMap = (Map<String, Object>) outParamInfo; |
| | | outSqlType = (Integer) outParamMap.getOrDefault("sqlType", sqlType); |
| | | } else { |
| | | // 默认使用输入参数的SQL类型 |
| | | outSqlType = sqlType; |
| | | } |
| | | |
| | | // 使用指定的SQL类型作为输出参数 |
| | | jdbcCall.declareParameters( |
| | | new SqlOutParameter(entry.getKey(), outSqlType) |
| | | ); |
| | | } else { |
| | | // 作为输入参数 |
| | | jdbcCall.declareParameters( |
| | | new SqlParameter(entry.getKey(), sqlType) |
| | | ); |
| | | } |
| | | } |
| | | } |
| | | for (Map.Entry<String, Object> entry : outParams.entrySet()) { |
| | | int outSqlType=12; |
| | | // int sqlType = getSqlType(entry.getValue()); |
| | | // Object outParamInfo = outParams.get(entry.getKey()); |
| | | // // 从输出参数信息中获取SQL类型 |
| | | // if (outParamInfo instanceof Integer) { |
| | | // outSqlType = (Integer) outParamInfo; |
| | | // } else if (outParamInfo instanceof Map) { |
| | | // // 假设Map中包含"sqlType"键 |
| | | // Map<String, Object> outParamMap = (Map<String, Object>) outParamInfo; |
| | | // outSqlType = (Integer) outParamMap.getOrDefault("sqlType", sqlType); |
| | | // } else { |
| | | // // 默认使用输入参数的SQL类型 |
| | | // outSqlType = sqlType; |
| | | // } |
| | | |
| | | // 使用指定的SQL类型作为输出参数 |
| | | jdbcCall.declareParameters( |
| | | new SqlOutParameter(entry.getKey(), outSqlType) |
| | | ); |
| | | } |
| | | // 执行存储过程并获取结果 |
| | | Map<String, Object> result = jdbcCall.execute(params); |
| | | Map<String, Object> result = jdbcCall.execute(mergedMap); |
| | | |
| | | // 处理输出参数 |
| | | if (outParams != null) { |
| | | for (String paramName : outParams.keySet()) { |
| | | if (result.containsKey(paramName)) { |
| | | // 将输出参数的值放回原参数Map中 |
| | | params.put(paramName, result.get(paramName)); |
| | | outParams.put(paramName, result.get(paramName)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | List<String> outParamsValues = outParams.values().stream() |
| | | .map(value -> value != null ? value.toString() : "null") |
| | | .collect(Collectors.toList()); |
| | | // 返回结果信息 |
| | | return null; |
| | | return outParamsValues; |
| | | } catch (Exception e) { |
| | | return null; |
| | | } |
| | |
| | | /** |
| | | * 调用存储过程 |
| | | * @param procedureName 存储过程名称 |
| | | * @param params 输入参数 |
| | | * @param outParams 输出参数 |
| | | * @param params 参数 |
| | | * @return 存储过程执行结果 |
| | | */ |
| | | List<String> procedureAPI(String procedureName, Map<String, Object> params,Map<String, Object> outParams); |
| | | List<String> procedureAPI(String procedureName, Map<String, Object> params); |
| | | |
| | | } |
| | |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.InputStreamReader; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.*; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | this.api = api; |
| | | this.logicConfig = JsonConversion.jsonToObjectByJackson(ReadFile.readJson(machine.getLogicFile()).toString(), LogicConfig.class); |
| | | this.plcParameters = JsonConversion.jsonToObjectByJackson(ReadFile.readJson(machine.getMachineFile()).toString(), PlcParameters.class); |
| | | this.logicConfig.getLogics(); |
| | | this.plcParameters.Initialization(); |
| | | for (LogicItem logicItem : logicConfig.getLogics()) { |
| | | if (logicItem.getLogicInterval()==0){ |
| | | //默认1000毫秒 |
| | | logicItem.setLogicInterval(1000); |
| | | } |
| | | for (Logic logic : logicItem.getLogic()) { |
| | | logic.setAddress(this.plcParameters.getMap().get(logic.getCodeId()).getAddress()); |
| | | logic.setPlcDataType(this.plcParameters.getMap().get(logic.getCodeId()).getPlcDataType()); |
| | | } |
| | | for (ReturnValue returnValue : logicItem.getReturnValue()) { |
| | | returnValue.setAddress(this.plcParameters.getMap().get(returnValue.getCodeId()).getAddress()); |
| | | returnValue.setPlcDataType(this.plcParameters.getMap().get(returnValue.getCodeId()).getPlcDataType()); |
| | | } |
| | | } |
| | | |
| | | |
| | | switch (machine.getProtocolType().getName()) { |
| | | case "ModbusTcp": |
| | | client = new ModbusTcpClient(machine.getIp(), machine.getPort(), 1); |
| | |
| | | log.error("无效的协议类型: {}", protocolType); |
| | | throw new IllegalArgumentException("无效的协议类型: " + protocolType); |
| | | } |
| | | if (client != null) { |
| | | client.connect(); |
| | | boolean connected = client.isConnected(); |
| | | if (!connected) { |
| | | log.error("连接PLC失败: {}", machine.getIp()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void run() { |
| | | log.info("MachineThread启动,设备IP: {}", machine.getIp()); |
| | | if (client == null || !client.isConnected()) { |
| | | log.error("PLC客户端未连接,线程退出"); |
| | | return; |
| | | } |
| | | |
| | | plcParameters.Initialization(); |
| | | |
| | | try { |
| | | // 初始化读取PLC参数 |
| | | readPlcParameter(); |
| | | } catch (Exception e) { |
| | | log.error("初始化读取PLC参数失败: {}", e.getMessage(), e); |
| | | return; |
| | | } |
| | | // 为每个逻辑项创建并启动子线程 |
| | | //startLogicThread(logicConfig.getLogics().get(0)); |
| | | for (LogicItem logicItem : logicConfig.getLogics()) { |
| | | startLogicThread(logicItem); |
| | | //startLogicThread(logicConfig.getLogics().get(0)); |
| | | } |
| | | |
| | | // 主线程持续运行,定期读取PLC参数并监控连接状态 |
| | | while (running) { |
| | | try { |
| | | // 读取PLC参数,为逻辑处理提供最新数据 |
| | | readPlcParameter(); |
| | | |
| | | // 检查PLC连接状态 |
| | | if (!client.isConnected()) { |
| | | log.warn("PLC连接断开,尝试重新连接"); |
| | | log.info("PLC尝试连接... 设备IP: {}", machine.getIp()); |
| | | tryReconnect(); |
| | | } |
| | | |
| | | // 检查逻辑线程状态,重启已终止的线程 |
| | | // 读取PLC参数,为逻辑处理提供最新数据 |
| | | this.readPlcParameter(); |
| | | plcParameters.Initialization(); |
| | | // 检查逻辑线程状态,开启/重启 线程 |
| | | checkLogicThreadsStatus(); |
| | | |
| | | // 等待下一个执行周期 |
| | | Thread.sleep(mainThreadInterval); |
| | | } catch (InterruptedException e) { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 线程退出前关闭所有资源 |
| | | shutdown(); |
| | | log.info("MachineThread已退出,设备IP: {}", machine.getIp()); |
| | |
| | | |
| | | // 为指定逻辑项创建并启动子线程 |
| | | private void startLogicThread(LogicItem logicItem) { |
| | | String logicId = logicItem.getName(); // 假设每个LogicItem有唯一ID |
| | | String logicId = this.machine.getId()+" - "+this.machine.getName()+" - "+ logicItem.getName(); // 假设每个LogicItem有唯一ID |
| | | if (logicThreads.containsKey(logicId) && logicThreads.get(logicId).isAlive()) { |
| | | log.warn("逻辑项线程已在运行: {}", logicId); |
| | | return; |
| | | } |
| | | |
| | | // 设置运行标志 |
| | | logicRunningFlags.put(logicId, true); |
| | | |
| | | // 创建并启动线程 |
| | | Thread thread = new Thread(() -> { |
| | | log.info("逻辑项线程启动: {}", logicId); |
| | | |
| | | // 逻辑项子线程持续运行的循环 |
| | | while (logicRunningFlags.getOrDefault(logicId, false)) { |
| | | try { |
| | | // 执行实际业务逻辑 |
| | | basicsLogic(logicItem); |
| | | |
| | | // 根据逻辑项的执行频率设置等待时间,默认1000ms |
| | | int logicInterval = 1000; |
| | | Thread.sleep(logicInterval); |
| | | Thread.sleep(logicItem.getLogicInterval()); |
| | | } catch (InterruptedException e) { |
| | | log.info("逻辑项线程被中断,准备退出: {}", logicId); |
| | | logicRunningFlags.put(logicId, false); |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | log.info("逻辑项线程已退出: {}", logicId); |
| | | }); |
| | | |
| | | // 设置线程名称 |
| | | thread.setName("Logic-" + logicId); |
| | | |
| | | thread.setName(logicId); |
| | | // 存储线程引用 |
| | | logicThreads.put(logicId, thread); |
| | | |
| | | // 启动线程 |
| | | thread.start(); |
| | | log.info("已启动逻辑项线程: {}", logicId); |
| | | //log.info("已启动逻辑项线程: {}", logicId); |
| | | } |
| | | |
| | | // 检查逻辑线程状态,重启已终止的线程 |
| | | private void checkLogicThreadsStatus() { |
| | | for (LogicItem logicItem : logicConfig.getLogics()) { |
| | | String logicId = logicItem.getName(); |
| | | String logicId = this.machine.getId()+" - "+this.machine.getName()+" - "+ logicItem.getName(); |
| | | Thread thread = logicThreads.get(logicId); |
| | | |
| | | // 如果线程不存在或已终止且运行标志为true,则重启线程 |
| | | if ((thread == null || !thread.isAlive()) && |
| | | logicRunningFlags.getOrDefault(logicId, false)) { |
| | | log.warn("逻辑项线程已终止,准备重启: {}", logicId); |
| | | if ((thread == null || !thread.isAlive()) &&!logicRunningFlags.getOrDefault(logicId, false)) { |
| | | startLogicThread(logicItem); |
| | | } |
| | | } |
| | |
| | | private void tryReconnect() { |
| | | if (client != null) { |
| | | try { |
| | | log.info("尝试重新连接PLC: {}", machine.getIp()); |
| | | client.disconnect(); |
| | | Thread.sleep(2000); |
| | | client.connect(); |
| | | boolean reconnected = client.isConnected(); |
| | | if (reconnected) { |
| | | log.info("PLC重新连接成功: {}", machine.getIp()); |
| | |
| | | // 关闭线程前的清理工作 |
| | | public void shutdown() { |
| | | running = false; |
| | | |
| | | // 停止所有逻辑线程 |
| | | for (String logicId : logicRunningFlags.keySet()) { |
| | | logicRunningFlags.put(logicId, false); |
| | |
| | | thread.interrupt(); |
| | | } |
| | | } |
| | | |
| | | // 等待所有逻辑线程结束 |
| | | for (String logicId : logicThreads.keySet()) { |
| | | Thread thread = logicThreads.get(logicId); |
| | |
| | | } |
| | | } |
| | | if (isEqual){ |
| | | List<String> result=new ArrayList<>(); |
| | | log.info("满足条件:{}",logicItem.getName()); |
| | | //3.查询此逻辑下需要返回给PLC的数据 result可接收 HTTP接口,视图,存储过程 等 如下 |
| | | try{ |
| | | String connectType=logicItem.getConnectType(); |
| | | String connectAddress=logicItem.getConnectAddress(); |
| | | Map map=new HashMap(); |
| | | switch (connectType) { |
| | | case "Http": |
| | | map.put("method","POST"); |
| | | map.put("plcParameter",plcParameters); |
| | | result= api.httpApi(connectAddress,map); |
| | | log.info("接口返回内容:{}",result); |
| | | break; |
| | | case "View": // 视图/表 |
| | | result= api.viewApi(connectAddress,map); |
| | | break; |
| | | case "Procedure": // 存储过程 |
| | | //result= api.procedureAPI(connectAddress,plcParameter); |
| | | break; |
| | | default: |
| | | log.warn("不支持的连接类型: {}", connectType); |
| | | return; // 不支持的方式 |
| | | List<String> resultWrite=null; |
| | | if (logicItem.getApiConfigBefore()!=null){ |
| | | ApiConfig apiConfig=logicItem.getApiConfigBefore(); |
| | | resultWrite=api.callApi(apiConfig,plcParameters); |
| | | log.info("ApiConfigBefore 外置接口[{}:{}]返回的内容:{}",apiConfig.getType(),apiConfig.getAddress(),resultWrite); |
| | | } |
| | | //写入PLC返回值成功时调用接口 |
| | | if (basicsResult(resultWrite,logicItem.getReturnValue())){ |
| | | ApiConfig apiConfig=logicItem.getApiConfigAfter(); |
| | | if (logicItem.getApiConfigAfter()!=null){ |
| | | List<String> result=api.callApi(apiConfig,plcParameters); |
| | | log.info("ApiConfigAfter 外置接口[{}:{}]返回的内容:{}",apiConfig.getType(),apiConfig.getAddress(),result); |
| | | } |
| | | } |
| | | |
| | | }catch (Exception e){ |
| | | log.error("调用接口失败: {}", e.getMessage(), e); |
| | | } |
| | | //4.返回PLC内容 |
| | | if (result != null&&!result.isEmpty()) { |
| | | basicsResult(result,logicItem.getReturnValue()); |
| | | } |
| | | |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("执行basicsLogic失败: {}", e.getMessage(), e); |
| | |
| | | if (values!=null && !values.equals("")){ |
| | | //还需增添 不同类型调用不同方法 |
| | | switch (itemReturnValue.getPlcDataType()) { |
| | | case "int": |
| | | case "Word": |
| | | client.writeRegister(itemReturnValue.getAddress(),(int)Double.parseDouble(values)); |
| | | break; |
| | | case "string": |
| | | case "String": |
| | | client.writeString(itemReturnValue.getAddress(),values); |
| | | break; |
| | | case "float": |
| | | case "Float": |
| | | client.writeFloat(itemReturnValue.getAddress(),Float.valueOf(values)); |
| | | break; |
| | | case "bit": |
| | | client.writeBit(itemReturnValue.getAddress(),Boolean.valueOf(values)); |
| | | break; |
| | | default: |
| | | log.error("不支持的数据类型: {}", itemReturnValue.getPlcDataType()); |
| | | return false; |
| | | } |
| | | |
| | | } |
| | | } |
| | | return true; |
| New file |
| | |
| | | package com.mes.connect.entity; |
| | | |
| | | |
| | | import lombok.Data; |
| | | import lombok.Getter; |
| | | import lombok.Setter; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Data |
| | | public class ApiConfig { |
| | | private String codeId; |
| | | private String type; |
| | | private String address; |
| | | private Map<String,Object> parameters; |
| | | } |
| | |
| | | public class LogicItem { |
| | | private String name; |
| | | private String sequence; |
| | | private String connectType; |
| | | private String method; |
| | | private String connectAddress; |
| | | private int logicInterval; |
| | | private ApiConfig apiConfigBefore; |
| | | private ApiConfig apiConfigAfter; |
| | | private List<Logic> logic; |
| | | private List<ReturnValue> returnValue; |
| | | @Getter |
| | |
| | | private int port; |
| | | |
| | | /** |
| | | * 端口 |
| | | * 参数文件路径 |
| | | */ |
| | | private String fileUrl; |
| | | /** |
| | | * 参数文件 |
| | | */ |
| | | private String machineFile; |
| | | |
| | | /** |
| | | * 端口 |
| | | * 逻辑文件 |
| | | */ |
| | | private String logicFile; |
| | | |
| | | /** |
| | | * 开关 |
| | | */ |
| | | private String open; |
| | | |
| | | public String getMachineFile(){ |
| | | return this.fileUrl+"\\"+this.machineFile; |
| | | } |
| | | public String getLogicFile(){ |
| | | return this.fileUrl+"\\"+this.logicFile; |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | { |
| | | "parameters": [ |
| | | { |
| | | "serialNumber": 0, |
| | | "content": "PLC请求", |
| | | "codeId": "plcRequest", |
| | | "plcDataType": "Word", |
| | | "fontLocation": 0, |
| | | "length": 2, |
| | | "ratio": 1, |
| | | "scale": 10, |
| | | "address": "S7.DB8.DBW0", |
| | | "remarks": "" |
| | | }, |
| | | { |
| | | "serialNumber": 1, |
| | | "content": "Mes发送字", |
| | | "codeId": "mesSend", |
| | | "plcDataType": "Word", |
| | | "fontLocation": 18, |
| | | "length": 2, |
| | | "ratio": 1, |
| | | "scale": 10, |
| | | "address": "S7.DB8.DBW2", |
| | | "remarks": "" |
| | | }, |
| | | { |
| | | "serialNumber": 2, |
| | | "content": "MES发送长", |
| | | "codeId": "width", |
| | | "plcDataType": "Word", |
| | | "fontLocation": 20, |
| | | "length": 2, |
| | | "ratio": 11, |
| | | "scale": 11, |
| | | "address": "S7.DB8.DBW4", |
| | | "remarks": "" |
| | | }, |
| | | { |
| | | "serialNumber": 11, |
| | | "content": "MES发送宽", |
| | | "codeId": "height", |
| | | "plcDataType": "Word", |
| | | "fontLocation": 22, |
| | | "length": 2, |
| | | "ratio": 12, |
| | | "scale": 12, |
| | | "address":"S7.DB8.DBW6", |
| | | "remarks": "" |
| | | } |
| | | ] |
| | | } |
| New file |
| | |
| | | { |
| | | "logics": [ |
| | | { |
| | | "name":"请求逻辑", |
| | | "sequence":"1", |
| | | "apiConfigBefore": { |
| | | "codeId": "loadSelect", |
| | | "type": "Http", |
| | | "address": "http://localhost:8082/account/testApi", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcRequest", |
| | | "value": [1] |
| | | }, |
| | | { |
| | | "codeId": "mesSend", |
| | | "value": [0] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesSend", |
| | | "fixed": true, |
| | | "value": 1 |
| | | }, |
| | | { |
| | | "codeId": "width", |
| | | "fixed": false, |
| | | "value": 1 |
| | | } |
| | | , |
| | | { |
| | | "codeId": "height", |
| | | "fixed": false, |
| | | "value": 2 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "name":"请求清空", |
| | | "sequence":"2", |
| | | "apiConfigBefore": { |
| | | "codeId": "", |
| | | "type": "View", |
| | | "address": "viewname", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcRequest", |
| | | "value": [0] |
| | | }, |
| | | { |
| | | "codeId": "mesSend", |
| | | "value": [1] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesSend", |
| | | "fixed": true, |
| | | "value": 0 |
| | | }, |
| | | { |
| | | "codeId": "width", |
| | | "fixed": true, |
| | | "value": 0 |
| | | }, |
| | | { |
| | | "codeId": "height", |
| | | "fixed": true, |
| | | "value": 0 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "name":"完成逻辑", |
| | | "sequence":"3", |
| | | "apiConfigBefore": { |
| | | "codeId": "edgSelect", |
| | | "type": "View", |
| | | "address": "viewname", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcComplete", |
| | | "value": [1] |
| | | }, |
| | | { |
| | | "codeId": "mesComplete", |
| | | "value": [0] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesComplete", |
| | | "fixed": true, |
| | | "value": 1 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "name":"完成清空", |
| | | "sequence":"4", |
| | | "apiConfigBefore": { |
| | | "codeId": "edgSelect", |
| | | "type": "View", |
| | | "address": "viewname", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcComplete", |
| | | "value": [0] |
| | | }, |
| | | { |
| | | "codeId": "mesComplete", |
| | | "value": [1,2,3] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesComplete", |
| | | "fixed": true, |
| | | "value": 0 |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| New file |
| | |
| | | { |
| | | "logics": [ |
| | | { |
| | | "name":"请求逻辑", |
| | | "sequence":"1", |
| | | "apiConfigBefore": { |
| | | "codeId": "edgSelect", |
| | | "type": "Procedure", |
| | | "address": "testProcedure", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcRequest", |
| | | "value": [1] |
| | | }, |
| | | { |
| | | "codeId": "mesSend", |
| | | "value": [0] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesSend", |
| | | "address": "S7.DB8.DBW2", |
| | | "fixed": true, |
| | | "value": 1, |
| | | "plcDataType": "int", |
| | | "length": 2 |
| | | }, |
| | | { |
| | | "codeId": "width", |
| | | "address": "S7.DB8.DBW4", |
| | | "fixed": false, |
| | | "value": 1, |
| | | "plcDataType": "int", |
| | | "length": 2 |
| | | } |
| | | , |
| | | { |
| | | "codeId": "height", |
| | | "address": "S7.DB8.DBW6", |
| | | "fixed": false, |
| | | "value": 2, |
| | | "plcDataType": "int", |
| | | "length": 2 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "name":"请求清空", |
| | | "sequence":"2", |
| | | "apiConfigBefore": { |
| | | "codeId": "edgSelect", |
| | | "type": "View", |
| | | "address": "viewname", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcRequest", |
| | | "value": [0] |
| | | }, |
| | | { |
| | | "codeId": "mesSend", |
| | | "value": [1] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesSend", |
| | | "fixed": true, |
| | | "value": 0 |
| | | }, |
| | | { |
| | | "codeId": "width", |
| | | "fixed": true, |
| | | "value": 0 |
| | | }, |
| | | { |
| | | "codeId": "height", |
| | | "fixed": true, |
| | | "value": 0 |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| New file |
| | |
| | | { |
| | | "logics": [ |
| | | { |
| | | "name":"请求逻辑", |
| | | "sequence":"1", |
| | | "apiConfigBefore": { |
| | | "codeId": "edgSelect", |
| | | "type": "View", |
| | | "address": "viewname" |
| | | }, |
| | | "apiConfigAfter": { |
| | | "codeId": "edgSelect", |
| | | "type": "Http", |
| | | "address": "http://localhost:8082/account/testApi", |
| | | "parameters": { |
| | | "method": "POST" |
| | | } |
| | | }, |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcRequest", |
| | | "value": [1] |
| | | }, |
| | | { |
| | | "codeId": "mesSend", |
| | | "value": [0] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesSend", |
| | | "address": "S7.DB8.DBW2", |
| | | "fixed": true, |
| | | "value": 1, |
| | | "plcDataType": "int", |
| | | "length": 2 |
| | | }, |
| | | { |
| | | "codeId": "width", |
| | | "address": "S7.DB8.DBW4", |
| | | "fixed": false, |
| | | "value": 1, |
| | | "plcDataType": "int", |
| | | "length": 2 |
| | | } |
| | | , |
| | | { |
| | | "codeId": "height", |
| | | "address": "S7.DB8.DBW6", |
| | | "fixed": false, |
| | | "value": 2, |
| | | "plcDataType": "int", |
| | | "length": 2 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | "name":"请求清空", |
| | | "sequence":"2", |
| | | "logic":[ |
| | | { |
| | | "codeId": "plcRequest", |
| | | "value": [0] |
| | | }, |
| | | { |
| | | "codeId": "mesSend", |
| | | "value": [1] |
| | | } |
| | | ], |
| | | "returnValue": [ |
| | | { |
| | | "codeId": "mesSend", |
| | | "fixed": true, |
| | | "value": 0 |
| | | }, |
| | | { |
| | | "codeId": "width", |
| | | "fixed": true, |
| | | "value": 0 |
| | | }, |
| | | { |
| | | "codeId": "height", |
| | | "fixed": true, |
| | | "value": 0 |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| | |
| | | username: root |
| | | password: beibo.123/ |
| | | driver-class-name: com.mysql.cj.jdbc.Driver |
| | | salve_JomooKBB: |
| | | url: jdbc:sqlserver://localhost:1433;databasename=JomooKBB |
| | | username: sa |
| | | password: beibo.123/ |
| | | driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver |
| | | # salve_JomooKBB: |
| | | # url: jdbc:sqlserver://localhost:1433;databasename=JomooKBB |
| | | # username: sa |
| | | # password: beibo.123/ |
| | | # driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver |
| | | # salve_JomooKBB: |
| | | # url: jdbc:sqlserver://172.18.19.85:1433;databasename=JomooKBB |
| | | # username: thok |
| | |
| | | cloud: |
| | | nacos: |
| | | discovery: |
| | | server-addr: localhost:8848 |
| | | server-addr: localhost:8849 |
| | | application: |
| | | name: deviceInteraction |
| | | name: plcConnect |
| | | redis: |
| | | database: 0 |
| | | host: localhost |
| | |
| | | server: |
| | | port: 8081 |
| | | port: 8001 |
| | | tomcat: |
| | | uri-encoding: UTF-8 |
| | | max-threads: 800 #最大工作线程数量 |
| | |
| | | mapper-locations: classpath*:mapper/*.xml |
| | | # configuration: |
| | | # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl |
| | | mes: |
| | | threshold: 3 |
| | | ratio: 10 |
| | | max: # 第二条线的最大尺寸信息 |
| | | firstLength: 3500 |
| | | secondLength: 2500 |
| | | min: |
| | | one: #第一条磨边线的最小尺寸信息 |
| | | firstLength: 600 |
| | | secondLength: 350 |
| | | two: #第二条磨边线的最小尺寸信息 |
| | | firstLength: 400 |
| | | secondLength: 300 |
| | | sequence: |
| | | order: false |
| | | |
| | |
| | | String s="白玻"; |
| | | log.info(s); |
| | | } |
| | | @Test |
| | | public void testReadJson() { |
| | | try { |
| | | LogicConfig logicConfig=JsonConversion.jsonToObjectByJackson(ReadFile.readJson("shelfLogic.json").toString(), LogicConfig.class); |
| | | PlcParameters plcParameters=JsonConversion.jsonToObjectByJackson(ReadFile.readJson("shelf.json").toString(), PlcParameters.class); |
| | | log.info("{},{}",logicConfig,plcParameters); |
| | | }catch (Exception e) { |
| | | |
| | | } |
| | | } |
| | | @Test |
| | | public void testReadS7Old() throws IOException { |
| | | S7PLC s7PLC = new S7PLC(EPlcType.S1500, "10.153.19.191", 102, 0, 0); |
| | |
| | | // log.info("{}",resultView); |
| | | |
| | | // 示例 调用testProcedure存储过程 |
| | | // Map<String, Object> params = new HashMap<>(); |
| | | // params.put("dataParmars", "测试数据"); // 输入参数,对应存储过程中的IN参数 |
| | | // Map<String, Object> outParams = new HashMap<>(); |
| | | // outParams.put("messagedate", Types.VARCHAR); // 输出参数,对应存储过程中的OUT参数 |
| | | // String[] resultProcedure = api.procedureAPI("testProcedure", params, outParams); |
| | | // // 打印执行结果 |
| | | // log.info("{}存储过程执行结果:{}",params,resultProcedure); |
| | | Map<String, Object> params = new HashMap<>();// 参数 |
| | | Map<String, Object> inParams = new HashMap<>();// 输入参数 |
| | | Map<String, Object> outParams = new HashMap<>();// 输出参数 |
| | | inParams.put("dataParsers", "测试数据"); |
| | | outParams.put("messageDate", Types.VARCHAR); |
| | | outParams.put("messageDate2", Types.VARCHAR); |
| | | params.put("inParams", inParams); |
| | | params.put("outParams", outParams); |
| | | List<String> resultProcedure = api.procedureAPI("testProcedure", params); |
| | | // 打印执行结果 |
| | | log.info("{}存储过程执行结果:{}",params,resultProcedure); |
| | | } |
| | | @Test |
| | | public void testMainThread() { |