一次获取soapenv:Header请求中的内容的辛酸(kengdie)经历

一次获取soapenv:Header请求中的内容的辛酸经历

写给那些不是很懂webservice请求和http请求的兄dei们


前言

提示:一次涉及接口服务端编写的辛酸历程:
由于开发需要,在springboot项目中我们要写一个webservice请求的服务端,供别人调用。于是我们做出了许多尝试。


提示:以下是本篇文章正文内容,下面案例可供参考

一、webservice是什么?

我通过网上参考别人对webservice接口的表述,理解为是一种不与平台和开发语言相关的一种数据传输方式。webservice请求是以xml文档形式进行发送请求数据,向webservice客户端提供可供调用相关接口方法的API文档。前些年使用的人比较多,现在的新项目使用的相对以前比较少了,所以现在开发webservice请求服务还需要提前做做相关功课。

二、soap协议是什么

soap协议是一种应用程序之间的基于XML的通信协议,与平台和语言无关,常用于webservice请求中进行网络数据通信传输数据。下面举个代码例子

<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
  <soap:Body xmlns:m="http://www.example.org/stock">
    <test>
      <m:nodetest>DEMO</m:nodetest>
    </test>
  </soap:Body>
</soap:Envelope>

三、项目开发历程

最开始产品经理给了我一份Word开发文档,我以为我按照开发文档来应该没什么大问题,我太怜了(弱小无助又可怜),来看请求报文格式

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Header>
		<Esb soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next" soapenv:mustUnderstand="0">
			<Route>
				<TransId></TransId>
				<Version/>
				<AuthCode/>
				<AuthType/>
				<CarryType></CarryType>
				<ServTestFlag></ServTestFlag>
			<EsbId></EsbId></Route>
			<traceId></traceId>
			<sampledFlag>1</sampledFlag>
			<debugFlag>1</debugFlag>
		</Esb>
	</soapenv:Header>
	<soapenv:Body>
		<handler xmlns="http://service.ispp.ztesoft.com/">
		<infType xmlns="">GroupActiveTask</infType>
		<inXML xmlns=""><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<RequestMsg>
……………………
</RequestMsg>]]>
		</inXML>
		</handler>
	</soapenv:Body>
</soapenv:Envelope>

我一看,呦,这不是webservice请求嘛,好家伙,我没有大意啊,我于是啪又开打了开发文档,我一看在这里插入图片描述
好家伙,我没有闪,这一个webservice撞我脸,这产品经理真讲无得,我给他赶忙送几瓶耗子尾汁。于是我开始干活了,代码如下:

1.接收webservice请求的接口

GroupActiveTaskWebService.java

package usi.eip.sys.cxf;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

/**
 * @Classname GroupActiveTaskService
 * @Description TODO
 * @Date 2020/12/9 16:17
 */
@WebService(name = "GroupActiveTask", targetNamespace = "http://service.test.testaaa.com/")
public interface GroupActiveTaskWebService {

    /**
     * @param infType
     * @param inXML
     * @return returns java.lang.String
     */
    @WebMethod
    @WebResult(targetNamespace = "")
    @RequestWrapper(localName = "handler", targetNamespace = "http://service.test.testaaa.com/", className = "usi.eip.sys.cxf.Handler")
    @ResponseWrapper(localName = "handlerResponse", targetNamespace = "http://service.test.testaaa.com/", className = "usi.eip.sys.cxf.HandlerResponse")
    public String groupActiveTask(@WebParam(name = "infType") String infType,
                                    @WebParam(name = "inXML") String inXML);
}

2.接收webservice请求的接口的实现类
GroupActiveTaskWebServiceImpl.java

/**
 * webService接口实现
 *
 */

@WebService(serviceName = "GroupActiveTask", targetNamespace = "http://service.test.testaaa.com/",
        endpointInterface = "cxf.GroupActiveTaskWebService")
public class GroupActiveTaskWebServiceImpl implements GroupActiveTaskWebService {
    // 打印日志
    private static final Logger LOGGER = LoggerFactory.getLogger(GroupActiveTaskWebServiceImpl.class);
    public String groupActiveTask(String infType, String inXML) {
        Document crmDoc = null;
        Document resaleDoc = null ;
        String response = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<ResponseMsg>\n" +
                "\t<RetCode>1</RetCode>\n" +
                "</ResponseMsg>";
        try {
            resaleDoc = DocumentHelper.parseText(inXML);
        } catch (DocumentException e) {
            return response;
        }
        //获取报文处理结果信息
        String accNbr;
        String custOrderId;
        String catChannel;
        String subCatChannel;
        String serviceId;
        String sysId;
        try {
            accNbr = IOMUtils.getNodeValue(resaleDoc,"RequestMsg/PubicVarList/AccNbr");
            custOrderId = IOMUtils.getNodeValue(resaleDoc,"RequestMsg/BusinessInfo/CustOrderId");
            catChannel = IOMUtils.getNodeValue(resaleDoc,"RequestMsg/BusinessInfo/CatChannel");
            subCatChannel = IOMUtils.getNodeValue(resaleDoc,"RequestMsg/BusinessInfo/SubCatChannel");
            serviceId = IOMUtils.getNodeValue(resaleDoc,"RequestMsg/OperatMaintenance/ServiceId");
            sysId = IOMUtils.getNodeValue(resaleDoc,"RequestMsg/SysId");
        }catch (Exception e){
            LOGGER.info("获取节点值异常:",e);
            return response;
        }
        String resultCode = "0";  //消息分析结果:0、成功,1、失败(抛出异常)
        //返回结果
        response = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "\t<ResponseMsg>\n" +
                "\t\t<AccNbr>"+accNbr+"</AccNbr>\n" +
                "\t\t<CustOrderId>"+custOrderId+"</CustOrderId>\n" +
                "\t\t<CatChannel>"+catChannel+"</CatChannel>\n" +
                "\t\t<SubCatChannel>"+subCatChannel+"</SubCatChannel>\n" +
                "\t\t<ServiceId>"+serviceId+"</ServiceId>\n" +
                "\t\t<RetCode>"+resultCode+"</RetCode>\n" +
                "\t</ResponseMsg>";
        return response;
    }
}

