I'm currently developing a JSF application using Spring and Primefaces 4.0. We have intermittent issues regarding the XML page being displayed instead of page itself when redirecting to other pages.
This seems to be similar to this https://stackoverflow.com/questions/29178778/partial-response-view-expired-exception-or-malformed-xhtml. Also whenever this happens there are no errors printed in the logs.
PartialResponse 1:
<partial-response>
<error>
<error-name>class java.lang.IndexOutOfBoundsException</error-name>
<error-message>
<![CDATA[ Index: 0, Size: 0 ]]>
<error-message>
</error>
</partial-response>
PartialResponse 2:
<partial-response>
<changes>
<update id="javax.faces.ViewState">-4640542341950585998:4269573232206322924</update>
</changes>
</partial-response>
We are currently using Omnifaces 2.0 FullAjaxExceptionHandlerFactory and we also used banterCz's JSFRedirectStrategy for expired session redirection in our session management filter.
public class JsfRedirectStrategy implements InvalidSessionStrategy {
private Logger logger = LoggerFactory.getLogger(getClass());
private static final String FACES_REQUEST_HEADER = "faces-request";
private String invalidSessionUrl;
/**
* {@inheritDoc}
*/
@Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
boolean ajaxRedirect = "partial/ajax".equals(request.getHeader(FACES_REQUEST_HEADER));
if(ajaxRedirect) {
String contextPath = request.getContextPath();
String redirectUrl = contextPath + invalidSessionUrl;
logger.debug("Session expired due to ajax request, redirecting to '{}'", redirectUrl);
String ajaxRedirectXml = createAjaxRedirectXml(redirectUrl);
logger.debug("Ajax partial response to redirect: {}", ajaxRedirectXml);
response.setContentType("text/xml");
response.getWriter().write(ajaxRedirectXml);
} else {
String requestURI = getRequestUrl(request);
logger.debug("Session expired due to non-ajax request, starting a new session and redirect to requested url '{}'", requestURI);
request.getSession(true);
response.sendRedirect(requestURI);
}
}
private String getRequestUrl(HttpServletRequest request) {
StringBuffer requestURL = request.getRequestURL();
String queryString = request.getQueryString();
if (StringUtils.hasText(queryString)) {
requestURL.append("?").append(queryString);
}
return requestURL.toString();
}
private String createAjaxRedirectXml(String redirectUrl) {
return new StringBuilder()
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
.append("<partial-response><redirect url=\"")
.append(redirectUrl)
.append("\"></redirect></partial-response>")
.toString();
}
public void setInvalidSessionUrl(String invalidSessionUrl) {
this.invalidSessionUrl = invalidSessionUrl;
}
}
faces-config.xml
<factory>
<exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
</factory>
web.xml
<context-param>
<param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
<param-value>1048576</param-value>
</context-param>
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/error/viewexpiredpage.xhtml</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/error/pagenotfound.xhtml</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/globalerrorpage.xhtml</location>
</error-page>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error/globalerrorpage.xhtml</location>
</error-page>
<error-page>
<exception-type>org.springframework.web.client.RestClientException</exception-type>
<location>/error/globalerrorpage.xhtml</location>
</error-page>
<error-page>
<exception-type>org.springframework.web.client.HttpServerErrorException</exception-type>
<location>/error/globalerrorpage.xhtml</location>
</error-page>