当前位置: 首页 > news >正文

SpringBoot调用WebService的实践

作者所在公司的系统间的信息交互是通过webservice完成。如:MES与SAP的交互,MES与WMS的交换,MES与SRM的交互,MES与IOT的交互等。

MES是用.NET VS2008 C#写的,调用webservice很简单,这里不再赘述。如有想了解的,可以私信作者。

此篇文章主要介绍IOT平台的怎么调用webservice。

作者所在公司的IOT平台是基于SpringBoot框架开发的。

环境要求(仅参考,可能别的版本也行,只是作者本次用的是以下版本):

工具版本
Java-jdk

java version "1.8.0_161"

Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
ideaIntelliJ IDEA 2019.2以上
git2.30及以上
Mavenapache-maven-3.6.3

SpringBoot框架不再赘述了,作者另一篇文章有做入门介绍,本篇文章主要写java的SpringBoot架构如果调用webservice(XML)

SpringBoot学习笔记-CSDN博客

1.先决条件

依赖引用:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>

2.结构创建

Bean类中创建与soapui中结构相同的请求类和返回类。

注意:如果XML中的字段名称与Java类中的字段名称不同,要用到以下几个注解。

@XmlRootElement(name = "XML根节点名称")

@XmlElementWrapper(name = "XML中LIst节点名称")
@XmlElement(name = "XML中普通节点名称")

这些注解可以帮助SpringBoot结构将XML中的字段反射到Java类中的字段。

3.写Controller

Controller层没什么特别的,正常写就行,因为传入参数是json,所以用PostMapping的方法

4.写Service层

Service层的接口,也正常写就行,返回一个MESResponse类型的对象

重点是Service的实现层

整体思路:通过xml调用MES系统提供的服务,将MES系统返回的信息流先转换成字符串,再反射到java的对象中。

下面贴上实现层的代码供大家参考:

