modbus-master-tcp 是一个基于netty的NIO modbus高性能通信库,值得学习
引入Maven库
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zg</groupId>
<artifactId>sboottest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sboottest</name>
<description>Demo project for Spring Boot</description>
<packaging>war</packaging>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-tomcat</artifactId>-->
<!--<version>2.3.7.RELEASE</version>-->
<!--<scope>provided</scope>-->
<!--</dependency>-->
<!--jsp依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!--数据源依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.19</version>
</dependency>
<!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!--javaee规范-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!--引入jstl-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
<!--引入ModbusMaster-->
<dependency>
<groupId>com.digitalpetri.modbus</groupId>
<artifactId>modbus-master-tcp</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
<!--WebService CXF依赖 begin-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
<!--WebService CXF依赖 end-->
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<verbose>false</verbose>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.zg.sboottest.SboottestApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warName>zg</warName>
</configuration>
</plugin>
</plugins>
<!-- 添加资源 -->
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- src/main/resources下的指定资源放行 -->
<includes>
<include>**/*.properties</include>
<include>**/*.yml</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
帮助类的接口
package com.zg.sboottest.commhelper;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
/**
* @Auther: Zg
* @Date: 2022/9/8 - 09 - 08 - 11:33
* @Description: com.zg.sboottest.commhelper
* @version: 1.0
*/
public interface ImodbusHelper {
//String Conn(String Ip, Integer Port) throws IOException;
String Conn() throws IOException;
String DisConn();
byte[] readHoldingRegisters() throws ExecutionException, InterruptedException;
String writeHoldingRegisters(Integer varAddress, Integer value) throws ExecutionException, InterruptedException;
//
// byte[] readHoldingRegisters(int address, int quantity) throws ExecutionException, InterruptedException;
}
帮助类:
package com.zg.sboottest.commhelper;
import com.digitalpetri.modbus.FunctionCode;
import com.digitalpetri.modbus.codec.Modbus;
import com.digitalpetri.modbus.master.ModbusTcpMaster;
import com.digitalpetri.modbus.master.ModbusTcpMasterConfig;
import com.digitalpetri.modbus.requests.ReadHoldingRegistersRequest;
import com.digitalpetri.modbus.requests.WriteSingleRegisterRequest;
import com.digitalpetri.modbus.responses.ModbusResponse;
import com.digitalpetri.modbus.responses.ReadHoldingRegistersResponse;
import com.zg.sboottest.entities.ActualData;
import com.zg.sboottest.entities.MyConfig;
import com.zg.sboottest.entities.VarType;
import io.netty.buffer.ByteBuf;
import io.netty.util.ReferenceCountUtil;
import javafx.scene.input.DataFormat;
import org.apache.tomcat.util.buf.HexUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.core.Converter;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
/**
* @Auther: Zg
* @Date: 2022/9/6 - 09 - 06 - 8:35
* @Description: com.zg.modbusmaster.modbus
* @version: 1.0
*/
@Component
public class ModbusHelper implements ImodbusHelper {
/**
* modubs从站ID
*/
private Integer slaveNo;
/**
* 寄存器数量
*/
private Integer quantity;
/**
* 起始地址
*/
private Integer address;
/**
* 成功代码
*/
public static final String SUCCESS_CODE = "0x000000";
/**
* 与modubs连接异常
*/
public static final String COON_FAIL_CODE = "0x000001";
/**
* 向modubs发送命令执行异常
*/
public static final String EXEC_FAIL_CODE = "0x000002";
/**
* 数据写入失败
*/
public static final String WRITE_FAIL_CODE = "0x000004";
private ModbusTcpMaster modbusTcpMaster;
public List<ActualData> actualDatas;
public List<ActualData> getActualDatas() {
return actualDatas;
}
public void setActualDatas(List<ActualData> actualDatas) {
this.actualDatas = actualDatas;
}
@Autowired
MyJsonConfigTool configTool;
public ModbusTcpMaster getModbusTcpMaster() {
return modbusTcpMaster;
}
@Override
public String Conn() throws IOException {
if (modbusTcpMaster == null) {
MyConfig myConfig = configTool.ReadJson();
actualDatas = myConfig.getActualDatas();
//Ip
String Ip = myConfig.getIp();
//端口
Integer Port = Integer.parseInt(myConfig.getPort());
//从站号
slaveNo = Integer.parseInt(myConfig.getSlaveNo());
//寄存器数量
quantity = actualDatas.size();
//起始地址
address = Integer.parseInt(myConfig.getAddress());
ModbusTcpMasterConfig config = new ModbusTcpMasterConfig.Builder(Ip).setPort(Port).build();
modbusTcpMaster = new ModbusTcpMaster(config);
return SUCCESS_CODE;
}
return COON_FAIL_CODE;
}
@Override
public String DisConn() {
if (modbusTcpMaster != null) {
modbusTcpMaster.disconnect();
}
Modbus.releaseSharedResources();
return SUCCESS_CODE;
}
/**
* @param varAddress 寄存器地址
* @param value 写入值
* @description: 写HoldingRegister数据
* @return: 结果值
*/
@Override
public String writeHoldingRegisters(Integer varAddress, Integer value) throws ExecutionException, InterruptedException {
ModbusResponse modbusResponse;
if (modbusTcpMaster==null){
return null;
}
// 发送单个寄存器数据,一般是无符号16位值:比如10
CompletableFuture<ModbusResponse> future = modbusTcpMaster.sendRequest(new WriteSingleRegisterRequest(varAddress, value), slaveNo);
//获取写入的响应流
modbusResponse = future.get();
if (modbusResponse == null) {
System.out.println("FCSC-ExternalConnection WriteHoldingRegisters:modbusResponse is null ");
return WRITE_FAIL_CODE;
}
//获取写入的响应FunctionCode
FunctionCode functionCode = modbusResponse.getFunctionCode();
System.out.println("FCSC-ExternalConnection functionCode=" + functionCode + " value=" + value);
if (functionCode == FunctionCode.WriteSingleRegister) {
return SUCCESS_CODE;
} else {
return WRITE_FAIL_CODE;
}
}
@Override
public byte[] readHoldingRegisters() throws ExecutionException, InterruptedException {
if (modbusTcpMaster==null){
return null;
}
CompletableFuture<ReadHoldingRegistersResponse> future = modbusTcpMaster
.sendRequest(new ReadHoldingRegistersRequest(address, quantity), slaveNo);
ReadHoldingRegistersResponse readHoldingRegistersResponse = future.get();
if (readHoldingRegistersResponse != null) {
ByteBuf buf = readHoldingRegistersResponse.getRegisters();
byte[] bytes = new byte[buf.capacity()];
buf.readBytes(bytes, 0, buf.capacity());
// System.out.println("bytes=" + Arrays.toString(bytes));
// for (int i = 0; i< bytes.length;i+=2){
// byte temp;
// temp = bytes[i];
// bytes[i]=bytes[i+1];
// bytes[i+1]=temp;
// }
return bytes;
}
ReferenceCountUtil.release(readHoldingRegistersResponse);
return null;
}
// byte数组转short数组
public short[] byteArray2ShortArray(byte[] data) {
short[] retVal = new short[data.length / 2];
for (int i = 0; i < retVal.length; i++)
retVal[i] = (short) ((data[i * 2] & 0xff) << 8 | (data[i * 2 + 1] & 0xff));
return retVal;
}
// short数组转byte数组
public byte[] ShortArray2byteArray(short[] s) {
byte[] targets = new byte[s.length * 2];
for (int i = 0; i < s.length; i++) {
int[] offsets = {0, 8};
targets[i * 2] = (byte) ((s[i] >>> offsets[0]) & 0xff);
targets[i * 2 + 1] = (byte) ((s[i] >>> offsets[1]) & 0xff);
}
return targets;
}
public short bytesToShort(byte[] bytes) {
return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
}
//byte数组转float数组
public float[] byteArray2FloatArray1(byte[] buffer) {
float[] target = new float[buffer.length / 4];
for (int i = 0; i < target.length; i++) {
byte[] tmp_buf = {buffer[i * 4], buffer[i * 4 + 1], buffer[i * 4 + 2], buffer[i * 4 + 3]};
target[i] = ByteBuffer.wrap(tmp_buf).order(ByteOrder.LITTLE_ENDIAN).getFloat();
}
return target;
}
//float数组转byte数组
public byte[] FloatArray2byteArray(float[] buffer) {
byte[] targets = new byte[buffer.length * 4];
for (int i = 0; i < buffer.length; i++) {
int fbit = Float.floatToIntBits(buffer[i]);
targets[i * 4] = (byte) (fbit >> 0);
targets[i * 4 + 1] = (byte) (fbit >> 8);
targets[i * 4 + 2] = (byte) (fbit >> 16);
targets[i * 4 + 3] = (byte) (fbit >> 24);
}
return targets;
}
}
监听:
package com.zg.sboottest.commhelper;
import com.zg.sboottest.entities.ActualData;
import com.zg.sboottest.services.ActualDataService;
import com.zg.sboottest.services.Impl.ActualDataServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;
import static com.zg.sboottest.commhelper.ModbusHelper.SUCCESS_CODE;
import static com.zg.sboottest.commhelper.ScheduleTimeIntervalSets.TASKSTART_LISTHEN_INTERVAL;
/**
* @Auther: Zg
* @Date: 2022/9/8 - 09 - 08 - 16:33
* @Description: com.zg.sboottest.commhelper
* @version: 1.0
*/
@Service
@EnableAsync
public class Listenner {
@Autowired
public ModbusHelper modbusHelper;
@Autowired
public ActualDataService actualDataService;
Boolean last = false;
Boolean trigIn = false;
Boolean trigQ = false;
public String Conn() throws IOException {
String conn = modbusHelper.Conn();
return conn;
}
/**
*
* @Async 异步
* @Scheduled 定时器,定时器1秒
*/
@Async
@Scheduled(cron = "*/1 * * * * *")
public void Listen() throws ExecutionException, InterruptedException {
if (modbusHelper.getModbusTcpMaster()!=null){
byte[] str = modbusHelper.readHoldingRegisters();
short[] shorts = modbusHelper.byteArray2ShortArray(str);
for (int i=0 ; i<modbusHelper.getActualDatas().size(); i++)
{
Double scale = Double.parseDouble(modbusHelper.getActualDatas().get(i).getScale());
Double value_ = scale * shorts[i];
modbusHelper.getActualDatas().get(i).setValue(String.valueOf(value_));
//modbusHelper.actualDatas.get(i).setValue(String.valueOf(shorts[i]));
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));
modbusHelper.getActualDatas().get(i).setCreateTime(now);
}
for (ActualData data :modbusHelper.getActualDatas()
) {
System.out.println("+++++++"+data.getValue()+"============");
}
this.Insert();
}
}
//上升沿插入数据库
public void Insert(){
//变量5的值等于5时候 触发上升沿
trigIn= modbusHelper.getActualDatas().get(4).getValue().equals("5.0");
trigQ = (trigIn & !last);
last = trigIn;
if (trigQ){
InsertDataBase();
}
}
private void InsertDataBase(){
String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));
for (int i=0 ; i<modbusHelper.getActualDatas().size(); i++)
{
modbusHelper.getActualDatas().get(i).setInsertTime(now);
}
Integer i = actualDataService.insertLists(modbusHelper.getActualDatas());
System.out.println("===+++插入数据成功!"+i+"UUU");
}
}
测试:
package com.zg.modbusmaster;
import com.zg.modbusmaster.modbus.ModbusHelper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@SpringBootTest
class ModbusmasterApplicationTests {
@Autowired
private ModbusHelper modbusHelper;
@Test
void contextLoads() throws ExecutionException, InterruptedException {
//ModbusHelper modbusHelper = new ModbusHelper();
modbusHelper.Conn("127.0.0.1",502);
byte[] str = modbusHelper.readHoldingRegisters(0,10,1);
short[] shorts = byteArray2ShortArray(str);
for (short s:shorts
) {
System.out.println("============"+Integer.toString(s)+"============");
}
//写
modbusHelper.writeHoldingRegisters(0,33,1);
}
// byte数组转short数组
public static short[] byteArray2ShortArray(byte[] data) {
short[] retVal = new short[data.length/2];
for (int i = 0; i < retVal.length; i++)
retVal[i] = (short) ((data[i * 2] & 0xff)<< 8 | (data[i * 2 + 1] & 0xff) );
return retVal;
}
// short数组转byte数组
public static byte[] ShortArray2byteArray(short[] s) {
byte[] targets = new byte[s.length*2];
for (int i=0;i<s.length;i++){
int[] offsets = {0,8};
targets[i*2] = (byte) ((s[i] >>> offsets[0]) & 0xff);
targets[i*2+1] = (byte) ((s[i] >>> offsets[1]) & 0xff);
}
return targets;
}
public static short bytesToShort(byte[] bytes) {
return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
}
//byte数组转float数组
public static float[] byteArray2FloatArray1(byte[] buffer) {
float[] target = new float[buffer.length / 4];
for (int i = 0; i < target.length; i++) {
byte[] tmp_buf = {buffer[i * 4] , buffer[i * 4 + 1],buffer[i * 4 + 2],buffer[i * 4 + 3]};
target[i] = ByteBuffer.wrap(tmp_buf).order(ByteOrder.LITTLE_ENDIAN).getFloat();
}
return target;
}
//float数组转byte数组
public static byte[] FloatArray2byteArray(float[] buffer) {
byte[] targets = new byte[buffer.length * 4];
for (int i = 0; i < buffer.length; i++) {
int fbit = Float.floatToIntBits(buffer[i]);
targets[i * 4] = (byte) (fbit >> 0);
targets[i * 4 + 1] = (byte) (fbit >> 8);
targets[i * 4 + 2] = (byte) (fbit >> 16);
targets[i * 4 + 3] = (byte) (fbit >> 24);
}
return targets;
}
}
Controller
package com.zg.sboottest.controller;
import com.zg.sboottest.commhelper.Listenner;
import com.zg.sboottest.commhelper.ModbusHelper;
import com.zg.sboottest.entities.ActualData;
import com.zg.sboottest.entities.Student;
import com.zg.sboottest.services.ActualDataService;
import com.zg.sboottest.services.Impl.ActualDataServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
/**
* @Auther: Zg
* @Date: 2022/9/7 - 09 - 07 - 13:11
* @Description: com.zg.sboottest.controller
* @version: 1.0
*/
@Controller
@CrossOrigin
public class MyController {
@Autowired
Listenner listen;
@Autowired
ModbusHelper modbusHelper;
@Autowired
ActualDataService actImpl;
//
// ConcurrentHashMap<String, Object> map;
// @RequestMapping("/test")
// public String Index(){
// return "redirect:/Views/GL.html";
// }
@RequestMapping("/")
public String Home(){
return "redirect:/Views/Default/Index.jsp";
//return "/Views/Default/Index";
}
@RequestMapping("/test11")
public void Test11(){
System.out.println("=======+++++========");
System.out.println(actImpl.findAll()+"===============");
}
@ResponseBody
@RequestMapping("/JYZSys/GetJYZSysData3")
public List<ActualData> myTest() {
try {
listen.Conn();
} catch (IOException e) {
e.printStackTrace();
}
return modbusHelper.getActualDatas();
}
@PostMapping("modify")
public String ModifyVariable(HttpServletRequest req, HttpServletResponse resp) throws ExecutionException, InterruptedException {
String name = req.getParameter("name");
String value = req.getParameter("value");
System.out.println("变量"+name+"写入成功:"+value);
for (ActualData data: modbusHelper.getActualDatas()
) {
if (name.equals(data.getName())){
modbusHelper.writeHoldingRegisters(Integer.parseInt(data.getVarAddress()),Integer.parseInt(value));
//data.setValue(value);
}
}
//return "redirect:/Views/Home/Index.jsp";
return "redirect:/Views/Home/Index.jsp?codeName=JYZ&index=0";
//return "?codeName=JYZ&index=0";
}
// @RequestMapping("/GetJYZSysData")
// public String GetJYZSysData(HttpServletResponse resp, HttpServletRequest req){
// req.setAttribute("test1","99999");
// return "redirect:/Views/GL.html";
// }
// @RequestMapping("/table")
// public String Table(HttpServletResponse resp, HttpServletRequest req){
// String username = req.getParameter("username");
// String password = req.getParameter("password");
// String realname = req.getParameter("realname");
// System.out.println("================"+username+"================"+password+"================"+realname);
// return "redirect:/Success.jsp";
// }
//
// @RequestMapping("/param")
// public String Param(Student student){
// System.out.println(student.toString());
// return "redirect:/Success.jsp";
// }
//
// @RequestMapping("/rest/{username}/{id}")
// public String TestResful(@PathVariable String username, @PathVariable String id){
// System.out.println("username="+username);
// System.out.println("id="+id);
// return "redirect:/Success.jsp";
// }
//
// @RequestMapping("/test/mav")
// public ModelAndView TestModelAndView(){
// /**
// * ModelAndView包含Model和View的功能
// * Model:向请求域中共享数据
// * View:设置逻辑视图实现页面跳转
// */
// ModelAndView modelAndView = new ModelAndView();
// modelAndView.addObject("testModelAndView","Hello, ModelAndView");
// modelAndView.setViewName("Success");
// return modelAndView;
// }
//
// @RequestMapping("test/model")
// public String TestModel(Model model){
// model.addAttribute("test2","1211212112");
// return "/Views/Index";
// }
//
// @RequestMapping("test/modelMap")
// public String TestModelMap(ModelMap modelMap){
// System.out.println(modelMap.getClass().getName());
// modelMap.addAttribute("TestModelMap","hello,ModelMapvvvvvvvvvvvv");
// return "/Views/Index";
// }
//
// @RequestMapping("/test/map")
// public String TestMap(Map<String,Object> map){
// System.out.println(map.getClass().getName());
// map.put("TestMap","hello,TestMap!vvvvvv");
// return "/Views/Index";
// }
//
// @RequestMapping("/test/session")
// public String TestSession(HttpSession session){
// session.setAttribute("TestSession","hello,TestHttpSession");
// return "Success";
// //return "redirect:/Success.jsp";
// }
//
// @RequestMapping("/test/application")
// public String testApplication(HttpSession session){
// ServletContext servletContext = session.getServletContext();
// servletContext.setAttribute("testApplicationScope", "hello,application");
// return "Success";
// }
}
lombok:下载依赖
并在Setting-Plugins 搜索lombok 下载插件
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
给类加上注解:
package com.zg.lomboktest.entities;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Auther: Zg
* @Date: 2022/9/6 - 09 - 06 - 13:15
* @Description: com.zg.lomboktest.entities
* @version: 1.0
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
public class Demo {
String code;
String name;
}
CXF-WebService
Config
package com.zg.sboottest.webservicecfg;
import com.zg.sboottest.services.MyWSService;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
/**
* @Auther: Zg
* @Date: 2022/9/17 - 09 - 17 - 21:38
* @Description: com.zg.sboottest.webservicecfg
* @version: 1.0
*/
@Configuration
public class CxfConfig {
@Autowired
private Bus bus;
@Autowired
private MyWSService myWSService;
//加上yml中的项目名称zg和cxf的路径ws
//完整:http://127.0.0.1:8080/zg/ws/TbService?wsdl
//jdk生成:
//wsimport -keep -encoding utf-8 -verbose http://127.0.0.1:8080/zg/ws/hello?wsdl
@Bean
public Endpoint TbService() {
EndpointImpl endpoint = new EndpointImpl(bus, myWSService);
endpoint.publish("/TbService");
return endpoint;
}
}
接口:
package com.zg.sboottest.services;
import java.util.concurrent.ExecutionException;
/**
* @Auther: Zg
* @Date: 2022/9/17 - 09 - 17 - 21:39
* @Description: com.zg.sboottest.services
* @version: 1.0
*/
public interface MyWSService {
String getNameAllData(String getData);
String SetValue(String varName, String varValue) throws ExecutionException, InterruptedException;
}
实现:
package com.zg.sboottest.services.Impl;
import com.zg.sboottest.commhelper.ModbusHelper;
import com.zg.sboottest.entities.ActualData;
import com.zg.sboottest.services.MyWSService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import java.util.concurrent.ExecutionException;
/**
* @Auther: Zg
* @Date: 2022/9/17 - 09 - 17 - 21:44
* @Description: com.zg.sboottest.services.Impl
* @version: 1.0
*/
@Service
@WebService
public class MyWSServiceImpl implements MyWSService {
@Autowired
ModbusHelper modbusHelper;
@WebMethod
@WebResult(name = "reslutAllVar")
@Override
public String getNameAllData(@WebParam(name = "WebParamGetData") String getData) {
if (getData.equals("getData")){
return modbusHelper.getActualDatas().toString();
}
return null;
}
@Override
public String SetValue(@WebParam(name = "WebParamVarName") String varName, @WebParam(name = "WebParamVarValue") String varValue) throws ExecutionException, InterruptedException {
String name = varName;
String value = varValue;
for (ActualData data: modbusHelper.getActualDatas()
) {
if (name.equals(data.getName())){
modbusHelper.writeHoldingRegisters(Integer.parseInt(data.getVarAddress()),Integer.parseInt(value));
//data.setValue(value);
return "success!!";
}
}
return "failed!!";
}
}
对一个项目用多个配置:
application.yml
spring:
profiles:
active: test # level: error
application-test.yml:
## 应用名称
#spring.application.name=sboottest
## 应用服务 WEB 访问端口
#server.port=8080
# 应用名称
# 应用服务 WEB 访问端口
server:
port: 8080
servlet:
#context-path: / #项目名称 8080后加的
context-path: /zg #项目名称 8080后加的
jsp:
init-parameters:
development: true #热部署
spring:
mvc:
view:
prefix: / #/ems/
suffix: .jsp
application:
name: zg #微服务用
#遇到相同类名覆盖注册
main:
allow-bean-definition-overriding: true
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/robots?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 123456
# 集成cxf,默认:cxf.path=/services
cxf:
path: /ws
mybatis:
configuration:
map-underscore-to-camel-case: true
mapper-locations: classpath:com/zg/sboottest/dao/*.xml #mapper配置文件的位置
type-aliases-package: com.zg.sboottest.entities