Object data lost between controllers - spring

I have a problem with transferring an object (as a modelAttribute) and its values in a form between controllers. I have a form with modelAttribute, say "myObject", which has some members. I add a modelAttribute "myObject" to model in the first controller.
I am able to read and present values of "myObject" values in the view, for example, I can get values via ${myObject.memberName}, but when it comes to the second controller which takes as a parameter the object (I mean: modelAttribute("myObject") MyObject myObject) the members are set to default values, mainly null!
Some values are being set in the form (they work fine) and rest of them are being set in the first controller. I want to get values set in the first controller in the second one but they are lost.
How should I transfer the values of a modelAttribute object to not lost them between controllers? Should I place them in HttpRequest paratemers?

HTTP is a stateless protocol. So you can expect that parameters are not going to hang around between requests.
Should I place them in HttpRequest paratemers?
Yes, if you want the values to be available to the controller which handles the next request you need to pass them as part of the request/post them in some form data.
If you have data which you wish to make available to many requests you could consider putting the model in the HttpSession.

Related

validate data in controller and model, or just controller?

I have the action contlrSaveText() in controller and the method modelSaveText() in model.
When the data comes from the website to the contlrSaveText(), I check whether the required information is received to save text, i.e. text name, text content etc. Then I call modelSaveText() to actually perform saving text. Do I need to validate data in this method as well or I can expect that controlled already did the job?
A model is only an abstract description, while a controller does the work.
Your model might have a controller on its own that take care of the data and updates the model. But that is technically a controller.
How he works with toward the outside, e.g. another controller that fills data in, is up to you how you define the interface. If your model uses relations or properties that require to be set up by the controller then you have to validate the data before inserting/accepting. But if not, then there is no point in validation and it can be skipped for performance reasons.
If you need to reject invalid data you have to think of a way how to tell the outside what whent wrong so it can respond to the error.
In your example I would go for validation, but that is just my opinion.

Can I reuse a Spring MVC View instance?

I created a custom view that uses Json.Simple to serialize the model and write the JSON to the response directly.
For some requests, I need to send back a static JSON message, so I am wondering can I reuse a View instance I created earlier (with the message already set)?
My View class is thread-safe.
Sure. As long as you make sure it's thread-safe, as you say, there's no reason that your controller can't return the same View object multiple times. Unorthodox, but valid.
I do not see any problem in reusing an already created view since the render method gets current response object.

ASP.NET MVC 3: how to get parameters the action method was called with?

How do you get the object parameters, which action method was called with at run-time, to accomplish something to the effect of the following
public ActionResult Index(Int32? x, Int32? y, DateTime? z, NumberStyles n) {
this.RouteData.Values["x"] = x
this.RouteData.Values["y"] = y
this.RouteData.Values["z"] = z
this.RouteData.Values["n"] = n
return View();
}
It seems like it should be a possible to the names and values of each parameter without this kind of tedious code.
Sometimes you can get the parameters which the action method was called with, by looking in RouteData, but this isn't always the case, particularly if the action method was invoked with an ajax request, the parameters may not show up in the RouteData, and instead show up in the Request Params.
What I'm looking for, is a generic way to get each parameter that is defined in the action method signature at run-time, and gets the parameter's actual object, run-time value, not just a string. Further more, it should work no matter how the action method was invoked, whether it may be the result of ChildActionExtensions.Action or an ajax callback.
RouteData and Request Params don't seem to have what I'm looking for.
Your code sample is setting values back into the RouteData collection. Are you trying to pass parameters to your view using the RouteData collection? That's not what it exists for, you might consider using ViewBag instead.
Or, create a POCO which contains all your properties and let the data binder do all the work (so use #model YourType in your view and pass a single argument to your view. The default model binder will map the individual argument values for you).
As far as the input value collections are concerned, there's a good reason why the value is not to be found consistently in the collections you've mentioned.
Perhaps the trick here is to clarify what's going on prior to your action being invoked. The arguments to your action method can come from more than one source. For example, it may come from:
The URL Path
The URL query string (eg: in a GET, the parameters after the question mark ?)
POSTed form data
Explicit arguments from another action
In your code sample above, the RouteData collection will only contain the value of "x" if your route has a matching parameter name.
For example: "{controller}/{action}/{x}". (this is a custom route pulling "x" from the path)
Failing that, the values will be resolved using the default model binder and will be pulled from either the query string parameters or POST data as the case may be.
The route value will take precedence. So if the above custom route was applied, the following URL:
http://www.example.com/Something/Index/1?x=2
would invoke your action with x=1. The 1 would then be found in the RouteData as pulled from the URL path and the x=2 found in the Request.QueryString would be ignored.
If you are concerned with how x got its value, then you must take into account all of the above so you know where to look. There is also the question of which route is applied to the request, but that's another topic altogether.
All the input came across the wire as text.. it was the model binder that examined your action signature and converted to the types you specified (wherever that is possible).
So, I don't think what you are asking for exists even conceptually in this setting.

spring mvc #requestmapping best practice

Checked the official ref, found a million ways to do things.
I guess I have 2 set of use cases.
1. return customized http response, basically I am responsible for filling in status code, response body(either XML or JSON or text).
2. return Model and View. view is a jsp page typically and fill in the view with data from modle.
My question is which is a better way to go? it possible to mix them together. In my first use set, is it possible to return a View? also is it possible to have both on them in one method. something like if A return customized http response, if B return ModelAndView.
Thanks!
The return value from any request handling method (i.e. on marked with the #RequestMapping annotation must either identify a view (that will generate the HTTP Response) or generate the HTTP Response itself.
Each handler method stands alone; by that I mean, you can return a view name from some handler methods and generate the HTTP Response in other handler methods.
Check out 15.3.2.3 Supported handler method arguments and return types in the Spring 3x reference document at http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/
As an option to generating the HTTP Response in the handler method, you could setup multiple view resolvers; one or more for normal view resolution (jsp pages, tiles, etc.) and one or more for "special" view resolution (XML, JSON, etc.). For the "special" views, you may want to create your own view class that extends org.springframework.web.servlet.view.AbstractView.
You can accomplish something similar to what you are describing using the ContentNegotiatingViewResolver, which can deal with serving different content based on a request, with no changes required to your #RequestMapping annotations, or in fact anything in you're controllers.
There are plenty of resources on how to use this method, including this and this

Spring MVC annotation preload form

I am a newbie to spring mvc annotations. Which is the best way to load data into a page that has say a string, list (list of country for a drop down) and some form elements like name and address
I see two possible ways
#ModelAttribute on a method - can be used for string, list, initialize the form elements
Put the string, list into ModelAndView in the RequestMethod.GET method
Can anyone shed light on the pros and cons.
Also can some one give a brief example on how to load reference data and form data. What goes inside a form backing object (just the form elements like an address object or the reference data also)
I prefer to create a method which returns, for example, a collection of Strings. I annotate this method with #ModelAttribute, and then the data is always available to all of my vies.
You can manually inject into the model as you described, which is sometimes more appropriate (when you only need model attributes in very specific cases). Often you'll want certain model attributes for multiple views, so it's easier to use a #ModelAttribute-annotated method.
Here is a simple example I wrote on barebones Spring MVC which might help you get started.

Resources