RenderMapping and clearing Session attribute - spring

I have a Spring Portlet application and the landing page of an application is a data entry form which is annotated by RenderMapping.
Is there a method that I can override which is executed before the RenderMapping method is called? My requirement is to clear Session attributes using SessionStatus.setComplete() and I wanted to do that(if possible) in the first method. When I did that in the RenderMapping method, the Model attributes became empty and when I tried to submit, I got an error which said Model Attribute is empty or something like that.
The reason I wanted to call SessionAttribute.setComplete() is to clear all SessionAttributes used, so that I get clear form.
Also is there a way to forward or redirect from one RenderMapping method to another RenderMapping method? Didn't see a way when looked, but still wondering.
Any ideas to handle this?

Related

Problems with Spring Forms and Validation

I am newer to Spring, previously I've worked in PHP and Python. I am having some issues understanding how Spring forms work and are validated. My understanding thus far is that when you are using the your form is backed by a bean, meaning you must provide a bean to the JSP. You can also use the stand HTML forms but then you have to manually retrieve the request parameters in the controller.
Here is the issue I am having. I have a User bean that is using Hibernate Validator, and I have add, edit pages for users. The issue is I don't want the password field to appear on the Edit page, the password is going to be garbage anyway because its using BCrypt. However when the form is submitted validation fails because it expects the password to be present. There doesn't seem to be anyway to do partial bean implementation using Spring Form.
I would like to use Spring Form if possible because it reduces repetitive validation code, and its always nice to work with objects. My thoughts now are do I create an intermediate object and then translate the data from that to my bean. Seems tedious and can lead to the creation of way to many objects. My other thought is to just using plain old HTML forms and pull the params myself and set the values in the object.
I'm not sure what is the best approach or if I'm even thinking on the right track. Spring Forms and the validation is offers seems great, but seems like it isn't particularly flexible. Like I said I'm new to Spring so I may just be missing something or not understanding.
Another issue I have been wrestling with is having multiple objects needed on a form. Lets say I have a User bean, which has the following Properties.
private Role role;
private Country country;
So I need to pass User, List, and List to my JSP. I can get them to display fine, however if the form validation fails when it returns to that page, I lose my role and country objects, unless I re-add them to the model before returning the view name. Am I missing something here or is that the norm. It's a request object so I guess that makes sense but seems tedious to have to re-add them every time.
My understanding thus far is that when you are using the your form is
backed by a bean, meaning you must provide a bean to the JSP.
I'd say mostly true. The form is backed by a bean, but the Spring JSTL tags know how to get to the bean based on the set modelAttribute. The bean is living in what you would consider "page" scope, unless you add set your model attribute to be in session. Either way, if you are using the Spring JSTL tags, they are going to one or the other place to get it.
You can also use the stand HTML forms but then you have to manually
retrieve the request parameters in the controller.
Not true. You can "simulate" the same thing that the Spring JSTL tags are doing. Understand that JSTL tags are very much like macros. They are simply copying in some pre-determined block of code into the output with some very rudimentary conditional statements. The key bit that Spring MVC needs to wire the Model Attribute on the Controller side is the name and value, which are easy to decipher how those get generated/wired together.
However when the form is submitted validation fails because it expects
the password to be present.
You could create a "DTO" or "Data Transmission Object", which is basically a go-between to take the values from the UI and are converted in the Controller/Service layer to the real Model objects on the backend. Or, if you are lazy like me, put the User in session scope, in which case you don't have to post the value as Spring will take the one out of session and just updated the one or two fields you did post. Don't post the password, Spring wont set the password.
My thoughts now are do I create an intermediate object and then
translate the data from that to my bean.
Yes, this is the DTO I referred to. You only need to do it where you need to.
I'm not sure what is the best approach or if I'm even thinking on the
right track.
There are probably thousands of ways to do anything in coding, some more right or wrong than others. I know some developers who are design-Nazi's and would say you should always do it one way or another, but I am not one of those people. I think as long as you are consistent, and you are not doing something completely boneheaded you are on the right track. My #1 concern with all the code I write is maintainability. I
Don't want to spend 20hrs trying to re-learn what I did 6mo ago, so I tend to choose the simpler option
Hate repeating code, so I tend to choose more module designs
Hate having to spend 20hrs trying to re-learn what I did 6mo ago, so tend to make heavy use of JavaDoc and comments where I find the code is tricky (lots of loops, doing something weird, etc)
Another issue I have been wrestling with is having multiple objects
needed on a form.
There are several ways to deal with this too. I have never used it, but you CAN actually have more than one Model Attribute associated with the same form and Controller handler. I think you use a <spring:bind> tag or something. I have seen samples around, so Google it if you think you need that.
My approach is usually to either put something in session or build a DTO to hold all the things I need. The first I use more for things like lists to drive building the view, for instance if I have a drop down of States coming from a table. I would have a List of the States put into session and just use them from there, that way I only go after them once and done.
I use the DTO approach (some might call it a Form Bean) when I have a complex gaggle of things I need to change all at once, but the things are not necessarily connected directly. Just to point out: You can have nested objects in your model attributes and use them in your Spring JSTL tags. You can also have Collections (List, Set, Map) in your Model Attribute and get to those as well, although Spring doesn't handle nested Collections very well.
Hope that helps.

