Sometimes it can be useful to capture/buffer the response
that comes from the javax.faces.webapp.FacesServlet. Per example, OmniFaces does this for implementing the caching mechanism. But, in this post we are not
talking about OmniFaces Cache component, and about the org.omnifaces.filter.OnDemandResponseBufferFilter.
This is an OmniFaces filter that can be configured to buffer a servlet output,
in this case the FacesServlet output. First, you need to configure it in web.xml, as below (there is also a configuration using a boolean context parameter,
named org.omnifaces.CACHE_INSTALL_BUFFER_FILTER):
...
<filter>
<filter-name>bufferFilter</filter-name>
<filter-class>org.omnifaces.filter.OnDemandResponseBufferFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>bufferFilter</filter-name>
<url-pattern>/faces/*</url-pattern>
</filter-mapping>
...
Now, the OnDemandResponseBufferFilter is ready for use! Below, you can see a simple
phase listener that before the Render Response phase it starts buffering, and
after Render Response phase, it just send to the log the buffer content:
package
my.dissecting.omnifaces;
import
java.io.IOException;
import
java.util.logging.Level;
import
java.util.logging.Logger;
import
javax.faces.event.PhaseEvent;
import
javax.faces.event.PhaseId;
import
javax.faces.event.PhaseListener;
import
org.omnifaces.component.output.cache.CacheInitializer;
import
org.omnifaces.filter.OnDemandResponseBufferFilter;
import
static org.omnifaces.filter.OnDemandResponseBufferFilter.BUFFERED_RESPONSE;
import
org.omnifaces.servlet.BufferedHttpServletResponse;
import
static org.omnifaces.util.Faces.getRequestAttribute;
public class
BufferingPhaseListener implements PhaseListener {
private static final Logger LOG =
Logger.getLogger(BufferingPhaseListener.class.getName());
private static final String
ERROR_NO_BUFFERED_RESPONSE = String.format(
"Check setting the '%s'
context parameter or installing the '%s' filter manually.",
CacheInitializer.CACHE_INSTALL_BUFFER_FILTER,
OnDemandResponseBufferFilter.class
);
private BufferedHttpServletResponse bufferedHttpServletResponse;
@Override
public void afterPhase(PhaseEvent event) {
try {
LOG.info("---------------------
Buffered code start ---------------------");
LOG.info(bufferedHttpServletResponse.getBufferAsString());
LOG.info("---------------------
Buffered code end -----------------------");
} catch (IOException ex) {
Logger.getLogger(BufferingPhaseListener.class.getName()).
log(Level.SEVERE,
null, ex);
}
}
@Override
public void beforePhase(PhaseEvent event) {
bufferedHttpServletResponse = getRequestAttribute(BUFFERED_RESPONSE);
if (bufferedHttpServletResponse == null) {
throw new IllegalStateException(ERROR_NO_BUFFERED_RESPONSE);
}
// Start buffering the response from
now on
bufferedHttpServletResponse.setPassThrough(false);
}
@Override
public PhaseId getPhaseId() {
return PhaseId.RENDER_RESPONSE;
}
}
Once you pass the false value to the setPassThrough()
method the buffering starts. If you pass
true,
the buffering stops. The buffered content can be obtained as string via getBufferAsString() method, or as a byte array, via getBuffer() method.
Per example, if you have the below page:
<?xml
version='1.0' encoding='UTF-8' ?>
<!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:o="http://omnifaces.org/ui">
<h:head>
<title>My Page</title>
<h:outputStylesheet
library="omnifaces" name="css/styles.css"/>
</h:head>
<h:body>
<h:panelGrid columns="1"
style="text-align: center;">
<h:outputLink
value="http://showcase.omnifaces.org/">
<p>OmniFaces 2.0
rocks!</p>
</h:outputLink>
<o:graphicImage
library="omnifaces" name="images/omnifaces20.png"
dataURI="false"/>
</h:panelGrid>
</h:body>
</html>
Then the buffer content will be:
<?xml
version='1.0' encoding='UTF-8' ?>
<!DOCTYPE
html>
<html
xmlns="http://www.w3.org/1999/xhtml">
<head id="j_idt2">
<title>My
Page</title>
<link
type="text/css" rel="stylesheet"
href="/OmniFacesBufferedHttpServletResponse/faces/javax.faces.resource/
css/styles.css;jsessionid=97d1683b0cfc45944cd7a1cf7c4a?ln=omnifaces"
/>
</head>
<body>
<table style="text-align:
center;">
<tbody>
<tr>
<td>
<a
href="http://showcase.omnifaces.org/">
<p>OmniFaces 2.0 rocks!</p>
</a>
</td>
</tr>
<tr>
<td>
<img
src="/OmniFacesBufferedHttpServletResponse/faces/javax.faces.resource/
images/omnifaces20.png;jsessionid=97d1683b0cfc45944cd7a1cf7c4a?ln=omnifaces"
alt="" />
</td>
</tr>
</tbody>
</table>
</body>
</html>
So, if you are a fan of OmniFaces, probably you have the
library already loaded in your project. Now, if this kind of task appears, you
know what to do without losing time or install other libraries or filters.
Niciun comentariu :
Trimiteți un comentariu