I'm using Spring MVC and I want to store request specific values somewhere so that they can be fetched throughout my request context. Say I want to set a value into the context in my Controller (or some sort of handler) and then fetch that value from some other part of the Spring request/response cycle (could be a view, view resolver, interceptor, exception handler, etc)... how would I do that?
My question is:
Does Spring MVC already provide a method to do what I described above?
If Spring doesn't have this functionality, any ideas on the best way to do this (by extending something maybe)?
Thanks!
If you need to pass an object from your controller to view, you can use Spring's ModelMap.
#RequestMapping("/list")
public String list(ModelMap modelMap) {
// ... do foo
modelMap.addAttribute("greeting", "hello");
return viewName;
}
on your view:
<h1>${greeting}</h1>
You could use sessionAttributes.
Session Attributes
I took the latest version of the api (3.1) since you didn't mention your version of spring.
Related
I created a Spring MVC project using a template that is created from the STS and this is what is generated in the controller:
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
//stuff
}
My question is, how does the locale and model variable get passed into the home method?
Also, what are the possible options for the objects that can be passed to the method?
The general answer is "Spring magic"; however, "Supported handler method arguments and return types" in the MVC chapter of the Spring reference guide has the exact answers to your questions.
The technical answer is through the use of SpringMVC HandlerAdapter mechanism.
By way of spring's DispatcherServlet, a Handler adapter is created and configured for each dispatched request.
I think the "spring magic" in this case is the AnnotationMethodHandlerAdapter located in the spring mvc packages. This adapter basically will be "mapped" to an HTTP request based on HTTP paths, HTTP methods and request parameters tied to the request.
So essentialy when the spring dispatcher servlet identifies a request with path "/", it will check for methods in it's container annotated with the RequestMapping annotation.
In your case it find's it...
Then the real magic begins...
Using java reflection, Spring will then resolve the arguments of your controller method. So in your case the Locale and model will automatically be passed to you. If you included another web like parameter, such as HttpSession, that will be passed to you.
I'm working with an API implemented with Spring Data Rest and I would need to handle the GET method like I can do with the #RepositoryEventHandler, which allows me to handle before/after save, create, delete...
The case is that I need to update the object to be returned gathering information from other APIs before returning it as the GET response.
Is there any way to handle the GET in spring data rest?
You probably need to use #RepositoryRestController for this. It lets you get stuff from the #Repository and then add new things to the response object. Pretty similar to #RestController, but keeps Spring Data REST’s settings, message converters, exception handling, and more.
you could add Interceptor implementing HandleInterceptor and add it to mapped inteceptor bean.
#Bean
public MappedInterceptor myMappedInterceptor() {
return new MappedInterceptor(new String[]{"/**"}, new MyInterceptor());
}
I am learning JAVA and Spring Framework. I wanted to know that is it possible in java to create Dynamic URL in spring framework using values from url and fetching from database.
I am trying to make URL Shortner in Java and I will need to lookup for url's short code in my database and as we all know, url shortner will look like "url/ShorTCode" and my script will look for "ShorTCode" keyword in database and will redirect to associated weblink.
So I wanted to know that is it even possible in JAVA and Spring? And one more thing, if I make something like this "url/yt/VIdeoCode" or "url/fb/UserProfile"
So it will look at yt object which will redirect to youtube link only and fb object which will redirect to facebook user profile.
I want to clarify that I am still learning JAVA, JSP and Spring but I want to keep this thing in my mind while I am learning so I can focus on some particular things.
Thank you all fro helping me.
If you're asking how your controller could respond with a dynamic redirect, the answer is either:
(1) Have the controller return a "redirect:" result instead of view name. It must be followed with an absolute url, and behavior might depend on your spring version and configuration, but basically it looks like this:
#RequestMapping(...)
public String myMethod(){
String url=... // database lookup, e.g. "http://myUrl"
return "redirect:"+url;
}
(2) Less elegant but sometimes useful: get direct access to the response. If your controller method has a parameter of type HttpServletResponse spring will automatically inject it. So:
#RequestMapping(...)
public String myMethod(HttpServletResponse resp){
...
response.sendRedirect(...)
}
I came across authentication code in my company's java code. The application is a set of several REST services built on Spring MVC. There is a method that gets called in one of the authentication services on the HttpServletRequest object called getHeader(). And the method retrieves an AuthId. Why would they use HttpServletRequest in a spring MVC application? What are the benefits of using this servlet type code in the spring app? What would this method do? Any alternatives?
Spring MVC provides a lot of fabulous abstractions on top of HttpServletRequest, so you can avoid its low-level implementation details. You rarely need to access it directly.
For example, you could get a header value like Content-Type like this:
#GET
#Path("/myService")
public Response doSomething(#HeaderParam("Content-Type") String contentType) {
...
}
But there are times when you do need to access the HttpServletRequest directly--usually when you are using another API that demands it. If you are using some other library with a method you need that takes HttpServletRequest, then you got to grab it from Spring MVC directly.
For example, check out this method in this random UrlUtil class:
public static String encodeUrlPathSegment(String pathSegment, HttpServletRequest httpServletRequest) {
//Get a path segment
}
You have no choice but to grab HttpServletRequest from Spring MVC.
Spring MVC is built on the Servlet API. Anything you could do with a Servlet, you can therefore do with Spring MVC. What the Spring MVC framework provides is a wrapper to code a web application in a specific architectural style. This wrapper adds behavior and some times simplifies tasks.
Why would they use HttpServletRequest in a spring MVC application?
In this case, because it is the most direct way to get the header.
What are the benefits of using this servlet type code in the spring
app?
Spring doesn't have to wrap anything. You get it directly from the source.
What would this method do?
Read the javadoc.
Any alternatives?
In a #Controller class' handler method, you can declare a parameter annotated with #RequestHeader and have Spring pass an argument that it retrieves from the HttpServletRequest headers.
This is, by default, restricted to #Controller methods annotated with #RequestMapping. If your service class is a HandlerInterceptor, Filter, or other type of class and simply has a reference to the HttpServletRequest object, there is nothing more you can do than retrieve it directly with getHeader(String).
Here is an alternative : Spring MVC define the parameter annotation #RequestHeader to read httpServletRequest headers :
#RequestMapping(...)
public #ResponseBody String myMethod(#RequestHeader String AuthId){
//the value of the parameter AuthId is the value of request header named AuthId
...
}
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.