Spring MVC URL mapping in controller For dynamic URLs - java

I have a page with part of a URL that is dynamic e.g.
http://localhost:8080/myApp/myPageList.htm?recNo=107&recNo=-96&recNo=-24&recNo=-9&recNo=38&recNo=-21&recNo=-50&crimeRecNo=-110
The last part of the page recNo is a parameter passed to the page. However, the parameter value was encrypted. I would like to know how I can set the urlMapping in the controller. I will be posting the data and i will require a urlMapping to process this form.

So based on your comments your request mapping should be
#RequestMapping("/myPageList.htm")
And the signature of your method something like
public WhateverType myPageList(#RequestParam("recNo") List<Integer> recNo, ...
assuming that recNo are integer values.

Using SimpleUrlHandlerMapping (doc sample)might help.
Have a look at ControllerClassNameHandlerMapping here, as well

Related

Spring Controller "redirect"

I'm been search for a solution for this problem for a while and didn't found any!!
To explain the problem I will give and example:
Let's imagine that I have a search page X with results (x1....x10) and a form to give feedback. This form will call a link for a controller (java spring controller) defined as '/feedback.html'. After the submit the feedback, the controller should return again to X with the same results. And here is the problem, how can I do this? because this feedback controller can go to X or to any other page depending where the form is!
In summary: How can I do the javascript history(-1) in the controller (java spring controller)??
Thanks
If you access the search page like this:
http://domain.com/search/query
or
http://domain.com/search?query=text
Then you can just pass this ulr along with the feedback form (by adding a hidden input with its value the URL)
<% request.setAttribute("redirectURL",
request.getAttribute("javax.servlet.forward.request_uri"));%>
<form:hidden path="redirectURL" value="${redirectURL}"/>
And then in the controller simply access the redirectURL property and redirect to the search page with the same query showing the same results.
The "redirect" Spring capabilities is usually used within a PRG pattern. Given your title and your use case, I'll assume you're trying to get redirected to the search page or another page after submitting your form (form action seems to be '/feedback.html').
So basically you have your feedback controller which should have a #RequestMapping annotated method like #RequestMapping(value = "/feedback.html", method = RequestMethod.POST). From there and within this method, you can redirect the request anywhere you want by returning a String matching an existing mapping in you Spring app (for example, if you want to redirect to the search page, given your search page is mapped with #RequestMapping(value = "/search.html", method = RequestMethod.GET), simply return "redirect:/search.html".
Note that the whole "search page" logic will have to be re-run (the redirect issuing a new GET request) so if you don't want that to happen, you will indeed have to store the search results in session (not sure what sense does that make... but it's possible).
EDIT : If your URL mapping permits it, you can also redirect the request to the search page with search parameters included, something like : "redirect:/search.html?myParam=10".
I think, in the search controller, you can store X in session and at the end of your feedback controler send a redirect to an URL that call the search controller (same methode or another one) that load the search result page using the X held in session.
You can also pass the X parameter with hiden field (if you dont want to use session).

JSTL objects in the url, not in tag context

So I'm writing a Spring 3 webapp with JSP views and JSTL tags. They normally work great, but there's this one controller call that doesn't grab the tags properly.
ModelAndView mav = new ModelAndView(
new RedirectView(RequestUtil.getWebAppRoot(request) + clientShortName, false)
);
mav.addObject("status","Session for interface successfully removed");
return mav;
So when I go to reference it in my view, I'll have a line that looks like:
<p>status="${status}"</p>
Which just displays as:
status=""
Now I would normally just dismiss this as something causing my view to render improperly, but I actually found this sitting appended to my URL:
?status=Session+for+interface+zFXDEV3+successfully+removed
So this leaves me with two questions:
Why can't I reference the object from a JSTL tag?
If I can't get it as a part of the tag context, what is it doing in the URL?
and for anyone wondering, the class types are:
org.springframework.web.servlet.view.RedirectView.RedirectView
org.springframework.web.servlet.ModelAndView.ModelAndView(View view)
This is not JSTL but Expression Language (commonly known as EL). The problem is that EL ${status} will look the variable in the request attributes, but when you redirect to your JSP you have status as request parameter but not as request attribute (note that this is normal behavior when you redirect to a page).
For a better example (taken from StackOverflow Expression Language code), this is what is executed:
<%
String status = (String) pageContext.findAttribute("status");
if (status != null) {
out.print(status);
}
%>
You have two possible options here:
As stated by #SotiriosDelimanolis, your #Controller class for this URL should take the request parameters and add them as request attributes. Lot of work if you could add more request parameters in the future.
Use the ${param} object from EL that gives you access to the request parameters. Using this, you should change ${status} to ${param.status}. End of story.
Because it is a RedirectView. The javadoc says:
By default all primitive model attributes (or collections thereof) are
exposed as HTTP query parameters (assuming they've not been used as
URI template variables), but this behavior can be changed by
overriding the isEligibleProperty(String, Object) method.
So your String objects are added as query parameters in the new, redirected, request. They are no longer available as model/request attributes to the new request.
The #Controller that handles the redirected URL should re-add the attribute to the model.

