1. 个人总结
- 使用SpringBoot搭建的Soap webService与webClient项目可以参看我写的另外两篇文章:
(1)webService (2)webClient
但是对于上面两篇文章的Spring-Web-Service搭建和使用过程中,我发现有的时候在接收soap请求时总是那么不尽人意,按照教程可以轻松的通过@RequestPayload实现soap请求到java实体类的映射,但是在个人开发中有的时候会碰到各种意想不到的问题。
对于上面遇到的问题,突然想到如果采用传统的接口方式去接收soap是不是可行,下面将描述我采用传统的接口形式去处理soap请求或者其它xml格式请求的过程。
2. 传统接口形式接收xml请求
- @RequestMapping指定consumes和produces【即:指定请求的数据类型和返回的数据类型】
- 使用JAXB根据xsd文件生成带有XML注解的实体类;
- 如果不想采用自动生成实体类的方式接收入参,可以在接收到xml字符串之后,采用dom4j、JDOM等其它的工具包进行解析处理(这些jar包需要单独引入)
以下是部分代码
package com.qs.parentchild2springbootstudy.util;
import lombok.extern.slf4j.Slf4j;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.*;
/**
* jaxb实体类与xml的映射工具
*
* @author QuS
* @date 2022/3/21 13:52
*/
@Slf4j
public class JaxbXmlUtils {
/**
* 将xml字符串转换成实体类
*
* @param xml 传入的xml字符串
* @param clazz 需要转换的实体类
* @param <T>
* @return
*/
public static <T> T xml2Object(String xml, Class<T> clazz) throws JAXBException {
try {
JAXBContext jc = JAXBContext.newInstance(clazz);
Unmarshaller unmarshaller = jc.createUnmarshaller();
//将xml字符串转换成流
StringReader reader = new StringReader(xml);
return (T) unmarshaller.unmarshal(reader);
} catch (JAXBException e) {
// logger.trace(e);
throw e;
}
}
/**
* 从xml文件中读取xml数据,转换成java实体类
*
* @param dataStream xml格式的文件流
* @param clazz 映射的实体类
* @param <T>
* @return
* @throws JAXBException
*/
public static <T> T xml2Object(InputStream dataStream, Class<T> clazz) throws JAXBException {
try {
JAXBContext jc = JAXBContext.newInstance(clazz);
Unmarshaller u = jc.createUnmarshaller();
return (T) u.unmarshal(dataStream);
} catch (JAXBException e) {
// logger.trace(e);
throw e;
}
}
/**
* 将实体类转换成xml
*
* @param t 传入的实体类
* @param clazz 实体类型
* @param <T>
* @return
* @throws JAXBException
*/
public static <T> String object2Xml(T t, Class<T> clazz) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(clazz);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");
StringWriter writer = new StringWriter();
marshaller.marshal(t, writer);
return writer.toString();
}
}
package com.qs.parentchild2springbootstudy.controller;
import com.alibaba.fastjson.JSONObject;
import com.qs.parentchild2springbootstudy.xml.response.ResponseXML;
import com.qs.parentchild2springbootstudy.xml.test.ROOT;
import com.qs.parentchild2springbootstudy.util.JaxbXmlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.web.bind.annotation.*;
import javax.xml.bind.JAXBException;
import java.io.StringReader;
import java.util.Iterator;
/**
* 解析xml的请求
*
* @author QuS
* @date 2022/3/21 13:35
*/
@Slf4j
@RestController
@RequestMapping(value = "xml")
public class TestXMLPhraseController {
@PostMapping(value = "phrase", consumes = "application/xml", produces = "application/xml")
public ResponseXML phraseXml(@RequestBody String requestXml) throws JAXBException {
log.info("请求参数为:{}", requestXml);
//这里会将requestXml映射成ROOT实体类,此ROOT实体类是用jaxb插件根据xsd文件生成的
System.out.println(JSONObject.toJSONString(JaxbXmlUtils.xml2Object(requestXml, ROOT.class)));
ResponseXML responseXML = new ResponseXML();
responseXML.setCode("0");
responseXML.setMessage("success");
responseXML.setData("成功");
return responseXML;
}
}
3. 根据xml生成xsd的工具
上面提到根据xml自动生成实体类需要借助jaxb, jaxb又需要xsd文件,那么如何将xml文件转换成xsd文件呢?如果自己足够自信,你可以自己手写;如果想偷懒,可以采用工具trang.jar去生成【可以在网络上自行搜索该jar包进行下载,如果找不见,可以在评论区留言,我可以发百度云链接】 执行如下命令即可根据xml生成xsd文件【jar包和xml文件需要在同一个目录下】
java -jar trang.jar xxxxx.xml xxxxx.xsd
5. Soap UI可以在添加WSDL后,然后自动生成soap请求
|