After the user get's redirected from a session bean, the following exception is thrown:
StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception java.lang.StringIndexOutOfBoundsException: String index out of range: -1 at java.lang.String.substring(String.java:1911
at com.sun.faces.renderkit.ServerSideStateHelper.getState(ServerSideStateHelper.java:266
at com.sun.faces.renderkit.ResponseStateManagerImpl.getState(ResponseStateManagerImpl.java:100
at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:227
at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:188
at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123
at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:453
at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:148
at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303
at org.omnifaces.viewhandler.RestorableViewHandler.restoreView(RestorableViewHandler.java:66
at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:192
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231
at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59
at com.sun.grizzly.ContextTask.run(ContextTask.java:71
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513
at java.lang.Thread.run(Thread.java:745)
The button code uses the actionListener
attribute:
actionListener="#{aController.aMethod}"
The controller performs the redirect like this:
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
String encodedURL = response.encodeURL(context.getRequestContextPath() + "/page.xhtml?faces-redirect=true");
context.redirect(encodedURL);
My session config:
<session-config>
<session-timeout>60</session-timeout>
<tracking-mode>URL</tracking-mode>
</session-config>
The page only contains one single form (as well as the generated HTML output), defined:
<form id="wrapper" name="wrapper" method="post" action="/ACETOwebkalender/a/b.xhtml" enctype="application/x-www-form-urlencoded">
The outer pages uses the Slider Revolution Responsive WordPress Plugin, which uses jQuery.ajax
. May this produce the issue?
This issue only appears in IE11 and Safari, when the page is embedded in another page using iFrame.
Fixed the bug for Safari with the following code snippet on every single page:
<script>
window.onload = function() {
if (top != self) { // If true, then page is been requested inside an iframe.
var jsessionid = '#{session.id}';
var forms = document.forms;
for (i = 0; i < forms.length; i++) {
forms[i].action += ';JSESSIONID=' + jsessionid;
}
}
};
</script>
And for IE, I updated the web.xml
to following:
....
<filter>
<filter-name>P3P Response Filter</filter-name>
<filter-class>util.ResponseFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>P3P Response Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>60</session-timeout>
<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
<tracking-mode>URL</tracking-mode>
</session-config>
...
Where ResponseFilter.class
is:
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.HttpServletResponse;
public class ResponseFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse resp = (HttpServletResponse) response;
resp.addHeader("P3P", "CP=\"DC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");
chain.doFilter(request, resp);
}
@Override
public void destroy() {}
}