Resolution: In order to tackle this issue, one of the simplest way is to write a Java EE filter which can help to retain the parameters by passing the parameters as it is to the target url along with response headers and thus, achieving the goal.
Here, I present a simple Java EE filter which we are already using in our project and works flawlessly. It is exactly similar solution to the implementation provided in WCS 12c v2.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package COM.FutureTense.Servlet; | |
import com.fatwire.cache.WebReference; | |
import java.io.FileNotFoundException; | |
import java.io.IOException; | |
import java.io.UnsupportedEncodingException; | |
import java.net.URLDecoder; | |
import java.util.Properties; | |
import java.util.Map; | |
import java.util.Set; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
import javax.servlet.Filter; | |
import javax.servlet.FilterChain; | |
import javax.servlet.FilterConfig; | |
import javax.servlet.RequestDispatcher; | |
import javax.servlet.ServletException; | |
import javax.servlet.ServletRequest; | |
import javax.servlet.ServletResponse; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
import org.apache.commons.lang.StringUtils; | |
import org.apache.commons.logging.Log; | |
import org.apache.commons.logging.LogFactory; | |
import org.owasp.esapi.ESAPI; | |
import org.owasp.esapi.Validator; | |
import org.owasp.esapi.errors.IntrusionException; | |
import org.owasp.esapi.errors.ValidationException; | |
import org.springframework.beans.factory.BeanFactory; | |
import org.springframework.beans.factory.xml.XmlBeanFactory; | |
import org.springframework.core.io.ClassPathResource; | |
public class CustomWebReferenceFilter | |
implements Filter | |
{ | |
private static final String LOCATION = "Location"; | |
private static final String LOOKUPHOST = "lookuphost"; | |
private static final String LOOKUPPAGE = "lookuppage"; | |
private static final String WebReference = "webreference.xml"; | |
private static final Pattern pattern = Pattern.compile("\\s"); | |
private static BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("webreference.xml")); | |
private static final Log logger = LogFactory.getLog("oracle.fatwire.sites.webreference"); | |
private Resolver resolver; | |
private static String contentType; | |
private static String encoding; | |
public void init(FilterConfig filterConfig) | |
throws ServletException | |
{ | |
this.resolver = ((Resolver)beanFactory.getBean("WebreferenceResolver")); | |
Properties properties = new Properties(); | |
try | |
{ | |
properties.load(getClass().getClassLoader().getResourceAsStream("ServletRequest.properties")); | |
contentType = (properties.get("cs.contenttype") != null ? (String)properties.get("cs.contenttype") : "text/html; charset=utf-8").toLowerCase().trim(); | |
int charsetIndex = contentType.lastIndexOf("charset="); | |
encoding = charsetIndex > -1 ? contentType.substring(charsetIndex + 8).trim() : "utf-8"; | |
int delimiterIndex = encoding.indexOf(";"); | |
if (delimiterIndex > -1) { | |
encoding = encoding.substring(0, delimiterIndex).trim(); | |
} | |
} | |
catch (FileNotFoundException e) | |
{ | |
throw new ServletException(e); | |
} | |
catch (IOException e) | |
{ | |
throw new ServletException(e); | |
} | |
} | |
public void destroy() {} | |
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) | |
throws IOException, ServletException | |
{ | |
request.setCharacterEncoding(encoding); | |
response.setContentType(contentType); | |
if (logger.isTraceEnabled()) | |
{ | |
logger.trace("encoding = " + encoding); | |
logger.trace("contentType = " + contentType); | |
} | |
HttpServletRequest httpRequest = (HttpServletRequest)request; | |
HttpServletResponse httpResponse = (HttpServletResponse)response; | |
if (this.resolver == null) | |
{ | |
if (logger.isDebugEnabled()) { | |
logger.debug("Resolver is not defined"); | |
} | |
filterChain.doFilter(request, response); | |
return; | |
} | |
String lookupPage = httpRequest.getParameter("lookuppage"); | |
String lookupHost = httpRequest.getParameter("lookuphost"); | |
if (logger.isDebugEnabled()) | |
{ | |
logger.debug("lookupPage: " + lookupPage); | |
logger.debug("lookupHost: " + lookupHost); | |
} | |
if (StringUtils.isNotEmpty(lookupPage)) | |
{ | |
WebReference webreference = this.resolver.resolve(httpRequest, lookupPage, lookupHost); | |
if (logger.isDebugEnabled()) { | |
logger.debug("webreference: " + webreference); | |
} | |
if (webreference != null) | |
{ | |
if (webreference.isRedirect()) | |
{ | |
redirect(httpResponse, webreference, httpRequest); | |
return; | |
} | |
if (webreference.isNotFound()) | |
{ | |
if (logger.isDebugEnabled()) { | |
logger.debug("Setting 404"); | |
} | |
httpResponse.setStatus(404); | |
httpResponse.sendError(404); | |
return; | |
} | |
String resolvedURL = webreference.getResolvedURL(); | |
if (logger.isDebugEnabled()) { | |
logger.debug("forwardURL: " + resolvedURL); | |
} | |
RequestDispatcher requestDispatcher = httpRequest.getRequestDispatcher(resolvedURL); | |
requestDispatcher.forward(request, response); | |
return; | |
} | |
if (logger.isDebugEnabled()) { | |
logger.debug("Setting 404"); | |
} | |
httpResponse.setStatus(404); | |
httpResponse.sendError(404); | |
return; | |
} | |
filterChain.doFilter(request, response); | |
} | |
public void redirect(HttpServletResponse httpResponse, WebReference webreference, HttpServletRequest httpRequest) | |
{ | |
Map<String, String[]> paramMap = httpRequest.getParameterMap(); | |
String otherParams = ""; | |
boolean firstParam; | |
if (paramMap.size() > 2) | |
{ | |
Set<String> keys = paramMap.keySet(); | |
firstParam = true; | |
for (String key : keys) { | |
if ((!key.equals("lookuphost")) && (!key.equals("lookuppage"))) { | |
if (firstParam) | |
{ | |
otherParams = otherParams + "?" + key + "=" + ((String[])paramMap.get(key))[0]; | |
firstParam = false; | |
} | |
else | |
{ | |
otherParams = otherParams + "&" + key + "=" + ((String[])paramMap.get(key))[0]; | |
} | |
} | |
} | |
} | |
if (logger.isDebugEnabled()) { | |
logger.debug("Redirecting to URL: " + webreference.getResolvedURL()); | |
} | |
if (webreference.isPermanentRedirect()) | |
{ | |
if (logger.isDebugEnabled()) { | |
logger.debug("Setting 301"); | |
} | |
httpResponse.setStatus(301); | |
} | |
else if (webreference.isTemporaryRedirect()) | |
{ | |
if (logger.isDebugEnabled()) { | |
logger.debug("Setting 302"); | |
} | |
httpResponse.setStatus(302); | |
} | |
String strippedName = replaceLinearWhiteSpace("Location"); | |
String strippedValue = null; | |
try | |
{ | |
strippedValue = replaceLinearWhiteSpace(URLDecoder.decode(webreference.getResolvedURL(), "UTF-8")); | |
} | |
catch (UnsupportedEncodingException e) | |
{ | |
strippedValue = replaceLinearWhiteSpace(webreference.getResolvedURL()); | |
} | |
//add other params as well | |
if (!otherParams.equalsIgnoreCase("")) { | |
strippedValue = strippedValue + otherParams; | |
} | |
try | |
{ | |
String safeName = ESAPI.validator().getValidInput("setHeader", strippedName, "HTTPHeaderName", 20, false); | |
String safeValue = ESAPI.validator().getValidInput("setHeader", strippedValue, "HTTPHeaderValue", 500, false, false); | |
httpResponse.setHeader(safeName, safeValue); | |
} | |
catch (ValidationException e) | |
{ | |
logger.error("Error redirecting ", e); | |
return; | |
} | |
catch (IntrusionException e) | |
{ | |
logger.error("Error redirecting ", e); | |
return; | |
} | |
} | |
private String replaceLinearWhiteSpace(String input) | |
{ | |
return pattern.matcher(input).replaceAll(" "); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<filter> | |
<filter-name>CustomWebReferenceFilter</filter-name> | |
<filter-class>COM.FutureTense.Servlet.CustomWebReferenceFilter</filter-class> | |
</filter> | |
<filter-mapping> | |
<filter-name>CustomWebReferenceFilter</filter-name> | |
<url-pattern>/Sites/*</url-pattern> | |
<dispatcher>REQUEST</dispatcher> | |
<dispatcher>FORWARD</dispatcher> | |
</filter-mapping> | |
<filter> | |
<filter-name>WebReferenceFilter</filter-name> | |
<filter-class>COM.FutureTense.Servlet.WebReferenceFilter</filter-class> | |
</filter> | |
<filter-mapping> | |
<filter-name>WebReferenceFilter</filter-name> | |
<url-pattern>/Sites/*</url-pattern> | |
<dispatcher>REQUEST</dispatcher> | |
<dispatcher>FORWARD</dispatcher> | |
</filter-mapping> |
Disclaimer: The code and/or the configurations posted are not official recommendations and should be used at sole's discretion with proper testing before deploying on live WebCenter Sites systems. Cheers!!