Java obieeweb服务API中的HtmlViewService未呈现报告(它仅显示旋转加载程序)
我有一个Java应用程序,它利用OBIEE Web服务API使用BI服务器的数据。我可以很好地使用XMLViewService和WebCatalogService,但是我不能让HtmlViewService在Java应用程序中正确地呈现报告。报告仅显示旋转加载程序,但从未实际呈现报告。我很确定这与Java应用程序和BI服务器位于不同的域这一事实有关。这就是API文档所说的: 在Oracle BI Web服务和第三方Web服务器不属于同一域名服务(DNS)域的情况下,用户可能会收到与跨域脚本的浏览器安全约束相关的JavaScript错误。要避免这些问题,请使用setBridge()方法修改回调URL以指向第三方Web服务器。请注意,未提供由第三方Web服务器执行的用于将请求重新路由到Oracle BI Web服务的Web组件。此功能需要由第三方应用程序完成。 几年前,我使用.NET/C#进行了相同类型的集成,并在同一个问题上运行,因为.NET应用程序和BI服务器位于不同的域上。因此,我必须创建一个HTTP处理程序(.ashx文件),并使用setBridge()方法来解决这个问题 我面临的挑战是找不到Java的servlet桥示例。而且我对将.NET/.ASHX代码移植到Javaservlet/bridge没有太大信心。有没有人可以提供任何代码示例或方向来为我指明正确的方向?下面是一段代码,向您展示了我正在做什么来提取报表数据:Java obieeweb服务API中的HtmlViewService未呈现报告(它仅显示旋转加载程序),java,web-services,wsdl,obiee,Java,Web Services,Wsdl,Obiee,我有一个Java应用程序,它利用OBIEE Web服务API使用BI服务器的数据。我可以很好地使用XMLViewService和WebCatalogService,但是我不能让HtmlViewService在Java应用程序中正确地呈现报告。报告仅显示旋转加载程序,但从未实际呈现报告。我很确定这与Java应用程序和BI服务器位于不同的域这一事实有关。这就是API文档所说的: 在Oracle BI Web服务和第三方Web服务器不属于同一域名服务(DNS)域的情况下,用户可能会收到与跨域脚本的浏览
// define report path
ReportRef reportRef = new ReportRef();
reportRef.setReportPath(reportFolder + "/" + reportName);
// set page params
StartPageParams pageParams = new StartPageParams();
pageParams.setDontUseHttpCookies(true);
// set report params
String pageId = htmlService.startPage(pageParams, sawSessionId);
String reportId = pageId + reportName;
htmlService.addReportToPage(pageId, reportId, reportRef, null, null, null, sawSessionId);
// get report html
StringBuffer reportHtml = new StringBuffer();
reportHtml.append(htmlService.getHtmlForReport(pageId, reportId, sawSessionId));
// return html
return reportHtml.toString();
这是浏览器中返回的错误:
无法加载XMLHttpRequest。请求的资源上不存在“Access Control Allow Origin”标头。因此,不允许访问源“”
根据请求,这是我的.NET/.ASHX桥:
using System.Collections.Specialized;
using System.Net;
using System.Text;
using System.Web;
using System;
using System.Collections;
using System.Configuration;
using System.Collections.Specialized;
using System.Web;
using System.Text;
using System.Net;
using System.IO;
using System.Diagnostics;
/*
This is a ASP.NET handler that handles communication
between the SharePoint site and OracleBI.
It will be deployed to:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\OracleBI
*/
public class OracleBridge: IHttpHandler
{
public bool IsReusable {get{return true;}}
public OracleBridge()
{
}
string getServer()
{
string strServer = "http://<enter-domain>/analytics/saw.dll";
int index = strServer.LastIndexOf("/");//split off saw.dll
if (index >=0)
return strServer.Substring(0,index+1);
else
return strServer;
}
public void ProcessRequest(HttpContext context)
{
HttpWebRequest req = forwardRequest(context);
forwardResponse(context,req);
}
private HttpWebRequest forwardRequest(HttpContext context)
{
string strURL = makeURL(context);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strURL);
req.Method = context.Request.HttpMethod;
NameValueCollection headers = context.Request.Headers;
req.Accept = headers.Get("Accept");
req.Expect = headers.Get("Expect");
req.ContentType = headers.Get("Content-Type");
string strModifiedSince = headers.Get("If-Modified-Since");
if (strModifiedSince != null && strModifiedSince.Length != 0)
req.IfModifiedSince = DateTime.Parse(strModifiedSince);
req.Referer = headers.Get("Referer");
req.UserAgent = headers.Get("User-Agent");
if (!req.Method.Equals("GET"))
{
CopyStreams(context.Request.InputStream,req.GetRequestStream());
}
return req;
}
private void forwardResponse(HttpContext context, HttpWebRequest req)
{
HttpWebResponse resp =null;
try
{
resp = (HttpWebResponse)req.GetResponse();
}
catch(WebException e)
{
resp = (HttpWebResponse)e.Response;
}
context.Response.StatusCode = (int)resp.StatusCode;
for (int i = 0; i < resp.Cookies.Count; i++)
{
Cookie c = resp.Cookies[i];
HttpCookie hc = new HttpCookie(c.Name, c.Value);
hc.Path = c.Path;
hc.Domain = getServer();
context.Response.Cookies.Add(hc);
}
context.Response.ContentType = resp.ContentType;
CopyStreams(resp.GetResponseStream(), context.Response.OutputStream);
}
private string makeURL(HttpContext context)
{
string strQuery = context.Request.Url.Query;
string[] arrParams = strQuery.Split('?','&');
StringBuilder resultingParams = new StringBuilder();
string strURL=null;
foreach(string strParam in arrParams )
{
string[] arrNameValue = strParam.Split('=');
if (!arrNameValue[0].Equals("RedirectURL"))
{
if (strParam.Length != 0)
{
if (resultingParams.Length != 0)
resultingParams.Append("&");
resultingParams.Append(strParam);
}
}
else if (arrNameValue.Length >1)
strURL = HttpUtility.UrlDecode(arrNameValue[1]);
}
if (strURL ==null)
throw new Exception("Invalid URL format. requestURL parameter is missing");
String sAppendChar = strURL.Contains("?") ? "&" : "?";
if (strURL.StartsWith("http:") || strURL.StartsWith("https:"))
{
String tmpURL = strURL + sAppendChar + resultingParams.ToString();
return tmpURL;
}
else
{
String tmpURL = getServer() + strURL + sAppendChar + resultingParams.ToString();
return tmpURL;
}
}
private void CopyStreams(Stream inStr,Stream outStr)
{
byte[] buf = new byte[4096];
try
{
do
{
int iRead = inStr.Read(buf,0,4096);
if (iRead == 0)
break;
outStr.Write(buf,0,iRead);
}
while (true);
}
finally
{
outStr.Close();
}
}
}
使用System.Collections.Specialized;
Net系统;
使用系统文本;
使用System.Web;
使用制度;
使用系统集合;
使用系统配置;
使用System.Collections.Specialized;
使用System.Web;
使用系统文本;
Net系统;
使用System.IO;
使用系统诊断;
/*
这是一个处理通信的ASP.NET处理程序
在SharePoint站点和OracleBI之间。
它将被部署到:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\OracleBI
*/
公共类OracleBridge:IHttpHandler
{
公共布尔可重用{get{return true;}}
公共OracleBridge()
{
}
字符串getServer()
{
字符串strServer=”http:///analytics/saw.dll";
int index=strServer.LastIndexOf(“/”)//分离saw.dll
如果(索引>=0)
返回strServer.Substring(0,索引+1);
其他的
返回strServer;
}
公共void ProcessRequest(HttpContext上下文)
{
HttpWebRequest req=转发请求(上下文);
转发响应(上下文,请求);
}
私有HttpWebRequestForwardRequest(HttpContext上下文)
{
字符串strURL=makeURL(上下文);
HttpWebRequest req=(HttpWebRequest)WebRequest.Create(strURL);
req.Method=context.Request.HttpMethod;
NameValueCollection标头=context.Request.headers;
req.Accept=headers.Get(“接受”);
req.Expect=headers.Get(“Expect”);
req.ContentType=headers.Get(“内容类型”);
字符串strModifiedSince=headers.Get(“如果自修改”);
if(strModifiedSince!=null&&strModifiedSince.Length!=0)
req.IfModifiedSince=DateTime.Parse(strModifiedSince);
req.Referer=headers.Get(“Referer”);
req.UserAgent=headers.Get(“用户代理”);
如果(!req.Method.Equals(“GET”))
{
CopyStreams(context.Request.InputStream,req.GetRequestStream());
}
返回请求;
}
私有void forwardResponse(HttpContext上下文,HttpWebRequest请求)
{
HttpWebResponse resp=null;
尝试
{
resp=(HttpWebResponse)req.GetResponse();
}
捕获(WebE例外)
{
resp=(HttpWebResponse)e.Response;
}
context.Response.StatusCode=(int)resp.StatusCode;
对于(int i=0;i1)
strURL=HttpUtility.UrlDecode(arrNameValue[1]);
}
if(strURL==null)
抛出新异常(“无效的URL格式。缺少requestURL参数”);
字符串sAppendChar=strURL.Contains(“?”)&“:”;
if(strURL.StartsWith(“http:)| | strURL.StartsWith(“https:))
{
字符串tmpURL=strURL+sAppendChar+resultingParams.ToString();
返回tmpURL;
}
其他的
{
字符串tmpURL=getServer()+strURL+sAppendChar+resultingParams.ToString();
返回tmpURL;
}
}
私有无效复制流(流指令、流输出
package com.abs.bi;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class OBIEEBridge
*/
public class BridgeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public BridgeServlet() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
this.processRequest(request, response);
} catch (Exception e) {
throw new ServletException(e);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
this.processRequest(request, response);
} catch (Exception e) {
throw new ServletException(e);
}
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpURLConnection urlCon = forwardRequest(request);
forwardResponse(response, urlCon);
}
@SuppressWarnings("unchecked")
private String decodeURL(HttpServletRequest request) {
StringBuffer bufURL = new StringBuffer("");
Map<String, String[]> params = request.getParameterMap();
String[] arrURL = params.get("RedirectURL");
String strURL = arrURL == null || arrURL.length == 0 ? null : arrURL[0];
bufURL.append(strURL);
int nQIndex = strURL.lastIndexOf('?');
if (params != null && !params.isEmpty()) {
bufURL.append(((nQIndex >= 0) ? "&" : "?"));
Set<String> keys = params.keySet();
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
try {
String strKey = it.next();
if (strKey.equalsIgnoreCase("RedirectURL")) {
continue;
}
String strEncodedKey = URLEncoder.encode(strKey, "UTF-8");
String[] paramValues = params.get(strKey);
for (String paramValue : paramValues) {
bufURL.append(strEncodedKey);
bufURL.append("=");
bufURL.append(URLEncoder.encode(paramValue, "UTF-8"));
bufURL.append("&");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
bufURL.deleteCharAt(bufURL.length() - 1);
}
return bufURL.toString();
}
@SuppressWarnings("unchecked")
private HttpURLConnection forwardRequest(HttpServletRequest request) throws IOException {
String strURL = decodeURL(request);
String[] arrURL = strURL.split("&", 2);
String baseURL = arrURL[0];
URL url = new URL(baseURL);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
String strMethod = request.getMethod();
con.setRequestMethod(strMethod);
Enumeration<String> en = request.getHeaderNames();
String strHeader;
while (en.hasMoreElements()) {
strHeader = en.nextElement();
String strHeaderValue = request.getHeader(strHeader);
con.setRequestProperty(strHeader, strHeaderValue);
}
// is not a HTTP GET request
if (strMethod.compareTo("GET") != 0) {
con.setDoOutput(true);
con.setDoInput(true);
con.setUseCaches(false);
DataOutputStream forwardStream = new DataOutputStream(con.getOutputStream());
try {
String urlParameters = arrURL[1];
forwardStream.writeBytes(urlParameters);
forwardStream.flush();
} finally {
forwardStream.close();
}
}
return con;
}
private void forwardResponse(HttpServletResponse response, HttpURLConnection con) throws IOException {
int nContentLen = -1;
String strKey;
String strValue;
try {
response.setStatus(con.getResponseCode());
for (int i = 1; true; ++i) {
strKey = con.getHeaderFieldKey(i);
strValue = con.getHeaderField(i);
if (strKey == null) {
break;
}
if (strKey.equals("Content-Length")) {
nContentLen = Integer.parseInt(con.getHeaderField(i));
continue;
}
if (strKey.equalsIgnoreCase("Connection") || strKey.equalsIgnoreCase("Server")
|| strKey.equalsIgnoreCase("Transfer-Encoding") || strKey.equalsIgnoreCase("Content-Length")) {
continue; // skip certain headers
}
if (strKey.equalsIgnoreCase("Set-Cookie")) {
String[] cookieStr1 = strValue.split(";");
String[] cookieStr2 = cookieStr1[0].split("=");
// String[] cookieStr3 = cookieStr1[1].split("=");
/*
* Change the Set-Cookie HTTP Header to remove the 'path' attribute. Thus the
* browser can accept the ORA_BIPS_NQID cookie from Oracle BI Server
*/
Cookie c = new Cookie(cookieStr2[0], cookieStr2[1]);
c.setPath("/");
response.addCookie(c);
} else {
response.setHeader(strKey, strValue);
}
}
copyStreams(con.getInputStream(), response.getOutputStream(), nContentLen);
} finally {
response.getOutputStream().close();
con.getInputStream().close();
}
}
private void copyStreams(InputStream inputStream, OutputStream forwardStream, int nContentLen) throws IOException {
byte[] buf = new byte[1024];
int nCount = 0;
int nBytesToRead = 1024;
int nTotalCount = 0;
do {
if (nContentLen != -1)
nBytesToRead = nContentLen - nTotalCount > 1024 ? 1024 : nContentLen - nTotalCount;
if (nBytesToRead == 0)
break;
// try to read some bytes from src stream
nCount = inputStream.read(buf, 0, nBytesToRead);
if (nCount < 0)
break;
nTotalCount += nCount;
// try to write some bytes in target stream
forwardStream.write(buf, 0, nCount);
} while (true);
}
}
package com.abs.bi;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspWriter;
import oracle.bi.web.soap.AuthResult;
import oracle.bi.web.soap.HtmlViewService;
import oracle.bi.web.soap.HtmlViewServiceSoap;
import oracle.bi.web.soap.ReportHTMLLinksMode;
import oracle.bi.web.soap.ReportHTMLOptions;
import oracle.bi.web.soap.ReportRef;
import oracle.bi.web.soap.SAWLocale;
import oracle.bi.web.soap.SAWSessionParameters;
import oracle.bi.web.soap.SAWSessionService;
import oracle.bi.web.soap.SAWSessionServiceSoap;
import oracle.bi.web.soap.StartPageParams;
public class AbsServiceUtils {
private AbsServiceUtils() {
}
public static URL buildWsdlUrl() throws MalformedURLException {
return new URL(IAbsService.BASEWSDLURL);
}
public static void writeBiContent(HttpServletRequest request, JspWriter out, String biReport) throws IOException {
String userAgent = request.getHeader("User-Agent");
Locale userLocale = request.getLocale();
String bridgeServletContextPath = request.getContextPath() + "/bridgeservlet";
String reportHtml = writeBiContent(biReport, userAgent, userLocale, bridgeServletContextPath);
if (out != null) {
out.println(reportHtml);
}
}
public static String writeBiContent(String biReport, String userAgent, Locale userLocale,
String bridgeServletContextPath) throws MalformedURLException {
HtmlViewService htmlViewService = new HtmlViewService(buildWsdlUrl());
HtmlViewServiceSoap htmlClient = htmlViewService.getHtmlViewService();
SAWSessionService sAWSessionService = new SAWSessionService(buildWsdlUrl());
SAWSessionServiceSoap myPort = sAWSessionService.getSAWSessionServiceSoap();
SAWSessionParameters sessionparams = new SAWSessionParameters();
sessionparams.setUserAgent(userAgent);
SAWLocale sawlocale = new SAWLocale();
sawlocale.setLanguage(userLocale.getLanguage());
sawlocale.setCountry(userLocale.getCountry());
sessionparams.setLocale(sawlocale);
sessionparams.setAsyncLogon(false);
AuthResult result = myPort.logonex(IAbsService.BIUSERNAME, IAbsService.BIPASSWORD, sessionparams);
String sessionID = result.getSessionID();
List<String> keepAliveSessionList = new ArrayList<>(1);
keepAliveSessionList.add(sessionID);
myPort.keepAlive(keepAliveSessionList);
StartPageParams spparams = new StartPageParams();
spparams.setDontUseHttpCookies(true);
String pageID = htmlClient.startPage(spparams, sessionID);
/**
* This method will set the path to the servlet which will act like a bridge to
* retrieve all the OBIEE resources like the javascript, CSS and the report.
*/
if (bridgeServletContextPath != null) {
htmlClient.setBridge(bridgeServletContextPath, sessionID);
}
ReportHTMLOptions htmlOptions = new ReportHTMLOptions();
htmlOptions.setEnableDelayLoading(false);
htmlOptions.setLinkMode(ReportHTMLLinksMode.IN_PLACE.value());
ReportRef reportref = new ReportRef();
reportref.setReportPath(IAbsService.BIROOTPATH + biReport);
StartPageParams startpageparams = new StartPageParams();
startpageparams.setDontUseHttpCookies(false);
htmlClient.addReportToPage(pageID, biReport.replace(" ", ""), reportref, null, null, htmlOptions, sessionID);
String reportHtml = htmlClient.getHeadersHtml(pageID, sessionID);
reportHtml = reportHtml + htmlClient.getHtmlForReport(pageID, biReport.replace(" ", ""), sessionID);
reportHtml = reportHtml + htmlClient.getCommonBodyHtml(pageID, sessionID);
return reportHtml;
}
}
package com.abs.bi;
public interface IAbsService {
public static final String BASEWSDLURL = "http://<OracleBIServer:port>/analytics/saw.dll/wsdl/v12";
public static final String BIUSERNAME = "USER";
public static final String BIPASSWORD = "PASS";
public static final String BIROOTPATH = "/shared/sharedfolder/";
public static final String BIREPORTNAME = "report";
}