Many times during testing there is a need to override interent data (IP, cookies, HTTP headers) to simulate different use cases. Most of times I see code such as: String ip = request.getRemoteAddr(); // for testing purposes if ( configuredForTesting ) { ip = getIpFromOtherSource(); } There is an elegant way to overcome this clutter using javax.servlet.http.HttpServletRequestWrapper and servlet filters (javax.servlet.Filter), shown in the following classes: import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class QAFilter implements Filter { public void init ( FilterConfig filterConfig ) throws ServletException { } public void doFilter ( ServletRequest request , ServletResponse response , FilterChain filterChain ) throws IOException, ServletException { // wrap the request for QA QARequestWrapper requestWrapper = new QARequestWrapper( (HttpServletRequest)request ); // pass the request/response on filterChain.doFilter( requestWrapper, response ); } public void destroy() { } } import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; public class QARequestWrapper extends HttpServletRequestWrapper { private String ip = null; private List cookies = null; private Map headers = null; public QARequestWrapper ( HttpServletRequest request ) { super ( request ); cookies = new ArrayList(); headers = new HashMap(); String ip = request.getParameter( "ip" ); if ( ip != null ) { ip = ip.trim(); if ( ip.length() != 0 ) { this.ip = ip; } } String[] unparsedCookies = request.getParameterValues( "cookie" ); if ( unparsedCookies != null ) { for ( int i = 0 ; i < unparsedCookies.length ; i++ ) { String[] cookieDetails = unparsedCookies[i].split( "~!!~" ); Cookie cookie = new Cookie( cookieDetails[0], cookieDetails[1] ); cookies.add( cookie ); } } String[] unparsedHeaders = request.getParameterValues( "header" ); if ( unparsedHeaders != null ) { for ( int i = 0 ; i < unparsedHeaders.length ; i++ ) { String[] headerDetails = unparsedHeaders[i].split( "~!!~" ); String headerKey = headerDetails[0]; String headerValue = headerDetails[1]; List headerValueList = (List)headers.get( new IgnoreCaseString( headerKey ) ); if( headerValueList != null ) { headerValueList.add( headerValue ); } else { List l = new ArrayList(); l.add( headerValue ); headers.put( new IgnoreCaseString( headerKey ), l ); } } } } public String getRemoteAddr() { String out = null; if ( ip != null ) { out = ip; } else { out = super.getRemoteAddr(); } return out; } public Enumeration getHeaders ( String headerName ) { Enumeration out = null; if ( headers != null ) { List headersFromUser = (List)headers.get( new IgnoreCaseString( headerName ) ); if ( headersFromUser != null ) { out = Collections.enumeration( headersFromUser ); } else { out = super.getHeaders( headerName ); } } else { out = super.getHeaders( headerName ); } return out; } public String getHeader ( String headerName ) { String out = null; if ( headers != null ) { List headersFromUser = (List)headers.get( new IgnoreCaseString( headerName ) ); if ( headersFromUser != null ) { out = (String)headersFromUser.listIterator().next(); } else { out = super.getHeader( headerName ); } } else { out = super.getHeader( headerName ); } return out; } public Enumeration getHeaderNames() { Enumeration out = null; if ( headers != null && headers.size() > 0 ) { HashSet actualKeySet = new HashSet( Collections.list( super.getHeaderNames() ) ); Set falseKeySet = headers.keySet(); List falseKeySetToString = new ArrayList( falseKeySet.size() ); for ( Iterator iter = falseKeySet.iterator ( ) ; iter.hasNext ( ) ; ) { IgnoreCaseString header = (IgnoreCaseString)iter.next ( ); falseKeySetToString.add( header.toString() ); } actualKeySet.removeAll( falseKeySetToString ); actualKeySet.addAll( falseKeySetToString ); out = Collections.enumeration( actualKeySet ); } else { out = super.getHeaderNames(); } return out; } public Cookie[] getCookies() { Cookie[] out = null; if ( cookies != null && cookies.size() > 0 ) { List cookiesList = new ArrayList( Arrays.asList( super.getCookies() ) ); for ( Iterator iterator = cookies.iterator() ; iterator.hasNext() ; ) { Cookie userDefinedCookie = (Cookie)iterator.next(); for ( Iterator iter = cookiesList.iterator() ; iter.hasNext ( ) ; ) { Cookie actualCookie = (Cookie)iter.next(); if ( actualCookie.getName().equals( userDefinedCookie.getName() ) ) { cookiesList.remove( actualCookie ); break; } } cookiesList.add( userDefinedCookie ); } Cookie[] cookiesArray = new Cookie[ cookiesList.size() ]; cookiesList.toArray( cookiesArray ); out = cookiesArray; } else { out = super.getCookies ( ); } return out; } private static class IgnoreCaseString { private String string = null; public IgnoreCaseString( String s ) { string = s; } public boolean equals ( Object obj ) { if ( ! ( obj instanceof IgnoreCaseString ) ) { return false; } else { return string.equalsIgnoreCase( ((IgnoreCaseString)obj).string ); } } public int hashCode() { return string.toLowerCase().hashCode ( ); } public String toString() { return string; } } } Now configure your filter only on your QA environment deployment descriptor (web.xml): qa_filter QAFilter qa_filter /yourWebApp/someResource The result: Now in your QA environment you can override internet data using HTTP parameters.