Spring MVC - how to pass data from filter to controller

I use Spring MVC in my web application. For every request I'd like to prepare the environment, for example load some data from the datastore and save it so every controller could access that information. I assume that's what filters are for (among other things). I can attach an information to the request variable in a filter, but how do I access it from the controller? Or is there a generally better way to do this?
I think your problem at the moment is how to get the data set in request inside your filter( already done by you) and then accessing it inside the hamdlerMapping method of your controller( you want to achieve).
I agree with both the previous answers but if you have decided to do it this way only then I think you should follow my answer.
In the handler method you have mapped your request to in your controller you can have a parameter in method signature for HttpServletRequest request and it will contain the request parameter you have set in your filter. And you can get that from this request object in your controller.
Hope this helps you. Cheers.
I don't see why this is a good thing to do, filter or no.
If you truly have read-only data that every controller needs, I think a caching solution that is loaded on startup is a better idea. I wouldn't do that with a filter, and I wouldn't burden every single request with such a thing. Once it's done, why keep repeating the action?
#duffymo is right, but if you really want to do that I suggest you to use interceptor
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor

I don't understand [Bind(Exclude="ID")] in MVC

I'm really confused by this... still.
I asked a similar question to this a while before, but i'll ask it even simpler now.
I see this in a lot of samples and tutorials. How could you put [Bind(Exclude="ID")] on an entire Model, and expect to do Edits on the model? If you get pack all the properties of a model on a POST but not the ID, then how do you know which ID to edit?
Even if i'm using ViewModels... i'm probably creating them without IDs. So in that case... also... how do I know which ID was updated on an Edit?
Yes, i understand that there is a "security" element to this. People can hijack the ID... so we need to keep people from updating the value during a POST. But... what is the correct way to handle edits then? What's common practice?
I feel like i'm missing something VERY trivial.
In MVC requests are processed by the model binder when the client makes a request. If you include models on your controllers then, as far as I'm aware, you actually have to specify the model you wish to bind to by prefixing your arguments with the model name (unless you only have one argument which is the model)
SomeModel_ID
Now, in some cases you might want to exclude certain properties from being bound to because they pose a security risk, which you seem to be happy with as a concept. We will exclude ID on the model, preventing any client request from posting this value in plain text.
Now why might we exclude an entire model? Well not all controller arguments are pre-processed by a model binder. RedirectToAction for example does not pass through the model binder, so it is conceivable in this instance for you to create a new model in a POST controller action, and redirect to a GET controller action, passing along a sanitised model. That model cannot be populated by the client, but we are free to populate it ourselves on the server side.
The only time I bind to a model is when I have a view model and an associated editor for that model. This makes it really easy to inject a common editor into a page and to encapsulate those properties. If you have to exclude certain properties from being bound to I would argue that you are doing it wrong.
Update
Following your comments I think I can see why you might be confused. The model bind excluder prevents the client from ever setting a model property. If you need this property to do your updating then you simply can't exclude it. What this does mean then is that the user could potentially post back any ID. In this case you should check that the user has permission to be modifying any objects or database records associated with this ID before serving the requested update. Validating the arguments is a manual process. You can use data annotations for validating inputs, but this isn't likely to help very much with access permissions. It's something you should be checking for manually at some stage.
You know the ID because it's passed to you through the page address. So:
http://yoursite.com/admin/users/edit/20
Will populate your ID parameter with 20. If it's used in a POST (ie, the information is filled in), just manually fill in the ID field and pass it to the database controller in whatever manner you have devised.
This is also immune to (trivial) hijacks because if they were to write some other ID besides 20, they wouldn't be updating the user with ID 20 now would they? :)

