To learn Java and web development I'm writing a personal app that has a form for entering a recipe with ingredients, instructions and various other fields. The main toolset is:
- Spring 3.6.4 with JSP forms
- Hibernate 4.3.10
It can take 5-10 minutes to complete the form, so if there is any sort of DataAccessException I'd like to be able to redisplay the form with their previous entries.
Most of the posts in SO and elsewhere recommend simply displaying an error page for SQL errors but they don't mention the user inconvenience in having to re-enter the data on the form again (due to peculiarities of the data structures used on the form, hitting the back button from the error page will not display all of the entered data).
One simple approach that does work is to catch the error in the controller POST method like this:
try {
recipeService.addRecipe(recipe);
}
catch (DataAccessException ex)
{
model.addAttribute("dataError", "DataAccessException caught");
model.addAttribute("ingredientList", recipeService.getIngredients(recipe));
return "recipe/addRecipe";
}
The dataError message is just for development and would be replaced with a more meaningful message later.
The problem I see with this approach is that the method will have to ultimately dig deeper into the actual error and determine if redisplaying the form makes sense, e.g., constraint violation = "fix this piece of data that caused an error" versus DB connection lost = "sorry, can't talk to the database - try back later". And no matter how thorough I try to be to identify the "redisplay" exceptions I doubt I'll catch them all (pun intended).
If I instead remove the try/catch and display an error page, then I'm not aware of a way to get back to the form with the entered data from the error page since the "recipe" modelattribute is not available to this method:
@ExceptionHandler(DataAccessException.class)
public ModelAndView handleDataAccessException(DataAccessException ex) {
ModelAndView view = new ModelAndView("/common/error");
logger.info("Recipe: DataAccessException exception!");
String errorMsg = ExceptionUtils.getRootCauseMessage(ex);
view.addObject("errorMessage", errorMsg);
return view;
}
I have not tried this yet, but would serializing the form data to a file on the server be an acceptable approach? On the error page I could add a message along the lines of "Click here to redisplay your recipe and try again". There would have to be a way for the redisplay method to know which set of serialized data to retrieve and send to the form, which may not be possible (not familiar enough yet with serialization).
I found this post about saving form data on the client: What is the best way to locally store user-entered data on a web page?. It's for a different context than what I'm trying to do, but it mentions localStorage and IndexedDB which may be a better solution?
I apologize in advance for the length of this post and if this has been answered elsewhere - I couldn't find any SO question that addressed this specific question (or any blog either). Any assistance will be greatly appreciated.
EDIT:
I believe that I could add ModelAttribute and SessionAttribute to the controller like this:
@SessionAttribute("recipe")
public class RecipeController {
@ModelAttribute
public Recipe initializeRecipe () {
return new Recipe();
}
....
But this would work only for the duration of the session, if I understand these annotations correctly (?). It would be better if the entered data could be retrievable in a later session, e.g., once the database is back up.