package com.zjtc.qmsquality.FPYData.service;import com.google.common.io.CharStreams;
import com.zjtc.qmsquality.FPYData.Util.EntityUtil;
import com.zjtc.qmsquality.FPYData.bean.MESRequest;
import com.zjtc.qmsquality.FPYData.bean.MESRsp;
import org.springframework.stereotype.Service;import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;@Service
public class FPYDataServiceImpl implements FPYDataService{public static final String targetUrl = "http://172.18.3.67:8020/MesFrameWork.asmx?wsdl"; //测试@Overridepublic MESRsp getFPYData(String no){//调用MES接口查询数据MESRsp mesResponse = new MESRsp();try {MESRequest mesRequest = new MESRequest();mesRequest.setNo(no);mesResponse = sendMessage(no);} catch (Exception e) {mesResponse.setResult("NG");mesResponse.setMessage(e.toString());}return mesResponse;}public static String getDataFromMESSystem(String no,int rflag)  {// 根据上面的XSDL文档封装请求参数String strParameter = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:dev=\"http://device.service.moresoft.com/\">\n" +"<soapenv:Header/>\n" +" <soapenv:Body>\n" +" <dev:IOTTOMES>\n" +"<dev:resBody>\n" +"<dev:rFlag>"+rflag+"</dev:rFlag>\n" +"  <dev:NO>" + no + "</dev:NO>\n\n" +" </dev:resBody>\n" +" </dev:IOTTOMES>\n" +"</soapenv:Body>\n" +"</soapenv:Envelope>";System.out.println("strParameter : " + strParameter);return strParameter;}public static MESRsp sendMessage(String no) throws Exception {try {URL url = new URL(targetUrl);OutputStreamWriter wr = null;HttpURLConnection conn = (HttpURLConnection) url.openConnection();String data = getDataFromMESSystem(no,2);System.out.println("data : " + data);conn.setRequestProperty("Content-Length", String.valueOf(data.getBytes().length));conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8");conn.setDoOutput(true);conn.setConnectTimeout(1000 * 20);conn.setReadTimeout(1000 * 20);if(data!=null && data.toString().trim().length()>0){wr = new OutputStreamWriter(conn.getOutputStream(),"UTF-8");wr.write(data);wr.flush();}String result = CharStreams.toString(new InputStreamReader(conn.getInputStream(), "utf-8"));System.out.println("result : " + result);String xml=analyzeResult(result);System.out.println("xml : " + xml);MESRsp mesResponse= EntityUtil.xml2Entity(xml,MESRsp.class);System.out.println("mesResponse.result : " + mesResponse.getResult());System.out.println("mesResponse.Message : " + mesResponse.getMessage());System.out.println("getFpyDataList : " + mesResponse.getFpyDataList());return mesResponse;} catch (Exception ex) {MESRsp mesResponse=new MESRsp();mesResponse.setResult("NG");mesResponse.setMessage(ex.toString());if(mesResponse.getMessage()!=null&&mesResponse.getMessage().startsWith("java.net.SocketTimeout")){mesResponse.setMessage("接口超时");}return  mesResponse;}}public static String analyzeResult(String result) throws Exception {int fromStr=result.indexOf("<IOTTOMESResult>");int toStr=result.indexOf("</IOTTOMESResponse>",fromStr);String xml=result.substring(fromStr,toStr);return  xml;}}

对了,关于这段XSDL的文档,参考soapui中的自动生成的xml文档。(直接复制粘贴上去就行,要什么参数,就填什么参数)

5.建字符串反射到java类的方法

按步骤写完第四步的朋友,应该会发现EntityUtil类不存在的报错【狗头保命】,不要紧,接下来咱们来贴上这个类的代码就好了。作者也是抄的,不过这个类不错,以后就是大家的了。

package com.zjtc.qmsquality.FPYData.Util;import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;public class EntityUtil {public static String entity2Xml(Object entity) throws JAXBException {JAXBContext context = JAXBContext.newInstance(new Class[]{entity.getClass()});Marshaller marshaller = context.createMarshaller();marshaller.setProperty("jaxb.formatted.output", true);marshaller.setProperty("jaxb.fragment", true);StringWriter sw = new StringWriter();marshaller.marshal(entity, sw);String xml = sw.toString();return xml;}public static <T> T xml2Entity(String xml, Class<T> c) throws JAXBException {T t = null;JAXBContext context = JAXBContext.newInstance(c);Unmarshaller unmarshaller = context.createUnmarshaller();t = (T) unmarshaller.unmarshal(new StringReader(xml));
//        System.out.println("12312312a: " + t.toString());return t;}public static <T> List<T> resultToList(ResultSet resultSet, Class<T> clazz) throws IllegalAccessException, InstantiationException, SQLException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {//创建一个 T 类型的数组List<T> list = new ArrayList<>();try {//通过反射获取对象的实例T t = clazz.getConstructor().newInstance();//获取resultSet 的列的信息ResultSetMetaData metaData = resultSet.getMetaData();//遍历resultSetwhile (resultSet.next()) {//遍历每一列for (int i = 0; i < metaData.getColumnCount(); i++) {//获取列的名字String fName = metaData.getColumnLabel(i + 1);//因为列的名字和我们EMP中的属性名是一样的,所以通过列的名字获得其EMP中属性Field field = clazz.getDeclaredField(fName.toLowerCase());//因为属性是私有的,所有获得其对应的set 方法。set+属性名首字母大写+其他小写String setName = "set" + fName.toUpperCase().substring(0, 1) + fName.substring(1).toLowerCase();//因为属性的类型和set方法的参数类型一致,所以可以获得set方法Method setMethod = clazz.getMethod(setName, field.getType());//执行set方法,把resultSet中的值传入emp中,  再继续循环传值setMethod.invoke(t, resultSet.getObject(fName));}//把赋值后的对象 加入到list集合中list.add(t);}} catch (Exception e) {e.printStackTrace();throw e;}// 返回listreturn list;}public static <T> List<T> convertObjectToList(Object object, Class<T> clazz) {Field[] fields = object.getClass().getDeclaredFields();List<T> list = new ArrayList<>();try {for (Field field : fields) {field.setAccessible(true);Object fieldValue = field.get(object);if (fieldValue instanceof List<?>) {list.addAll((List<T>) fieldValue);}}} catch (IllegalAccessException e) {e.printStackTrace();}return list;}
}

这个类笔者是作为公共类单独建了个Util软件包专门放的,大家可以参考。

6.运行项目,测试结果。

到这里,代码就基本完成了,可以运行一下代码,测试一下有没有其他问题,遇到问题解决问题就是了。

ps:作者一开始遇到了获取xml成功,但是反射成java类死活不成功的问题,原因是没用对注解:XmlElementWrapper(name = "XML中LIst节点名称")

后面加上这个注解之后就愉快的跑成功了。

下面附上运行成功和测试成功的截图:

以下就是SpringBoot中调用Webservice(XML)的一个简单实践。如有疑问,欢迎私信骚扰。

http://www.lryc.cn/news/371387.html

相关文章:

  • 源码编译构建LAMP
  • 搜索是门艺术,大神都是这样找资源
  • 【设计模式深度剖析】【5】【行为型】【迭代器模式】
  • 怎么更快捷的修改图片大小?压缩图片jpg、png、gif的快捷方法
  • Shell脚本 if语句
  • 集合查询-并(UNION)集运算、交(INTERSECT)集运算、差(EXCEPT)集运算
  • 常用的bit位操作
  • 自动控制原理【期末复习】(二)
  • 机器学习——集成学习和梯度提升决策树
  • MYSQL 查看SQL执行计划
  • ARM-V9 RME(Realm Management Extension)系统架构之系统安全能力的MPAM
  • cuda 架构设置
  • 基于 Vue 3 封装一个 ECharts 图表组件
  • LeetCode 算法: 旋转图像c++
  • Java Android 静态内部类 以及优雅实现单例模式/避免handler内存泄漏
  • Flink协调器Coordinator及自定义Operator
  • C调用C++中的类
  • NFTScan 正式上线 Sei NFTScan 浏览器和 NFT API 数据服务
  • 2024年高考:计算机相关专业前景分析与选择建议
  • SQL聚合函数---汇总数据
  • webpack5新特性
  • java单体服务自定义锁名称工具类
  • 整理好了!2024年最常见 20 道并发编程面试题(四)
  • 持续交付一
  • 基于 Python 解析 XML 文件并将数据存储到 MongoDB 数据库
  • Interview preparation--案例加密后数据的模糊查询
  • 一个简单的R语言数据分析案例
  • springCloudAlibaba之分布式事务组件---seata
  • 无公网IP与服务器完成企业微信网页应用开发远程调试详细流程
  • CSS 字体颜色渐变