Spring passing object/string between controllers (GET & POST) - spring

I've been struggling with passing some value between controller.
I have one controller like this:
#RequestMapping(value = "/add", method = RequestMethod.GET)
public String addGet(HttpServletRequest request, #ModelAttribute(value="branch") Branch branch, Model model, blahblahblah)
//What I want to pass and re use:
String loadRespond;
try{
loadRespond= *SOME LOAD STRING METHOD*;
branch= branchManager.convertString(loadRespond); //METHOD TO SPLIT STRING & INDUCT TO OBJECT
}catch{exception){
//blabla
}
After I successfully inducted all the attributes into the object branch,i show them all through a binding form. What i want to do is, when i'm going to update the data/change some attribute, i want to compare the old branch to the new changed branch. This means that i have to pass the old branch object or the loadRespond string onto the POST method so that can be used. Do anyone have any idea of how to do this? Maybe to assign it to hidden type field in the jsp? and then use it on the controller with request mapping /add of method type post? Thanks..I'm a newbie..

Why don't you try out with session scope ?
store your old branch into the session . and when you get the new object compare with the old one (by retrieving from session)
You can save into session as any of both,
request.getSession().setAttribute("sessionvar", "session value");
#SessionAttributes("sessionvar")
A nice Example here to start with it.
Side-note : your question title doesnt quite expalain your problem and the solutions may vary

As San Krish notes in his answer the most common way is to use #SessionAttributes and pass objects/data using them.
This is useful if you don't worry about user moving backwards and forwards in a page, or want basic control of the object.
Now if you want to have a chain where controller 1 passes to controller 2 which may pass to controller 3 your best bet is to implement web flows.
Summary:
For short and sweet and quick: SessionAttributes is the way to go, example here http://www.intertech.com/Blog/understanding-spring-mvc-model-and-session-attributes/
For chain passing, greater control and validation use Spring Web Flows.

Related

Spring MVC - Keeping object state between ajax requests

Spring MVC 4.1
Hi,
I have a situation where, on a single page, there are several input fields. As the users enters numbers into these fields, a bunch of calculations will occur and update various other fields on the page.
I want this whole calculation model to take place in Java on the server-side. I really want to avoid replicating this logic in Javascript on the client.
What I envision is...
User opens the page, the object that does the calculations (let's call it Calculator) is created and its initial state is set (many of its fields are pre-populated with values).
This Calculator instance is stored and available for the duration of the user's time on that page.
Whenever the user changes a value in an input field, that new value is sent to the server via ajax and plugged into our Calculator object. The Calculator, re-calculates the other fields based on the new state and returns the results to the page.
The other fields on the page are updated accordingly.
The key here is that I'm not sending the state of all fields with each ajax request. I'm only sending the current value that was updated. Essentially, I'm trying to ensure that the form state and the Calculator state on the back-end are always synchronized.
I have looked into #SessionAttributes and #ModelAttribute.
The problem with #ModelAttribute, as I understand it, is that it will be re-created with each ajax request.
The problem with #SessionAttributes is that it is a session variable. What if the user has two of these windows open? And how do I ensure the object is removed from the session when they leave the page? etc...
Maybe there's no magic Spring bullet and I just have to figure out the session variable thing. But any pointers on dealing with this would be much appreciated.
Thanks!
You have a couple of options:
.1. Like you have said using the #SessionAttributes, however yes it suffers from the issue that you have mentioned, multiple instances of the same session will see the same variable.
.2. Store state somewhere else and re-hydrate the state using #ModelAttribute annotated method. I would personally prefer this approach, essentially when you create the form, create it with a identifier for the current state:
#RequestMapping(params = "form")
public String createForm(Model uiModel) {
uiModel.addAttribute("calculationId", UUID.randomUUID().toString());
return "calculationpage/create";
}
Then for subsequent ajax requests, ensure your previous calculationId is sent across:
#ModelAttribute("calculationState")
public CalculationState rehydrateState(String calculationId) {
//retrieve current state of calculation from some persistent store..
}
#RequestMapping("/calculate")
public String handleCalculation(#ModelAttribute("calculationState") CalculationState c) {
//you will get a calculationstate with the delta's at this point..
}
.3. Another potential approach may be to use session but disambiguate different instances within the session with a custom id:
public String handleCalculation(HttpSession session, #RequestParam("calcId") String calcId) {
CalculationState calcState = (CalculationState) session.getAttribute("calculation" + calcId);
}
You need any sort of persistent store outside session to store and retrieve the state of your calculator model. Like Biju said, I will go for solutions like No 2.

MVC 4 WebAPI - Is there a way to get a dictionary of values passed to a POST action?

I am able to successfully retrieve an object via POST action.
I am trying to build a proof of concept for dynamic treatment of form values posted, so that I do not know at design time what those names or values will be.
Is there a particular type of binder or formatter etc. that should be added after [FromBody] attribute in the post action to achieve this?
Essentially I need a name-value-pair. I tried KeyValuePair and dynamic. Dynamic returns an object. I don't know how to get the key names and values out of it.
This should do what you are looking for.
public HttpResponseMessage Post(FormDataCollection collection) {
...
}

REST, Spring MVC 3 and PUT request with AJAX

I guess I'm looking more for advice than any specific coding solutions. Here's the scenario:
I have a form where a new user can be created
This form is accessed via a GET request through a Spring controller
#RequestMapping(value = "/secure/clients", method = RequestMethod.GET)
public String prepareNewClient(final Principal principal, final ModelMap map) {
map.addAttribute("client", new Client());
return "secure/clients";
}
The form is presented, all works fine and I submit the new client using $.ajax({})
The submission triggers a POST request using the same URL to the following method on my controller
#RequestMapping(value = "/secure/clients", method = RequestMethod.POST)
public #ResponseBody JsonResponse saveClient(
#ModelAttribute("client") final Client client,
final BindingResult result,
final Principal principal,
final ModelMap map) {
// validate input
// save client
// prepare JsonResponse object
return jsonResponse;
}
After completion, I want to keep the user on the same screen and have the form trigger a PUT instead of a POST. Which is fine, I can achieve that with jQuery, but as soon as I submit the form again, the client is not on the ModelMap anymore.
I have even tried adding the saved client to the ModelMap of my POST method but even that didn't work.
I'm not entirely sure if I'm doing it the right way. To be honest, every tutorial I've seen uses more or less what I'm doing but NONE of them have a PUT request - mostly deal with creation of objects, which I don't have an issue.
What I have in mind is that I might need to have a controller method mapping to /secure/clients/{clientId} with HTTP.GET and another controller method mapping /secure/clients/{clientId} with HTTP.PUT.
But I'm not sure if that makes sense, so I'm a bit lost.
Should I create my controllers entirely on JSON calls?
Should I redirect the user and forget about AJAX calls in this scenario?
Suggestions are more than appreciated. Thank you!
HttpMethod are not enterely support by web browsers. PUT requesr works great when two applications are working with Restfull API's, but for browser compatibility, it is better to limit yourself to POST or GET request.
You can also put a override parameter in your form to instruct the web server to handle the post as the desired method.
<input type="hidden" name="_method" value="put"/> would do the job.
Spring sf namespace takes care of that hidden field for you.
<sf:form method="put">
....
</sf:form>
In addition, you can test your controller with restclient-ui to see if the problem comes from your WebServer or your client.
I agree with #Daniel.
But you can use HiddenHttpMethodFilter available in Spring. That should make your work easy. You will no longer need to put the hidden filed every time.
Hope that helped. Cheers.
#Daniel and #Japan thank you very much for your answers.
I figured what you said #Daniel and I ended up stepping out of the box and thinking differently - and it worked great.
Just to give you an idea:
Instead of staying on the page, when a new client is inserted I actually refresh the browser
After the function is called the user gets redirected to /secure/clients/{clientId}
From there on a new function is mapped, along with a new POST request
It worked for me. And leveraging from Knockout.JS helped a lot as well.
Thanks again!

Hide url routing parameters in asp.net mvc

Is there a method for specifically hiding the routing parameters in ASP.NET MVC from the users. Specifically, I'd like a link
http://sitename.com/Do?title = 2
to simply become
http://sitename.com/Do
but internally pass the titleId to my controller.
Is that do able?
Thanks
Update: yes, there are buttons on my webpage that currently have such as their href, but I'd rather hide all the parameters so users dont go to other parts of the page directly by trying differnt parameters. #Moshe, no its not a from submit or post else I'd have used a strongly typed view. Thanks
As long as your parameters are on the client, they are never 'hidden' unless you encrypt them. You could store the parameter in a hidden field and set the action method to post, then the value is not visible in the URL. But a user with a little bit of knowlegde about web could still manipulate the hidden field (unless you encrypt the value in some way).
EDIT: If it has to be save you have to check the user's credentials on the server. Otherwise you can obscure the data like in the other sample or you can use encryption, e.g. with ProtectData.Protect(...).
For simple numeric values that have to be passed back and forth to a view you can write two private methods in your controller:
private int Obscure(int source) {
return (source*source) * 3; //or something clever you come up with
}
private int DeObscure(int obscuredValue) {
return (int)Math.Sqrt(obscuredValue / 3); //inverse the Obscure method
}
You can use these to obscure values before you pass them to a view, and de-obscure them after you get them posted back. Mind you, this is really not a good way to implement security, as is explained in this stackoverflow post.
Another option is to create an Obscure/DeObscure procedure that takes in the entire querystring and somehow mangles that back and forth. This would required writing a custom ViewEngine though. Sounds interesting...

Hiding Query String Parameters

I have a GET action for creating records. Because the page is somewhat dynamic, I don't use a model to hold the data. I go off to do some OAuth, only to return to the create screen later on. In order to pass the data back, I am redirecting with a query string. I parse the query string in the GET action, and then show the view. The thing is, the query string is showing up in the browser. This displays pseudo-sensitive data.
Since I am only using the query string for transferring data, I am wondering if I can throw the query string away to prevent it from showing up on the browser.
Otherwise, is there a way to go to another action without redirecting? I've found, if I call the "other" action method directly, it tries to find the view of the original action. I can explicitly change the return View(viewModel) line to return View("create", viewModel) but that seems really dirty.
You should consider changing the action to accept POST requests. At least this will prevent the sensitive information from appearing in the browser. For extra security, your site should be served via SSL.
The other thing you can try is encrypting the sensitive values or the entire query string. The only problem is that this, too, will be preserved in the browser's history unless you require users to log in.
It looks like your action method is trying to do too much. Authentication/authorization is a separate concern which should not be part of the action method. It is better to move the authentication work in to an action filter.
Create an class that extends authorization attribute and override its OnAuthorization method to do your authorization work.
This frees your controller action method to accept POST requests.

Resources