What the problem is : What happens when clicking on the browser back button --> opens up a page whose viewscoped-managedbean is already destroyed --> submit
The browser seems to have served the page from its cache instead of sending a fullworthy HTTP GET request to the server, while you have JSF state saving method set to server (which is the default).
There are 2 ways to solve this problem:
Tell the browser to not cache the dynamic JSF pages. You can do this with help of a filter.
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if (!req.getRequestURI().startsWith(req.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc)
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
res.setHeader("Pragma", "no-cache"); // HTTP 1.0.
res.setDateHeader("Expires", 0); // Proxies.
}
chain.doFilter(request, response);
}
Map the filter on the FacesServlet or its same URL-pattern.
Set the JSF state saving method to client, so that the entire view state is stored in a hidden field of the form instead of in the session in the server side.
javax.faces.STATE_SAVING_METHOD
client
The filter way is preferable.