做了一个webservice提供给别人使用,但是中间用到了,esb做路由中转,
而esb对返回的soap报文有特定的格式要求(如下),
但是.net返回的soap报文做了部分封装,有一些格式是提前定义好的,不可以再修改。
问题就是在.net返回 的soap报文封装好的节点中,我们需要做一些符合esb规范的自定义。
查资料一直也没实现,明天就必须要测试了,大神指点!
项目要求报文格式:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:ns1="http://***********WorkOrder/v1" xmlns:ns3="http://******************WorkOrder/schema" xmlns:ns2="http://esb.******.com">
<ns1:workOrderAuditResponse>
<ns2:replyInformation> //replyInformation节点的内容必须存在,切按照esb规范
<ns2:responseType></ns2:responseType>
<ns2:responseCode></ns2:responseCode>
</ns2:replyInformation>
<ns3:responseDataXml>
<ns3:returnCode></ns3:returnCode>
<ns3:returnDesc></ns3:returnDesc>
</ns3:responseDataXml>
</ns1:workOrderAuditResponse>
</soap:Body>
</soap:Envelope>
现在返回报文格式:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance">
<soap:Body>
<workOrderAuditResponse xmlns="http://is.service.pccc.bankcomm.com/abstraction/atomic/pccc.is.ISBpWorkOrder/V1">
<replyInformation xmlns="http://esb.pccc.bankcomm.com">
<responseType>N</responseType> //这里不知道该如何进行soap返回报文自定义,所以不符合规范
<responseCode>0000000</responseCode>
<responseDataXml>
<returnCode>000003</returnCode>
<returnDesc>noins</returnDesc>
</responseDataXml>
</replyInformation>
</workOrderAuditResponse>
</soap:Body>
</soap:Envelope>
我们也用过完全通过拼接字符串,然后用Context.Response的方式返回给esb,这样虽然格式是正确的,但是esb那边却一直报错“Illegal character‘D’ at line 15”,说在15行(报文最后一行即:</soap:Envelope>)有非法字符'D',但是我们排查了一下,也没发现问题。
以上两种方法,接口在本地是可以直接访问,返回内容页正确,但是放到esb路由中转就会报错。
明天就要用了,加班到现在也没解决,求大神指点
我的主机是windows2008 r2 ,esb那边不是windows机器,虽然编码设置utf-8,但是不同系统编码是否有影响?
已经解决,解决方法如下。
1.首先使用字符串拼接出来自定义的返回报文格式data。
2.使用如下方法输出
Context.Response.ContentEncoding = System.Text.Encoding.UTF8;
Context.Response.ContentType = "text/xml";
Context.Response.Write(data);
Context.Response.Flush();
Context.Response.End();
我们也用过完全通过拼接字符串,然后用Context.Response的方式返回给esb,这样虽然格式是正确的
这个思路是可以的,注意构造的时候XML的需要转意的字符。
现在我们是:一直报错“Illegal character‘D’ at line 15”,说在15行(报文最后一行即:</soap:Envelope>)有非法字符'D',但是我们排查了一下,也没发现问题。
@SunPanda: 最后返现是输出的时候,没有进行结束,完整输出代码如下。
#region 输出xml格式报文到界面
private void ResponseWrite(string data)
{
try
{
Context.Response.ContentEncoding = System.Text.Encoding.UTF8;
Context.Response.ContentType = "text/xml";
Context.Response.Write(data);
Context.Response.Flush();
}
catch (Exception ex)
{
App.Diagnostics.TraceLog.Write(DateTime.Now + "=======输出XML格式报文失败!错误信息:" + ex.Message + "\r\n");
string errorData = ResponseXml("", "000008", "IS系统异常");
Context.Response.ContentEncoding = System.Text.Encoding.UTF8;
Context.Response.ContentType = "text/xml";
Context.Response.Write(errorData);
Context.Response.Flush();
}
finally
{
try
{
Context.Response.End();
}
catch
{
Console.WriteLine("response end");
}
}
}
#endregion
直接使用系统生成的不可以吗?
你的这个需求也曾想过,毕竟自动的soap有点复杂,但我从没去实践过。
给你个建议:从attribute着手,应该是一个解决方案。
自动生成的格式不符合项目要求,所以需要自定义一些格式。
谢谢。
@SunPanda: 理论上是没有影响,但最好调试一下。
确认一下,是请求报文,还是你的WebService返回的报文?
是我要返回的报文。
有对webservice返回的报文做过扩展么?谢谢。
@SunPanda: 只实现过请求报文定制格式的,采用WebRequest模拟,你这种返回报文,应该可以采取同样的方式处理。
@幻天芒: 哦,有相关文章或者范例么?
@SunPanda: WebService它也是一个http请求,你那fiddle监视下请求报文,然后构造这样的Web请求来模拟,就可以了。这是请求的做法,如果是返回的话,我想也可以在接受到请求后,自定义一个xml,然后返回。当然,这个就不算是WebService了。
没写过自定义格式的,长知识了。
已经解决,解决方法如下。
1.首先使用字符串拼接出来自定义的返回报文格式data。
2.使用如下方法输出
Context.Response.ContentEncoding = System.Text.Encoding.UTF8;
Context.Response.ContentType = "text/xml";
Context.Response.Write(data);
Context.Response.Flush();
Context.Response.End();
供ESB调用的接口:
可以这样获得ESB的调用参数
public void workOrderDispatch(
[XmlElement(Namespace = "http://is.service.aaa.bbb.com/abstraction/atomic/ddd.is.ccc/schema")]
string version,
[XmlElement(Namespace = "http://is.service.aaa.bbb.com/abstraction/atomic/ddd.is.ccc/schema")]
string customerName,
[XmlElement(Namespace = "http://is.service.aaa.bbb.com/abstraction/atomic/ddd.is.ccc/schema")]
string documentType,
[XmlElement(Namespace = "http://is.service.aaa.bbb.com/abstraction/atomic/ddd.is.ccc/schema")]
string document,
[XmlElement(Namespace = "http://is.service.aaa.bbb.com/abstraction/atomic/ddd.is.ccc/schema")]
string mobile,
[XmlElement(Namespace = "http://is.service.aaa.bbb.com/abstraction/atomic/ddd.is.ccc/schema")]
string contactPhone,
[XmlElement(Namespace = "http://is.service.aaa.bbb.com/abstraction/atomic/ddd.is.ccc/schema")]
string description,
)
{
逻辑代码。。。。
}
发送给ESB报文,并接收返回信息:
#region 发送报文
public static string SendToESB(string requestDataXml)
{
Stream requestStream = null;
HttpWebRequest httpReq;
try
{
Uri requestUri = new Uri("http://esb的IP地址加端口号:2801");
httpReq = (HttpWebRequest)WebRequest.Create(requestUri);
httpReq.Method = "POST";
httpReq.ContentType = "text/plain";
byte[] bytes = Encoding.UTF8.GetBytes(requestDataXml);
httpReq.ContentLength = bytes.Length;
requestStream = httpReq.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Flush();
requestStream.Close();
HttpWebResponse response = null;
StreamReader reader = null;
response = (HttpWebResponse)httpReq.GetResponse();
var responseStream = response.GetResponseStream();
reader = new StreamReader(responseStream, Encoding.UTF8);
var s = reader.ReadToEnd();
return s;
}
catch (Exception ex)
{
return ex.ToString();
}
}
#endregion
mark
楼主,请问你这个问题怎么解决的?可以请教你一下吗?谢谢了,我的QQ:429870776
麻烦楼主指点一下,非常感谢!
手工拼接好符合规则的xml字符串,然后用post的方式提交给esb服务器。
看看最近有一篇文章也写的很详细,你可以看一下。
http://www.cnblogs.com/huangzelin/p/4550076.html
我也是C#模拟调用java cxfwebservice的开始用的web引用的方式 自己构造的soapheader 但是里面有一些esb规范的格式 没办法用c#类库构造