Help me better understand Struts2, validation, and stateful actions

As I understand it, Struts2 action class instances can (unlike Struts1) be stateful, because each GET or POST to an action creates a new instance of the backing action class.
I also see that there's a standard(?) idiom (Pattern?) to provide input forms: the same .jsp is used as the View component of two different actions, like this:
<action name="showForm" class="defaultActionThatDoesNothingExceptReturnSuccess">
<result name="success">inputForm.jsp</result>
</action>
<action name="validateAndProcessForm" class="realAction">
<result name="input">inputForm.jsp</result>
<result name="success">formProcessed.jsp</result>
</action>
The first action just displays the form, without validating the input or processing it. The form in the .jsp posts to the second action:
<s:form action="validateAndProcessForm" method="post">
and that second action validates the posted fields/parameters, returning "input" if the form's inputs are incomplete or invalid, or actually calling the action class's execute if the inputs are complete and valid, thus processing the form and returning the (e.g.) formProcessed.jsp that displays something like "thanks for your input!".
So we have this sort of "picket fence" idiom:
defaultAction- -> realAction-
| | | |
-> input.jsp- <--- -> success.jsp
This is done so that the first time input.jsp is displayed, validations aren't called (and so validation errors are not shown), but that after the submit button on that jsp is clicked, the "real" action will validate the input, possibly passing back errors calling out invalid input which the input.jsp will display.
Which brings us back to stateful, non-singleton actions; because the action is stateful and thus not shared across GETs or POSTs, and each instance is instantiated just for that GET or POST, the action has no way to know if a particular session has "GETted" the same page multiple times. So GETting showForm.action will never validate, and GETing validateAndProcessForm will always validate (and show errors if the parameters are invalid), even if that GET is the first time a particular session has "GETted" that URL.
Which is why we need the "fence post": the first action just to display the form, the second to capture the input.
Is my understanding correct? Is there a less verbose way to do this, to not validate input on the initial GET, but to validate on the POST, without having to have two actions for every form?
There is another way to perform what you want without the picket fence. The validation interceptor, by default, does not fire for the input method. You can therefore update your struts.xml to the following:
<action name="*MyForm" method="{1}" class="realAction">
<result name="input">inputForm.jsp</result>
<result name="success">formProcessed.jsp</result>
</action>
With this setup, you do not need the empty action at all. When you first go to the form, you would go to the url "inputMyForm", and have your form action just point to "MyForm". The {1} in the method block just means that the framework will call whatever method matches the * from the action name. If the * match is empty, it defaults to the execute method. So you get the following kinds of actions:
inputMyForm would go to the input() method of your action class
MyForm would go to the execute() method of your action class
executeMyForm would go to the execute() method of your action class
customMethodNameMyForm would go to the customMethodName() method of your action class
Since the validator interceptor excludes any actions going to the input method, you can set up whatever validation you want for this action, and it will only look for it when you submit the form. Since every time you submit the form, it is going to the execute method, the validation will occur every time you submit the form.
Also, if you are extending the ActionSupport class, that class already defines the input() method, so you would not even need to change your action class to accomplish this.
It's possible to do things differently but lets say you let struts2 handle all the requests. Everything that struts2 handles is an "action".
Don't worry about GET or POST they are just two different methods of sending data to an action, if there are parameters (regardless if they are get or set) then struts2 will try to place that data onto the actions class (assuming there is one). If there is a validation method (or a properly named validation xml file) then validation will be run after the class properties are set. Then the execute() method for the class is called (assuming there is a class). After this a jsp is typically rendered which has at its disposal all the public data in the action's method.
Take your "showForm" action... you can reduce the xml to:
<action name="showForm">
<result>inputForm.jsp</result>
</action>
You can see you don't need to define a class. Further the default result is success so we don't need to mention that either.
So when thinking of hmtl we would think in terms of pages. When thinking in struts we think in terms of actions, they only need to be as complicated as necessary. That is if you need to show a form then you need a show form action, if you want a display page that uses the form data then you need a "displayPage" action which does something with the form data.
So think of each action as starting with a url > ----------- > ending with returning date (generally rendering a jsp). The dashes are the optional parts that you may define, but if you don't they will sensibly default for you. To see what features are provided to you you'll need to look in struts2-core-x.x.x.x.jar and view the contents of the struts-default.xml that is where "defaultStack" is defined. Each interceptor in turn is called, knowing what they offer (and the other interceptors offer) let you know what you get out of the box (I wouldn't look into them too deeply just know they are there so you'll know for instance that if you need to upload a file the simple fact that the "fileUpload" intercepter is in the default stack should be indication enough that there must be built in file uploading capabilities.
So no there is not a "false action" to the input form. It is a real action abet a simple one. After you learn how to define packages, actions, default actions for a package and perhaps globally and learn how to define an interceptor then you should look at the conventions plug in. It makes life a lot easier!
Your question makes sense. Your pattern is correct, though:
as Quaternion pointed out, there is little or no "verbosity". Your first "showForm" is a dummy "action mapping", its "do nothing" class does not need a particular class definition (the default ActionSupport is enough).
there are other possible patterns; some people might prefer the idiom you are pointing out (and it has a long history - I remember doing some pelr CGI pages in that way, centuries ago) : use a single url (and hence a single action mapping) for the two "steps" (show the initial form and process the form), by guessing inside the action method (or in the validator) the current step, perhaps by checking that some parameter is present (perhaps a hidden field) or perhaps by discriminating POST/GET. In Struts2, I prefer the other way, in general.
BTW, calling the Struts2 actions "stateful" is correct only if you undestand (you do, apparently) that that 'state' does not survive among requests.

mvc 2.0 updatemodel and my ID Column

I have created a create view within my MVC 2.0 Application and by default it included a field for the integer ID Column.
This is definitely a field i do not need.
If i remove the field and use updatemodel when trying to create the object in code, will something break because it doesnt see my ID column data being passed in, even though it is auto increment?
Also, i noticed that in the NerdDinner example, updatemodel was used and after that the repository.save method was called.
I thought that updatemodel would save the object to the database..why then call the .save method afterwards? Or have i missed something?
Any help with this would be appreciated.
Cheers
As I understand it, the UpdateModel method will blow away all data in the object. This is because MVC is round-trip based. Anything that goes out should come back if you need to keep state. See this question for more details.
A better way to handle this scenario in my opinion is to have an input model class as an Action parameter which is passed to a service call to update the domain entity in the DB. (Or this mapping code could be right in the action method if you really want.)
Also please be aware of the security vulnerabilities that could be introduced by binding directly to your DB model.

Resources