有一个需求: 要求根据设备 Mac 和终端设备类型来查询设备库存状态.
接口协议是采用 webservice 协议, 信息交互方式为 xml 格式信息
输入参数存放到 xml 各个节点下, 并转为一个 String, 作为接口的输入参数. xml 的封装格式如下所示:
- <?xml version="1.0" encoding="UTF-8"?>
- <ROOT>
- <MSG_CONTENT>
- <DEVICE_MAC></DEVICE_MAC>
- <DEVICE_TYPE></DEVICE_TYPE>
- </MSG_CONTENT>
- </ROOT>
输出参数存放到 xml 各个节点下, 并转为一个 String, 作为接口的输出参数. xml 的封装格式如下所示:
- <?xml version="1.0" encoding="UTF-8"?>
- <ROOT>
- <RESULT_CODE > 返回编码 </RESULT_CODE>
- <RESULT_MSG > 失败描述 </RESULT_MSG>
- <STATE > 终端状态 </STATE>
- <IS_EXIST > 终端是否存在 </IS_EXIST>
- <OWNER_CITY > 终端归属地市 </OWNER_CITY>
- </ROOT>
webservice 也就是 Web 服务, 是一种跨平台跨语言的服务, 类似就是一个第三方的服务, 你写好接口让别人来调用, 你是提供服务的一方. 接口都是用来提供服务的, 接口就是一组功能的集合.
在 java 中写 webservice 接口, 需要在接口类上标注 @WebService 注解, 表明这是一个 webservice,@WebParam(name = "DEVICE_MAC") 这个注解标注在方法参数上, 表示获取的参数, 注释用于定制从单个参数至 Web Service 消息部件和 xml 元素的映射.
例如:
- @WebService
- public interface qryIptvStateService {
- // 根据设备 Mac 和设备类型查询库存状态信息
- String qryIptvState(@WebParam(name = "DEVICE_MAC") String DEVICE_MAC);
- }
现在实现这个接口
endpointInterface: 服务接口全路径, 指定做 SEI(Service EndPoint Interface) 服务端点接口
serviceName: 表示对外发布的服务名 (也就是接口文档中的方法名), 指定 Web Service 的服务名称: wsdl:service. 缺省值为 Java 类的简单名称 + Service.
- @WebService(endpointInterface = "intf.zznode.device.qryIptvStateService", serviceName = "qryIptvState")
- public class qryIptvStateServiceImpl extends BaseService implements qryIptvStateService {
- @Override
- public String qryIptvState(String xml) {
- // 业务代码
- }
- }
现在开始使用 java 构建 xml 文档节点
例如要构建这样结构的 xml 文档
- <ROOT>
- <MSG_CONTENT>
- <DEVICE_MAC>
- </DEVICE_MAC>
- <DEVICE_TYPE>
- </DEVICE_TYPE>
- </MSG_CONTENT>
- </ROOT>
主要的作用就是便于 java 对象与 xml 文件节点元素之间的转换
@XmlRootElement(name = "ROOT") 将这个注解标注在 java 类上, 表示这个是 xml 文档的根元素, 名字为 ROOT.
- @XmlRootElement(name = "ROOT")
- public class ROOTStoreInfo {
- //root 下面的 msg_content 元素
- private StoreMsgContent MSG_CONTENT;
- //setter/getter 方法
- }
- public class StoreMsgContent {
- private String DEVICE_MAC;
- private String DEVICE_TYPE;
- //setter/getter 方法
- }
最终构建出来的 xml 文档为
- <ROOT>
- <MSG_CONTENT>
- <DEVICE_MAC></DEVICE_MAC>
- <DEVICE_TYPE></DEVICE_TYPE>
- </MSG_CONTENT>
- </ROOT>
- // 最后需要将传入的 xml 格式的字符串映射解析为 java 类
- public static <T> T xml2Object(String xmlStr, Class<T> c) {
- try {
- // JAXB(即 Java Architecturefor xml Binding) 是一个业界的标准,
- // 即是一项可以根据 xml Schema 产生 Java 类的技术.
- // 该过程中, JAXB 也提供了将 xml 实例文档反向生成 Java 对象树的方法,
- // 并能将 Java 对象树的内容重新写到 xml 实例文档.
- JAXBContext context = JAXBContext.newInstance(c);
- Unmarshaller unmarshaller = context.createUnmarshaller();
- T t = (T) unmarshaller.unmarshal(new StringReader(xmlStr));
- return t;
- } catch (JAXBException e) {
- e.printStackTrace();
- return null;
- }
- }
现在能够实现用 java 类构建 xml 格式的文档节点信息, 并且能将传入的字符形式的 xml 格式数据映射为标注了 @XmlRootElement 的类.
现在需要将操作结果返回.
- // 用于响应返回的 xml 文档信息
- //@XmlType 注解 propOrder 的值是一个字符串数组, 用来设置 xml 文档节点的顺序
- @XmlRootElement(name = "ROOT")
- @XmlType(propOrder = {"RESULT_CODE", "RESULT_MSG", "STATE", "IS_EXIST", "OWNER_CITY","OTT_STB_ID"})
- public class ROOTStoreInfoRespone {
- private String RESULT_CODE;// 返回编码: 1 成功, 0 失败
- private String RESULT_MSG;// 失败描述, RESULT_CODE 为 0 必填
- private String STATE;// 终端设备状态, RESULT_CODE 为 1 必填
- private String IS_EXIST;// 终端设备是否存在: 1 存在, 0 不存在
- private String OWNER_CITY;// 终端归属地市, IS_EXIST 为 1 时必填
- private String OTT_STB_ID;//OTT 序列号 sn
- //setter/getter 方法
- }
- // 用于将 java 类转换为 xml 格式
- public static String getXml(ROOTStoreInfoRespone root) {
- StringWriter wr = new StringWriter();
- try {
- //JAXBContext 将 java 类与 xml 文档相互转换
- JAXBContext context = JAXBContext.newInstance(ROOTStoreInfoRespone.class);
- // 使用 Marshaller 生成 xml 文件
- Marshaller mar = context.createMarshaller();
- // 格式化 xml 格式
- mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
- // 去掉生成 xml 的默认报文头
- // mar.setProperty(Marshaller.JAXB_FRAGMENT, true);
- mar.marshal(root, wr);
- return wr.toString().replace("standalone=\"yes\"","");
- } catch (JAXBException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
- // 调用
- getXml(rootStoreInfoRespone)
总结:
java 写 webservice 部分
@WebService 注解用于标注一个接口类, 表示这是一个 webservice.
@WebParam(name = "DEVICE_MAC") 注解用于标注参数, 这个参数和传入的 xml 节点元素名相同, 值为这个节点的值.
@WebService(endpointInterface = "intf.zznode.device.qryIptvStateService", serviceName = "qryIptvState") 用于标注在实现了 webservice 接口的实现类上.
endpointInterface 表示接口类的全路径, serviceName 表示对外提供的 webservice 方法名称.
java 构建和解析 xml 部分
@XmlRootElement(name = "ROOT") 将这个注解标注在 java 类上, 表示这个是 xml 文档的根元素, 名字为 ROOT. 这个类里面的属性即为 xml 中的节点元素.
@XmlType(propOrder = {"RESULT_CODE", "RESULT_MSG", "STATE", "IS_EXIST", "OWNER_CITY","OTT_STB_ID"}) 表示是 xml 类型.
propOrder 是一个字符数组, 表示的是 xml 中节点元素的先后顺序.
xml 格式的字符串映射为 java 类
将 java 类解析为 xml 文档格式.
主要是这次开发任务做了一个这样的需求, 特此记录一下, 对于 webservice 还不是很熟悉, 还需要加强学习.
来源: http://www.bubuko.com/infodetail-3289692.html