3.用于接收请求参数封装的实体类
Handler .java

package usi.eip.sys.cxf;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;

/**
 * <p>
 * Java class for handler complex type.
 * 
 * <p>
 * The following schema fragment specifies the expected content contained within
 * this class.
 * 
 * <pre>
 * &lt;complexType name="handler">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="IsapCopmletionType" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         &lt;element name="inXML" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "handler", propOrder = { "infType", "inXML" })
public class Handler {
	
	protected String infType;
	protected String inXML;

	/**
	 * Gets the value of the isapCopmletionType property.
	 * 
	 * @return possible object is {@link String }
	 * 
	 */
	public String getInfType() {
		return infType;
	}

	/**
	 * Sets the value of the isapCopmletionType property.
	 * 
	 * @param value
	 *            allowed object is {@link String }
	 * 
	 */
	public void setInfType(String value) {
		this.infType = value;
	}

	/**
	 * Gets the value of the inXML property.
	 * 
	 * @return possible object is {@link String }
	 * 
	 */
	public String getInXML() {
		return inXML;
	}

	/**
	 * Sets the value of the inXML property.
	 * 
	 * @param value
	 *            allowed object is {@link String }
	 * 
	 */
	public void setInXML(String value) {
		this.inXML = value;
	}

}

4.相应请求封装的实体类
HandlerResponse .java

package usi.eip.sys.cxf;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

/**
 * <p>
 * Java class for handlerResponse complex type.
 * 
 * <p>
 * The following schema fragment specifies the expected content contained within
 * this class.
 * 
 * <pre>
 * &lt;complexType name="handlerResponse">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="return" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "handlerResponse", propOrder = { "_return" })
public class HandlerResponse {

	@XmlElement(name = "return")
	protected String _return;

	/**
	 * Gets the value of the return property.
	 * 
	 * @return possible object is {@link String }
	 * 
	 */
	public String getReturn() {
		return _return;
	}

	/**
	 * Sets the value of the return property.
	 * 
	 * @param value
	 *            allowed object is {@link String }
	 * 
	 */
	public void setReturn(String value) {
		this._return = value;
	}

}

5.创建webservice服务地址供客户端调用
WebServiceConfig.java

/**
 * webService 配置类
 *
 */
@Configuration
public class WebServiceConfig {
	@Bean
	public Endpoint endpoint() {
		EndpointImpl endpoint = new EndpointImpl(springBus(), webServices());
		// 接口发布
		endpoint.publish("/Services");
		return endpoint;
	}
	@Bean
	public GroupActiveTaskWebService groupActiveTaskWebService() {
		return new GroupActiveTaskWebServiceImpl();
	}

	@Bean
	public WebServices webServices() {
		return new WebServicesImpl();
	}

	@Bean(name = Bus.DEFAULT_BUS_ID)
	public SpringBus springBus() {
		return new SpringBus();
	}
}

开发到这,客户端的请求服务端已经能收到正确的报文了,可是后来产品经理又提了新需求,就是要获取请求中的soapenv:Header里的节点的值。这不是简单嘛,我于是上网各种百度,CSDN,我大意了啊,找了整整两天…没找到这样写的。喊上项目经理一起找资料,,,,,又过去了一天,,,还是没有相关介绍,到这我知道事情肯定没有那么简单了。

最后又过了两天,我偶然看到在项目里别人的代码写的这种请求竟然用了HttpPost发请求。。。他竟然用了HttpPost我真是十万个小马在我内心奔腾。我接着百度搜了一下,说soap只是协议,在http请求中也可以使用此协议。我于是做了一个大胆的决定,用Http服务端接收这个客户端来的不知道什么玩意的请求,直接发到测试环境开测。事实证明,我赌对了,原本一筹莫展的功能摇身一变接收到了所有的报文,我直接一个split三下五除二拿出了所有需要的节点值。至此,我只能感叹一句,开发需求不对接明确就是在间接谋杀程序猿。。还有一句,到一筹莫展的时候不妨坐下歇歇,可能回头看一眼就望见了希望在向你招手。


总结

对待webservice请求和http请求的功能需求,一定要明确开发需求。要是实在无法实现功能,就要怀疑你的开发文档是不是一个假的开发文档了。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值