我使用RESTFull WebService API(BOBJ 4.1)来检索有关存储库中报告的信息。
当我尝试派生数据提供者列表时,它适用于大多数报告的文件。但是,对于某些报告,我收到了“(404)未找到”消息。我感谢这是对没有任何数据提供者的报告的有效响应,但我确信我收到404消息的报告肯定有一个或多个数据提供者。我也不希望它与权限相关,因为我没有收到“拒绝访问”消息,我可以使用Rich Client打开“有问题”的报告。
我使用以下链接:
http://{servername}:{port}/biprws/raylight/v1/documents/{reportID}/dataproviders
以前有没有人遇到过这种问题?我错过了什么吗?
答案 0 :(得分:1)
我遇到了一些BO REST服务的问题(其中一些服务在我们重新启动服务器后就消失了。)
您没有说明您使用哪种技术来调用Web服务,但这里是您如何在C#应用程序中获取错误信息。
在我的C#应用程序中,下面是我用来调用GET& POST Business Objects 4.x REST服务,如果出现问题,它会尝试读取错误消息,因此我们得到的不仅仅是“404 not found”或“503 Server error”......
要使用这些功能,您必须已登录BO并获得登录令牌。
protected string CallGETWebService(string URL, string token)
{
HttpWebRequest GETRequest = null;
try
{
GETRequest = (HttpWebRequest)WebRequest.Create(URL);
GETRequest.Method = "GET";
GETRequest.Accept = "application/xml";
GETRequest.Timeout = 3 * 60 * 1000; // Wait for upto 3 minutes
GETRequest.KeepAlive = false;
GETRequest.Headers.Add("X-SAP-LogonToken", token);
HttpWebResponse GETResponse = (HttpWebResponse)GETRequest.GetResponse();
Stream GETResponseStream = GETResponse.GetResponseStream();
StreamReader reader = new StreamReader(GETResponseStream);
string response = reader.ReadToEnd();
return response;
}
catch (WebException ex)
{
// If the web service throws an exception, attempt to see if it give us any clues about what went wrong.
string exception = GetExceptionMessage(URL, ex);
throw new Exception(exception);
}
}
protected string CallPOSTWebService(string URL, string token, string XMLdata)
{
try
{
// Call a "POST" web service, passing it some XML, and expecting some XML back as a Response.
byte[] formData = UTF8Encoding.UTF8.GetBytes(XMLdata);
HttpWebRequest POSTRequest = (HttpWebRequest)WebRequest.Create(URL);
POSTRequest.Method = "POST";
POSTRequest.ContentType = "application/xml";
POSTRequest.Accept = "application/xml";
POSTRequest.Timeout = 3 * 60 * 1000; // Wait for upto 3 minutes
POSTRequest.KeepAlive = false;
POSTRequest.ContentLength = formData.Length;
POSTRequest.Headers.Add("X-SAP-LogonToken", token);
Stream POSTstream = POSTRequest.GetRequestStream();
POSTstream.Write(formData, 0, formData.Length);
HttpWebResponse POSTResponse = (HttpWebResponse)POSTRequest.GetResponse();
StreamReader reader = new StreamReader(POSTResponse.GetResponseStream(), Encoding.UTF8);
string response = reader.ReadToEnd();
return response;
}
catch (WebException ex)
{
// If the web service throws an exception, attempt to see if it give us any clues about what went wrong.
string exception = GetExceptionMessage(URL, ex);
throw new Exception(exception);
}
}
protected string GetExceptionMessage(string URL, WebException ex)
{
// If one of the BO web service threw an exception, attempt to see if it give us any clues about what went wrong.
string exception = "An exception occurred whilst calling: " + URL + ", " + ex.Message;
try
{
if (ex.Response == null)
return exception;
if (ex.Response.ContentLength == 0)
return exception;
using (Stream sr = ex.Response.GetResponseStream())
{
// The web service will return a string containing XML, which we need to parse, to obtain the actual error message.
StreamReader reader = new StreamReader(sr);
string XMLResponse = reader.ReadToEnd();
XElement XML = XElement.Parse(XMLResponse);
XElement XMLException = XML.Elements().Where(e => e.Name.LocalName == "message").FirstOrDefault();
if (XMLException != null)
exception = XMLException.Value; // eg "Info object with ID 132673 not found. (RWS 000012)"
}
}
catch
{
// If the web service returned some other kind of response, don't let it crash our Exception handler !
}
return exception;
}
重要的是,如果BO的REST服务失败,GetResponse()
将抛出WebException
,然后我们使用我的GetExceptionMessage()
函数来检查错误响应(BO Rest Services以XML格式返回)并尝试从中提取错误消息。
使用此功能,我们的C#代码可以抛出异常,其中包含一些有用的信息:
Info object with ID 132673 not found. (RWS 000012)
..而不是像这样抛出一个模糊的异常(顺便说一句,这是所有SAP自己的C#示例都会做的,因为没有包含任何错误处理)......
(404) Page not found
(503) Service unavailable
我也遇到过BO REST服务实际会抛出“(503) Service Unavailable
”异常的情况......这完全是误导!同样,此代码将有助于向我们提供真正的错误消息。
如果BO的REST服务成功,它们将返回包含一些XML数据的字符串。让我们看一些示例代码,展示我们如何使用我的函数调用REST服务来获取有关特定Webi报告的详细信息。
我们将调用REST服务,然后将XML响应字符串转换为XElement
,这样我们就可以从XML中获取Report的名称。
string token = /* Your login-token */
string URL = string.Format("http://MyServer:6405/biprws/infostore/{0}", ReportID);
string WebiReportResponse = CallGETWebService(URL, token);
// Parse the web service's XML response, and obtain the name of our Webi Report
XElement ReportDetails = XElement.Parse(WebiReportResponse);
XElement title = ReportDetails.Elements().Where(e => e.Name.LocalName == "title").FirstOrDefault();
string ReportName = (title == null) ? "Unknown" : title.Value;
我完全厌恶SAP文档(缺乏它)。
如果SAP本身提供了一些像这样的样本.Net代码,生活将变得更加容易......
答案 1 :(得分:0)
我经常在Java例程中遇到此问题,该例程遍历系统中的所有WebI报告以查找其数据提供者。在例程的开始它可以正常工作,但随着时间的推移,它变得越来越慢并且引发越来越多的这种错误。我相信程序本身并没有什么能够减慢系统速度,并且它可以毫无问题地调用其他BO RESTful服务。
最后我回到使用Java SDK获取信息,它工作正常。即使它正常工作,它也比Restful快得多。使用BO 4.1 SP7