Using different servlets for different pages - servlets

I'm programming a car-hire web-site as my university project. There are some restrictions like * no JavaScript*, i can only use .jsp and servlets.
I've got few forms, i.e. booking form for customers, form to edit vehicles fleet for manager, etc. Lets say that data entered in the form needs to be validated and saved to a database. So i was thinking of checking weather the data is valid with the help of a servlet.If some field/fields were filled incorrectly i want (with the help of my servlet) to reload the page with form and to ask to re-enter data.
Question. How do I reload a page with a form on it with a help of servlet suggesting that some changes to this page should be made (highlighting of problematic fields, label stating that smth went wrong, etc.)?
Thanks for considering my question.

This is a basic functionality of every MVC framework (Stripes, Spring MVC, Struts, etc.). The idea is to have a servlet prepare a bean with default (usually empty) values, store this bean in a request attribute, and then dispatch to a JSP which displays a form populated with the values stored in the bean.
When the form is submitted, another instance of the same bean is populated with the request parameters, then validated, and if an error is found, the servlet stores the bean in the same request attribute as before, and also error messages in another request attribute. It then redispatches to the same JSP. This JSP redisplays the same form, and thus redisplays the value that the user has just submitted. It also displays the errors stored in the request attribute (and which was null when the JSP was executed for the first time).
Each error message can be associated with a form field name, so that the JSP can, for example, associate an "error" CSS class to a field if an error exists for this field.

Related

Spring Data, updating MVC partial entity

I'm new to Spring, Spring data and Spring MVC so I want to make sure I am not missing something.
I have a form for updating a User object, the form posts to a controller and the controller calls my service class that updates/add the entity using a UserDOA which extends CRUDRepository. I think this is a very basic test code.
The issue is that the form doesn't contain all the fields in my User class, so when the object is posted to the controller, only the fields that are contained in the form are populated and the entity fields that are not in the form are null. For example my user has 4 fields, firstname, lastname, age, password. The form only contains the first 3 fields so when the object is posted to the controller, the password field is null, that is as I expect. My issue is that if I then call save(entity) on my DAO it will update the user but that would include nulling the password field, which of course is undesirable.
Of course I could simply retrieve the original entity from the repository and merge it with only the fields that have been updated, but it seems to me this is a lot of work that would be very commonly required and typically spring has a solution to these types of generic tasks.
Did I miss something?
TIA

Spring MVC 3.1 - Model Attribute lost

I have a quick question on scope of ModelAttributes.
Dev. Env: Spring MVC 3.1/Java 6/JSP w/JSTL for Views
In my controller, I add an attribute to the model via
model.addAttribute(“appForResubmission”, appForResubmission);
In the JSP(served out in response to a GET request) I read it’s contents as:
${appForResubmission.appId}
— works fine and the data is shown on JSP as expected.
Upon submission of the JSP, in the same controller in a different method(in response to a PUT request), I try to read the attributes from the Model for any changes and I am doing this as
#ModelAttribute(“appForResubmission”) Application app
in the method signature.
However, all I get is a new Application object when I try to interrogate the object for data. Spring’s documentation says this kind of instantiation of a new object happens when the requested attribute does not exist in the Model.
What would cause the attribute to be lost? Any ideas? I am suspecting it is a scope issue someplace but I am not sure where the problem could be.
Any pointers you could provide is greatly appreciated?
Thank you,
M. Reddy
The scope of a modelattribute is the request, internally it is just equivalent to HttpSerletRequest.setAttribute("model", model).
If you want the model to be available in a different controller you probably have two options, one is to reconstruct it, based on what you submit to the controller or using your persistent source. The second option is for specific model attributes to be added to the session using #SessionAttribute({'modelname'}), but just be careful that you have to call SessionStatus.complete to remove the model added to the session later.

Retain Dynamic dropdown values

