Controlling the HTTP Expires Header

After reading a question on stack overflow about setting an own HTTP expires header and the problem that an additional header is generated automatically,  I made some tests how the domino server can be forced to stop this behaviour programmatically.

During my tests I was able to stop it by using  facesContext.responseComplete() but this works only for „headless“ XPages (set rendered to false). If you are calling the method in a normal XPage (set rendered to true), the generated output will be discarded and looks like the „headless“ version.

Here are two examples including screenshots from firebug console (containing the HTTP response):

  • Adding the header in beforeRenderResponse / beforePageLoad
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
   <xp:this.beforeRenderResponse>
   <![CDATA[#{javascript:
      var ec = facesContext.getExternalContext();
      var response = ec.getResponse();
      var writer = response.getWriter();

      // set headers
      var now = new Date();
      response.setDateHeader("Expires",
         now.getTime() + (60*60*1000));
      response.setHeader("Cache-Control", "public");

      // Output it
      writer.write( now.getTime().toString() );
      }]]>
   </xp:this.beforeRenderResponse>
   <xp:label value="Test!" id="label1"></xp:label>
 </xp:view>

As you can see here, the output from the writer was added to the XPage first (the output will be added before the <HTML>-Tag and causes invalid HTML, but this can be ignored in this demo):

The response contains two HTTP expires header. The -1 is added after the programmatically generated one.

  • Adding the header in afterRenderResponse / afterPageLoad
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
   <xp:this.afterRenderResponse>
   <![CDATA[#{javascript:
      var ec = facesContext.getExternalContext();
      var response = ec.getResponse();
      var writer = response.getWriter();

      // set headers
      var now = new Date();
      response.setDateHeader("Expires",
         now.getTime() + (60*60*1000));
      response.setHeader("Cache-Control", "public");

      // Output it
      writer.write( now.getTime().toString() );
      }]]>
   </xp:this.afterRenderResponse>
   <xp:label value="Test!" id="label1"></xp:label>
</xp:view>

In this scenario, the output is added after the HTML code.

The HTTP expires header was added first.

  • How to remove the header

After some research, I was able to remove the header programmatically:

First, you have to create a new java class which implements com.ibm.xsp.context.RequestParameters.ResponseCacheHeader.

package ch.hasselba.jsf.core;

import javax.servlet.http.HttpServletResponse;
import com.ibm.xsp.context.RequestParameters.ResponseCacheHeader;

public class SHResponseCacheHeader implements ResponseCacheHeader {

   public SHResponseCacheHeader(){}

   public boolean initResponseCacheHeader(HttpServletResponse arg0){
      return true;
   }
}

It is required that the initResponseCacheHeader() method returns true, otherwise this won’t work!

Then, you have to add the responseCacheHeader object to the requestParameters of facesContext:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false">
   <xp:this.beforePageLoad>
   <![CDATA[#{javascript:
      importPackage( ch.hasselba.jsf.core );

      var ec = facesContext.getExternalContext();
      var response = ec.getResponse();
      var writer = response.getWriter();

      // set headers
      var now = new Date();
      response.setDateHeader("Expires",
         now.getTime() + (60*60*1000));
      response.setHeader("Cache-Control", "public");

      // set response cache header object
      var reqParam = facesContext.getRequestParameters();
      var resCH = new SHResponseCacheHeader();
      reqParam.setResponseCacheHeader( resCH );

      // Output it
      writer.write( now.getTime().toString() );
      }]]>
   </xp:this.beforePageLoad>
   <xp:label value="Test!" id="label1"></xp:label>
 </xp:view>

The output will be generated as expected, but the useless HTTP expires header won’t be added anymore:

Dieser Beitrag wurde unter Java, JSF, Server, ServerSide JavaScript, Web, XPages abgelegt und mit , , , , , , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.