Spring MVC RequestMapping ParamRequest collection/array

I have a #Controller with a #RequestMapping functions that accept collections.
Imagine something like:
requestHandler(Collection<Long> param){
...
}
This mapping only matches when I send requests such as:
http://www.domain.com/mapping/funct?param=1&param=2&param=3
I'd like to match it as well when I send a comma sepparated value:
http://www.domain.com/mapping/funct?param=1,2,3
Is there a way without using .split ? I'd like it to be automatically parsed to a collection.
You would have to write a custom Converter and register it in your Spring MVC context.
It is better to access all query parameters and parse according to your needs in this type of scenarios
You should have access to the requests query string via request.getQueryString().
In addition to getQueryString, the query parameters can also be retrieved from request.getParameterMap() as a Map.

passing values from controller to filter

I like to pass values from a spring controller to a filter without using session. suggestions please..
From the first controller I set the values to the request and showing a page. Some jsp pages included with this view (using tiles) is using this attributes. When I try to access this values from this controllers, it is null .
Add an attribute to the request in your controller (using request.setAttribute(...)), then fetch it in the filter (using getAttribute(...)).
(Answer is as lacking in detail as the question...)

Can I find the URL for a spring mvc controller in the view layer?

I think what I need is called reverse url resolution in Django. Lets say I have an AddUserController that goes something like this:
#Controller
#RequestMapping("/create-user")
public class AddUserController{ ... }
What I want is some way to dynamically find the url to this controller or form a url with parameters to it from the view (JSP), so I don't have to hardcode urls to controllers all over the place. Is this possible in Spring MVC?
Since Spring 4 you can use MvcUriComponentsBuilder.
For the most type-safe method:
String url = fromMethodCall(on(MyController.class).action("param")).toUriString();
Note this example requires that the method returns a proxyable type - e.g. ModelAndView, not String nor void.
Since 4.2, the fromMappingName method is registered as a JSP function called mvcUrl:
Login
This method does not have the proxy restriction.
Have you considered having a bean that aggregates all of the controller URLs you need into a HashMap and then adding this controller/URL Map to any model that requires it? Each Spring controller has the ability to call an init() method, you could have each controller add it's name and URL to the controller/URL map in the init() methods so it would be ready to use when the controllers go live.
Can solve with Java Reflection API. By Creating Custom Tag library. methods looks like this
Class c = Class.forName("Your Controller");
for(Method m :c.getMethods()){
if(m.getName()=="Your Method"){
Annotation cc = m.getAnnotation(RequestMapping.class);
RequestMapping rm = (RequestMapping)cc;
for(String s:rm.value()){
System.out.println(s);
}
}
}
Possible Problem You Can Face is
1.Path Variable > Like this /pet/show/{id} so set of path name & value should be support then replace this String.replace() before return url
2.Method Overriding > only one method is no problem. if Method override Need to give support sequence of Parameter Type That you really want like Method.getParametersType()
3.Multiple Url to Single Method> like #RequestMapping(value={"/", "welcome"}). so easy rule is pick first one.
4.Ant Like Style Url > Like this *.do to solve this is use multiple url by placing ant like style in last eg. #RequestMapping(value={"/pet","/pet/*.do"})
So Possible link tag style is
<my:link controller="com.sample.web.PetController" method="show" params="java.lang.Integer">
<my:path name="id" value="1" />
</my:link>
Where parmas attribute is optional if there is no method override.
May be I left to think about some problem. :)
I would probably try to build a taglib which inspects the annotations you're using in order to find a suitable match:
<x:url controller="myController">
<x:param name="action" value="myAction"/>
</x:url>
Taglib code might be something roughly like
Ask Spring for configured beans with the #Controller annotation
Iterate in some suitable order looking for some suitable match on the controller class or bean name
If the #RequestMapping includes params, then substitute them
Return the string
That might work for your specific case (#RequestMapping style) but it'll likely get a bit hairy when you have multiple mappings. Perhaps a custom annotation would make it easier.
Edit:
AbstractUrlHandlerMapping::getHandlerMap, which is inherited by the DefaultAnnotationHandlerMapping you're most likely using, returns a Map of URL to Handler
Return the registered handlers as an
unmodifiable Map, with the registered
path as key and the handler object (or
handler bean name in case of a
lazy-init handler) as value.
So you could iterate over that looking for a suitable match, where "suitable match" is whatever you want.
You can get access to the request object in any JSP file without having to manually wire in or manage the object into the JSP. so that means you can get the url path off the request object, have a google into JSP implicit objects.
Here is a page to get you started http://www.exforsys.com/tutorials/jsp/jsp-implicit-and-session-objects.html
The problem with this is that there's no central router in SpringMVC where all routes are registered and ordered. Then reverse routing is not a static process and route resolution in the view layer can be hard to integrate.
Check out this project for a centralized router (like rails) and reverse routing in the view layer.

Categories