I have 3 dyanmically generated dropdowns in this aspx page. The 2nd and 3rd one are populated as per the selected value of the first one (I've the code for creating the 2nd and 3rd dropdown in 1st one's selectedindexchanged event)
How do I write the code in a such a way that when I traverse back to the page, the dynamic dropdowns retain their selected values?
I'm assuming that what you mean when you say that you "traverse back" to the page is that you navigate to a different page on the site and come back to this page that it's dropdown values will be filled in with what the user selected.
Remember that HTTP is an inherintly statless protocol in that it won't remember data in between postback to the servers. In order to overcome this limitation ASP.NET and other web frameworks use various ways of saving data between request. Currently you are relying on "ViewState" that is stored within the page as a hidden variable called __VIEWSTATE (look at the page source sometime to get an idea of what field looks like) this scope of this hidden variable is when the page first gets loaded and everytime you do a postback to the same page. From your description you probably need a longer term persistance called SessionState or Cookies that will store values for a particular Session.
Here is a link from MSDN that contains interesting information regarding all the possible ways of saving state in an ASP.NET application. Let me know if you've got any other questions.
http://msdn.microsoft.com/en-us/library/75x4ha6s.aspx
--EDIT--
Here's a link to the MSDN article on Session State. My recommendation is to be careful with Session state and only store things that are absolutely required. Also I'd recommend you have a Class that contains the a bunch of constant for the Session Keys. It's easier to manage
http://msdn.microsoft.com/en-us/library/ms178581.aspx
ie instead of
string value = Session["Key"];
//Create a class SessionKeys
Class SessionKeys{
public const string SESSION_KEY = "Key"
}
//Now that string is strongly typed and you don't have to worry about misspelling it
string value = Sesssion[SessionKeys.SESSION_KEY];

How do you reformat an annotated date in Spring MVC when validation has failed?

I have a Spring-MVC app that is displaying a form based on a bean. The bean has a date field annotated with this:
#DateTimeFormat(iso=ISO.DATE_TIME)
This works as expected; the date displays in that format. Meanwhile, other fields in the bean are being validated using JPA validation annotations. When the user submits the form, I have a custom data converter registered to convert the incoming String into a Date which appears to be running fine.
So the problem happens when the user submits the form and validation fails on one of the other fields. When the validation error sends the user back to the form input page, the format on the date has changed to what you'd expect after calling toString() on a date object.
Is there a way to re-trigger the DateTimeFormat annotation on the object before it is sent back to the form?
Something is wrong with your setup, you don't need a custom data converter to convert String into Date. If everything configured fine, #DateTimeFormat controls the data conversion in all cases, both incoming and outcoming.
Make sure you have <mvc:annotation-driven /> and don't override default converters in some way.
Take a look at the samples, such as mvc-showcase.

Custom Elmah YSOD data

I'm using Elmah with ASP.NET and wondering how I would add custom data, such as a session variable, to an unhandled exception email.
I've tried several handlers in the Global.asax file but can't seem to find the right one.
For this, I'd think you would need to modify the Elmah source and recompile. It shouldn't be too difficult to achieve. If you have a look in the constructor of the Elmah.Error class, the HttpContext is passed in, from which you should be able to get the info you need, e.g. Session, Form variables etc. You could add custom fields to the Elmah.Error class for this data
I think the Elmah.ErrorMailHtmlFormatter class is where the email is constructed using a HtmlTextWriter, and here you could insert code in the RenderSummary() method to include the custom fields you added to Elmah.Error.
I know it may be a pain to start working with source, but personally I think it's the cleanest way as there currently is no facility for report/email templates, and it's better that bolting on something to change the output after it has been generated.
Andrew's answer helped a lot, thanks. I ended up doing the following:
Added a OnBuilding event to the ErrorMail http module. The event args for this event have a NameValueCollection property.
I handled the OnBuilding event in global.asax.
Since HttpModules don't always have access to sessionstate, esp. if the exception occurs before the session is loaded, I copied the data i wanted reported into the HttpApplication cache(indexed by sessionid).
When an exception occurs I grab the data i want out of the application cache via the sessionid stored in the request(specifically, in the cookie). I generate a NameValueCollection from this data and send it back to the httpmodule via the OnBuilding args.
The data is then rendered to email similarly to how the server variables section is rendered.

Resources