Skip to content

Instantly share code, notes, and snippets.

@rafaeltuelho
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rafaeltuelho/9376341 to your computer and use it in GitHub Desktop.
Save rafaeltuelho/9376341 to your computer and use it in GitHub Desktop.
Java HTTP Servlet to be used as a bridge between a Web APP and Oracle BI Server when using OBIEE SOAP API for integration scenarios.
package br.net.rafaeltuelho.servlets;
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;
import org.apache.log4j.Logger;
/**
* Servlet implementation class OBIEEBridge
*/
public class OBIEEBridge extends HttpServlet {
private static final long serialVersionUID = 1L;
private static Logger logger = org.apache.log4j.Logger
.getLogger(OBIEEBridge.class);
/**
* @see HttpServlet#HttpServlet()
*/
public OBIEEBridge() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
logger.info("doGet");
try {
this.processRequest(request, response);
} catch (Exception e) {
logger.error("Servlet Error: ", e);
throw new ServletException(e);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
logger.info("doPost");
try {
this.processRequest(request, response);
} catch (Exception e) {
logger.error("Servlet Error: ", 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();
logger.debug("Request param is: " + params.toString());
String[] arrURL = params.get("RedirectURL");
String strURL = arrURL == null || arrURL.length == 0 ? null : arrURL[0];
bufURL.append(strURL);
logger.info("URL is: " + 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")){
logger.debug("skipping [RedirectURL] key from map parameters...");
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 {
logger.info(">>> forwardRequest >>>");
String strURL = decodeURL(request);
logger.info("\t decodeURL returned: " + strURL);
String[] arrURL = strURL.split("&", 2);
String baseURL = arrURL[0];
URL url = new URL(baseURL);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
logger.info("\t Connection opened OK");
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);
logger.debug("\t Set [request] header " + strHeader + "=" + strHeaderValue);
con.setRequestProperty(strHeader, strHeaderValue);
}
// is not a HTTP GET request
if (strMethod.compareTo("GET") != 0) {
logger.info("\t Try to copy request body and send within a [" + strMethod +
"] request to the target ["+
con.getURL().getHost() + "] Server");
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 {
logger.info("<<< forwardResponse <<<");
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);
logger.info("\t Add COOKIE \n\t" +
c.getName() + "\n\t\t" +
"value: " + c.getValue() + "\n\t\t" +
"path: " + c.getPath() + "\n\t\t" +
"domain: " + c.getDomain());
}
else{
response.setHeader(strKey, strValue);
logger.info("\t Set [response] header " + 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 {
logger.debug("copyStreams called nContentLen=" + nContentLen);
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;
logger.debug("copyStreams. About to call inputStream.read " + nBytesToRead);
// try to read some bytes from src stream
nCount = inputStream.read(buf, 0, nBytesToRead);
logger.debug("copyStreams.read returned " + nCount);
if (nCount < 0)
break;
nTotalCount += nCount;
logger.debug("copyStreams. About to call forwardStream.write " + nCount);
// try to write some bytes in target stream
forwardStream.write(buf, 0, nCount);
logger.debug("copyStreams. write done");
} while (true);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment