BOBJ。 RESTFul Web服务API。获取数据提供者列表返回“404”消息

时间:2015-01-29 11:03:34

标签: web-services rest sap business-objects business-objects-sdk

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

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

我使用以下链接:

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

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

2 个答案:

答案 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