0

我使用 RESTFull WebService API (BOBJ 4.1) 来检索有关存储库中报告的信息。

当我尝试派生数据提供者列表时,它适用于大多数报告。但是,对于某些报告,我会收到“(404)未找到”消息。我很欣赏对于没有任何数据提供者的报告来说这是一个有效的响应,但我确信我收到 404 消息的报告肯定有一个或多个数据提供者。我也不希望它与权限相关,因为我没有收到“拒绝访问”消息,并且可以使用富客户端打开“有问题”的报告。

我使用以下链接:

http://{servername}:{port}/biprws/raylight/v1/documents/{reportID}/dataproviders

有没有人遇到过这种问题?我错过了什么吗?

4

2 回答 2

1

我在一些 BO REST 服务上遇到了同样的问题(其中一些在我们重新启动服务器后就消失了)。

您没有说明您使用哪种技术来调用 Web 服务,但这是您在 C# 应用程序中获取错误信息的方式。

在我的 C# 应用程序中,以下是我用来调用 GET & POST Business Objects 4.x REST 服务的函数,如果出现问题,它会尝试读取错误消息,因此我们得到的不仅仅是“404 not found” " 或 "503 服务器错误"...

要使用这些功能,您必须已登录 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 服务以 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 中获取报告的名称。

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 代码,生活会容易得多……

于 2016-04-08T09:53:33.757 回答
0

我经常在一个 Java 例程中遇到这个问题,该例程遍历系统中的所有 WebI 报告以找到它们的数据提供者。在例程开始时,它工作正常,但随着时间的推移,它变得越来越慢,并引发越来越多的此类错误。我相当确信该程序本身不会对减慢系统速度造成任何不利影响,并且它可以毫无问题地调用其他 BO RESTful 服务。

最后,我回到使用 Java SDK 获取信息,它工作正常。它也比 Restful 快得多,即使它正常工作。使用 BO 4.1 SP7

于 2016-08-17T13:56:23.257 回答