Annotated Web MVC Controllers in Spring 2.5

Spring 2.5 introduces an approach for writing annotated Web MVC controllers, which we haven't been blogging about much yet… I'll take the opportunity to give you an overview of what Spring MVC is really about these days.
Spring MVC is essentially a request dispatcher framework, with a Servlet API variant and Portlet API variant. It operates very closely within its hosting environment - either Servlets or Portlets. Think about Spring MVC as providing foundational facilities and conveniences on top of the Servlet/Portlet container: e.g. flexible request mappings, separation between controller processing and view rendering phase, data binding, basic JSP tag libraries that complement the JSTL, etc. The building blocks of sophisticated HTTP request processing.
Spring MVC is a very flexible affair: Its core DispatcherServlet can not only host its native controllers but can adapt to any kind of action type. It can host plain HttpRequestHandlers that process HTTP-based remoting protocols: This is what Spring users leverage when they define HTTP invoker / Hessian / Burlap service exporters, or XFire exporters for Web Services. DispatcherServlet can even host arbitrary third-party Servlets, allowing those Servlets to be configured and managed by the Spring environment.
Spring 2.5's annotated controllers
So how does Spring 2.5's annotation-based controller approach fit into this picture? Quite simple: It is essentially an alternative controller type supported by the DispatcherServlet / DispatcherPortlet, not implementing a specific interface but rather using annotations to express request mappings for specific handler methods. It is primarily a next-generation style for implementing multi-action controllers, superseding Spring's good old MultiActionController class.
Let's have a look at an example, taken from the "imagedb" sample application that comes with the Spring distribution. (Note: This is the Spring 2.5 final version of "imagedb", slightly differing from the RC version.)
@Controller
public class ImageController {
private ImageDatabase imageDatabase;
@Autowired
public ImageController(ImageDatabase imageDatabase) {
this.imageDatabase = imageDatabase;
}
@RequestMapping("/imageList")
public String showImageList(ModelMap model) {
model.addAttribute("images", this.imageDatabase.getImages());
return "imageList";
}
@RequestMapping("/imageContent")
public void streamImageContent(@RequestParam("name") String name, OutputStream outputStream)
throws IOException {
this.imageDatabase.streamImage(name, outputStream);
}
@RequestMapping("/imageUpload")
public String processImageUpload(
@RequestParam("name") String name, @RequestParam("description") String description,
@RequestParam("image") MultipartFile image) throws IOException {
this.imageDatabase.storeImage(name, image.getInputStream(), (int) image.getSize(), description);
return "redirect:imageList";
}
@RequestMapping("/clearDatabase")
public String clearDatabase() {
this.imageDatabase.clearDatabase();
return "redirect:imageList";
}
}
What does this controller class really do - what's the point of its design? Let's go through it step by step…
@Controller and @RequestMapping
First of all, the class is annotated with the @Controller stereotype. This indicates that its methods should be scanned for request mappings. It also allows for autodetection through Spring 2.5's component scanning (<context:component-scan>) just like the other stereotypes @Component, @Repository and @Service. In the case of the "imagedb" sample, the ImageController is still defined explicitly through a <bean> tag - simply because autodetection only really pays off in case of a larger number of controllers.
The constructor is marked as @Autowired and accepts an argument of type ImageDatabase. This is core Spring 2.5 functionality, namely annotation-driven dependency injection: This constructor will be called passing in a Spring bean of type ImageDatabase, obtained by type from the Spring ApplicationContext. In our case, this is the central ImageDatabase service from the application's service layer.
The actual request mappings are expressed through @RequestMapping annotations at the method level. Each of those mappings binds to a specific HTTP path within the containing DispatcherServlet. The mapping path can also be inferred from the handler method name, with a common mapping pattern (e.g. "*.image") expressed at the type level - reusing the InternalPathMethodNameResolver as known from the good old MultiActionController!
So when using @RequestMapping at the type level, method-level annotations will 'narrow' the mapping for the specific handler methods. @RequestMapping allows for specifying HTTP request methods (e.g. method = RequestMapping.GET) or specific request parameters (e.g. params = "action=save"), all narrowing the type-level mapping for specific methods. Alternatively, @RequestMapping at the type level can also be combined with a good old Controller interface implementation - such as a SimpleFormController or MultiActionController.
Flexible handler method signatures
The mapping is what I would call the "obvious" part, since it's pretty clear what's happening there. Now, the not-so-obvious part: the handler method signatures. This is a very flexible affair, not being tied to very specific signatures like in the good old Controller or MultiActionController case. You could be using a standard HttpServletRequest / HttpServletResponse / ModelAndView signature, of course, but the real power lies in using more specific arguments.
The "imagedb" sample shows a couple of fundamental variants:
@RequestMapping("/imageList")
public String showImageList(ModelMap model) {
model.addAttribute("images", this.imageDatabase.getImages());
return "imageList";
}
For this handler method, the only argument to be resolved is a ModelMap. ModelMap is a part of Spring 2.0's redesigned ModelAndView object, encapsulating a collection of name-value attribute pairs that will be exposed to the view. The code above simply calls the ImageDatabase service to load a List of ImageDescriptor objects and exposes them under the attribute name "images". Alternatively, you could call the addAttribute variant without an attribute name, in which case the name will be inferred from the given value type (in our case here: "imageDescriptorList").
The return value is a String, simply indicating the name of the view to be rendered. Essentially, you could be writing the same method with no arguments and a ModelAndView return value - but the above is usually easier to read and avoids a dependency on the ModelAndView object. (Note that ModelMap is a generic class in the "ui" package, whereas ModelAndView is a rather specific class in the "web.servlet" package.)
@RequestMapping("/imageContent")
public void streamImageContent(@RequestParam("name") String name, OutputStream outputStream)
throws IOException {
this.imageDatabase.streamImage(name, outputStream);
}
This handler method shows a quite different use case. Its purpose is to stream image content from the database to the HTTP response. It writes the response directly, not forwarding to a view; hence its return type is void. It uses Spring 2.5's new @RequestParam annotation to receive an HTTP request parameter in the form of a method argument, as well as an argument of type OutputStream for a handle to the response stream. The actual loading of the image content is delegated to the ImageDatabase service again.
Alternatively, you could implement the same handler method with a more traditional HttpServletRequest / HttpServletResponse signature, gaining more control over the exact HTTP processing. However, this introduces stronger coupling to the Servlet API and takes a bit more effort to unit-test.
@RequestMapping("/imageContent")
public void streamImageContent(HttpServletRequest request, HttpServletResponse response)
throws IOException {
this.imageDatabase.streamImage(request.getParameter("name"), response.getOutputStream());
}
The purpose of such handler methods should already become apparent: They are quite simple 'bridges' between the HTTP request world and the service layer world, adapting request parameters and response contents. Let's have a look at the image upload handler for an advanced example.
@RequestMapping("/imageUpload")
public String processImageUpload(
@RequestParam("name") String name, @RequestParam("description") String description,
@RequestParam("image") MultipartFile image) throws IOException {
this.imageDatabase.storeImage(name, image.getInputStream(), (int) image.getSize(), description);
return "redirect:imageList";
}
The basic purpose is again accepting a couple of specific HTTP request parameters, doing some processing, then returning the name of a view - in this case indicating a redirect to the "imageList" path. However, this particular method processes a multipart file upload, which is why the "image" argument is declared as type MultipartFile. Spring's @RequestParam processing will automatically resolve this as multipart element, so that the handler method is able to obtain the file size and to access the uploaded file contents as InputStream.
For a full list of argument types supported for annotated handler methods, see the @RequestMapping javadoc.
Beyond stateless multi-action controllers
So much for using Spring 2.5's web annotations to implement multi-action controllers. The same controller style can also accommodate basic form handling, superseding the good old SimpleFormController. This can be seen in the Spring 2.5 version of PetClinic, which has all of its form controllers implemented in the annotation style now, showing the use of form objects and JavaBean-based data binding. A discussion of those form handling capabilities will be the subject of a follow-up post.
Let me conclude with pointing out where Spring MVC's purpose ends: exactly with stateless controllers, basic form handling and flexible view rendering. MVC is fundamentally a dispatching-centric module of Spring's core web support, serving as runtime for many different kinds of usages - and with higher-level functionality to be built on top. In that respect, it is similar to Java EE 5's JSF runtime, which also primarily serves as a basic web platform to build higher-level functionality on top of.
This is where Spring Web Flow enters the picture: SWF is our higher-level, conversation-oriented controller engine, with strong support for both MVC views and JSF views. I strongly recommend checking out SWF for building web user interfaces, in particular when facing non-trivial navigation and state management needs. There is exciting stuff happening in the Spring Web Flow 2.0 milestones, aligned with where the Spring 2.5 MVC foundation is going - but also with a particularly strong focus on JSF, through our new Spring Faces module. Watch this space!
Solomon says:
Added on November 14th, 2007 at 2:41 pmI'm pretty excited about the Controller annotation changes. As a Spring MVC user, I think it's going to take me some time to understand the new approach really well. That effort, IMHO, will be well worth it.
The following documentation seems like a logical follow up for the information in this post:
http://static.springframework.org/spring/docs/2.5.x/reference/mvc.html#mvc-annotation
The information I found there on WebDataBinders, reference data creation and Validation are invaluable.
The way that @ModelAttribute is used to express reference data to be used by the view, seems to be pretty similar to WebBean's "outjection." Could this be the start of "conversational semantics" in Spring?
I would like to ask for an extension of the annotation processing: Validation based on annotations in the "Form/Command" objects. There are plenty of frameworks that already support that kind of functionality including both Hibernate and Stripes.
Solomon says:
Added on November 14th, 2007 at 2:45 pmI'm looking forward to SWF and Spring Face. It looks like the Spring community is already adding features on top of the @Controller base:
http://blog.digitalascent.com/2007/11/gwt-rpc-with-spring-2x_12.html - GWT/Spring @MVC integration
Juergen Hoeller (blog author) says:
Added on November 14th, 2007 at 3:13 pmHi Solomon - thanks for your kind words!
With respect to @ModelAttribute: This is essentially just a declarative form of calling ModelMap.addAttribute - semantically quite different from outjection to managed scopes. In other words, it is a purely MVC request processing based concept and doesn't imply any kind of conversation management. This is in line with Spring's core MVC module being a request dispatcher foundation with focus on stateless controller processing.
That aside, the Web Beans spec doesn't have outjection anymore, since they eventually figured that it doesn't add much value per se (that you couldn't achieve with other, equally simple means). So it's only really Seam that has outjection/bijection, to be turned into legacy once they aim for Web Beans compliance - as far as I understand.
Conversation management is one of the central themes in Spring Web Flow, as is explicit navigation management. I strongly recommend checking out the latest SWF 2.0 milestone if you're interested in the direction that the Spring portfolio is going there! The unified web user interface solution in the Spring stack is going to be SWF-based, with a choice between MVC and JSF views. Stay tuned!
Validation is still an ongoing topic. At present we allow for calling any kind of validation from within handler methods, registering validation errors on the passed-in Errors (or BindingResult) object. You can call traditional Spring Validators there but also custom validator objects or validation processors that operate based on annotations in the command/form class. We might be providing integration with specific validation solutions on the way forward. For the time being, it should be reasonably straightforward to implement a custom adapter for your preferred validation solution (if desired).
Juergen
Jing Xue says:
Added on November 15th, 2007 at 10:23 amI just wanted to (shamelessly) plug in a blog post I just wrote last night about the unintrusiveness of Spring 2.5's new annotation based injection feature. Albeit not directly related to Spring MVC, I just thought that it might serve as a complementary piece:
http://www.digizenstudio.com/blog/2007/11/14/spring-25s-unintrusive-annotation-based-configuration/
Peter Mularien says:
Added on November 15th, 2007 at 10:36 amThanks for posting this Juergen - it's a great overview. Are you guys planning on doing a webcast focused on the Spring Web technologies? If not, I'll be the first to suggest that it would be widely viewed
Jorge says:
Added on November 15th, 2007 at 4:22 pmHey Juergen,
This looks very cool and flexible, but lately I've been enjoying a lot lately some non-java frameworks that make it very easy to create web applications using RESTful architectures, so I can't help to ask, What is the point of view of the Spring MVC team regarding REST? Can we expect some out-of-the-box support for it in the near future?
I'm pretty sure it's already possible to create RESTful applications with Spring MVC, what I'd love to have is a set of classes that make it not only possible but easy
Dmitriy Kopylenko says:
Added on November 15th, 2007 at 6:10 pmJorge,
check out Restlet: http://www.restlet.org It's quite nice.
I've created a "custom" Spring/Restlet integration (it's a bridge between Spring DispatcherServlet and Restlet engine based on Spring's HandlerAdapter machinery), so Restlet "Resources" and regular Spring MVC app could happily co-exist in the same ServletContext.
Jorge says:
Added on November 16th, 2007 at 7:53 amHi Dimitry,
I know Restlet and although I haven't used it it looks very good. In fact a nice integration with Spring would give it what it's currently missing. Is your adaptation available under an OpenSource license?
It would be great to have it included and supported in the Spring distribution. Hava you suggested it? If so, did you get any answer back?
Alexandre Poitras says:
Added on November 17th, 2007 at 9:22 amHi Juergen,
I was wondering if it's possible to define a bean as a "scoped proxy" using the Scope annotation?
Dmitriy Kopylenko says:
Added on November 19th, 2007 at 9:07 amJorge,
the integration is simply the "home backed" one at the moment (it's not huge) and I've done it simply to quickly move on one of the projects we're doing with REST (with pressing deadlines, etc.). I simply do not have enough time at the moment, but once the project is over, I could suggest it to the community and may be it could find a home in the Spring modules or something.
In a nutshell, it uses implementation of Spring's HttpRequestHandler which is configured with Restlet's SpringRouter (mapping of the URI templates to Resources) and Restlet's ServletConverter which is the adapter between Servlet API and Restlet API.
Then the distinct DispatcherServlet is configured to route all the requests (i.e. /api/*) to this restlet handler, etc.
Then the final piece is that since Restlet resources are instantiated by the Restlet engine for each request, I use Spring's @Configurable and AspectJ machinery to inject the dependencies into them during 'newing…'.
It works quite well so far.
As Juergen mentioned, Spring's DispatcherServlet machinery is quite good for plugging different request processing work flows into it!
Dmitriy Kopylenko says:
Added on November 19th, 2007 at 9:12 amJuergen,
is there any way to consider adding Restlet support to one of the Spring's portfolio projects (could very well live under Spring remoting subsystem) as RESTful style and Restlet engine is getting popular by the day?
Regards,
Dmitriy.
Stevie Braga says:
Added on November 28th, 2007 at 1:57 pmThis annotation stuff is a really nice feature!
I've tried some types of controller, like SimpleFormController, MultiActionController and Abstract Controller with annotations. They worked pretty fine, but I got a problem trying to create a WizardFormController with annotations!
Is it possible? Have you already done something like that?
Juergen Hoeller (blog author) says:
Added on November 28th, 2007 at 2:53 pmStevie,
The only annotation-based wizard form controller that's included in the Spring 2.5 final distribution is the PetsController in the PetPortal sample application. This is designed for a Portlet environment, but nevertheless: The "showPetForm" and "submitPage" methods together implement the entire wizard flow there. The only difference in a Servlet environment would be that you'd return a view or send an HTTP redirect instead of setting a "render parameter" (the Portlet way of instructing the view).
In any case, the annotation-based style is certainly more "free-form" than the traditional SimpleFormController / AbstractWizardFormController style. This means that you can freely choose page parameters etc. The resulting code is a bit less explicit than SFC/AWFC based code but certainly much more flexible.
Finally, for applications with complex forms and complex navigation rules, I strongly recommend Spring Web Flow. SWF introduces the notion of an explicit flow definition as a more explicit way of defining page interactions; a pre-built, higher-level flow controller engine instead of manually constructed navigation in loosely related handler methods.
Juergen
Juergen Hoeller (blog author) says:
Added on November 28th, 2007 at 4:20 pmDmitriy,
We certainly do consider REST support! We'll present our current plans there around TSE. A hint: Take JAX-RS and Spring 2.5 style annotated handlers and you're pretty close
Juergen
Adam Taft says:
Added on December 1st, 2007 at 11:34 pm"We certainly do consider REST support! We'll present our current plans there around TSE. A hint: Take JAX-RS and Spring 2.5 style annotated handlers and you're pretty close :-)"
I'm overly excited about this! Very encouraging to hear. We're using the new annotation style for several REST services. Spring could definitely help make this a little easier, though. Would love to contribute to an effort in this direction, maybe email me?
WRT Restlet, it's a fine project and all, but it's getting too bloated and is trying to be its own complete framework instead of fitting in with other frameworks. I don't think it's necessary to consider them in the stack at all, particularly if you're just going to support REST style directly via JAX-RS annotations (as you imply).
Adam
Dmitriy Kopylenko says:
Added on December 4th, 2007 at 2:00 pmWell, there is JAX-RS RI called Jersey, if that helps: https://jersey.dev.java.net/
Regards,
Dmitriy.
Josh Devins says:
Added on December 6th, 2007 at 1:10 pm[quote post="236"]Well, there is JAX-RS RI called Jersey, if that helps: https://jersey.dev.java.net//quote
For those that haven't looked at it yet, it's not the most usable implementation for a Spring user. I have no doubt that the Spring support for JSR-311 will be much more usable for those not on Glassfish and using NetBeans.
Hans says:
Added on December 17th, 2007 at 5:54 amNice article.
I have tried to mix annotation based mapping with the previous SimpleUrlHandlerMapping, when i use DefaultAnnotationHandlerMapping they work together without any problem, but if i use AnnotationMethodHandlerAdapter to be able to register a WebBindingInitializer all the mappings from SimpleUrlHandlerMapping stop working.
Anyway, this approach it's taking us to a faster web tier development of our enterprise web apps.
Hey i enjoyed a lot TSE2007.
Nice work!!
Hans Ospina
John Coleman says:
Added on January 7th, 2008 at 1:17 pm@Juergen: Where are the REST support plans you promised! We're dying for them over here.
Anonymous Hero says:
Added on January 7th, 2008 at 1:18 pmJuergen: Where are the REST support plans you promised? I have searched and search to no avail - I'm really looking forward to implementing this in my own applications.
Juergen Hoeller (blog author) says:
Added on January 7th, 2008 at 5:43 pmYou caught me there
We have decided to postpone the full-scale REST support plans for a further while, which is why we haven't announced the full story yet.
The basic idea is that we'll be supporting REST style mappings through annotations as well, very similar to Spring 2.5's @MVC style. We're also aiming to stay close to the JAX-RS API, although that API turned out to be not quite ideal for our purposes in the details. The final decision hasn't been made there yet, though.
So you can expect us to come up with a full-blown REST story in the first half of 2008. I'm afraid I can't give a more concrete schedule at this point…
Juergen
Juergen Hoeller (blog author) says:
Added on January 7th, 2008 at 5:47 pmHans, I guess what you're missing in your setup is a org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter definition. If you're defining an AnnotationMethodHandlerAdapter explicitly, you have implicitly turned off all default adapters, which is why you need to define a SimpleControllerHandlerAdapter (for the Controller interface) explicitly then.
Juergen
Jeevan Edakkunath says:
Added on January 8th, 2008 at 9:29 amHi,
I am Jeevan Edakkunnath,a java/j2ee developer from India,I am a beginner in Spring.I was trying to develop a web application with spring frame work,i am getting the follwing exception,
"javax.servlet.jsp.JspTagException: Neither BindingResult nor plain target object for bean name 'backingObject' available as request attribute"
If you can help me on this regard i will be thank full to you.I posted in spring forums also.with liitle success.I want the flow of spring web application,especially i want the controller flow,there i am lagging.(From forums ,i got i have to bind the ModelAndView object to the request object,I tried alot,but i dont know how to do it.)
Expecting your valuable reply.
Thanking you
Jeevan EM
Ilya Boyandin says:
Added on January 9th, 2008 at 12:33 pmHello Jürgen,
Thanks for the nice intro! I use annotated controllers in my project already and I find them very convenient and useful. The only thing I am not sure about is the necessity of making the form objects session attributes. In the examples which use the new annotated style (e.g. in the docs and in petclinic) you always do so. Putting a form object into the session means that it can be potentially accessed by several threads at once and hence must be thread safe, right? If the user opens the same page in another browser tab or just clicks the submit button twice - nasty things can happen otherwise. But making objects thread-safe comes at a high price, so I think that in most cases the old controller style (where formBackingObject() was simply called once again upon submission to recreate the form object) should be preferred. Is it possible to avoid making the form object a session attribute within an annotated form controller? Or am I worried too much about this?
Thanks in advance.
Juergen Hoeller (blog author) says:
Added on January 10th, 2008 at 5:50 pmIlya, thanks for your kind words!
Regarding session attributes: You can simply omit @SessionAttributes as well. Any form objects that you're using in your handler methods will then be reinstantiated for every request. This is very similar to the good old SimpleFormController's choice between session and non-session mode. You may also define @ModelAttribute annotated methods (called for every request) that reobtain a model object in a custom fashion, similar to SFC's formBackingObject in non-session mode.
Session attributes can at present only be stored in the global session, analogous to the session mode in SimpleFormController. The typical solution there is not to make those session-scoped objects thread-safe; it is rather to introduce the notion of a "conversational session" (in its simplest form equivalent to scoping per browser window). This is what Spring Web Flow covers in the Spring portfolio at present, albein in a much more sophisticated fashion.
We consider providing simple window isolation for Spring MVC as well, transparently behind @SessionAttributes (i.e. as a configuration option, with no change to controller code). The problem there is identifying the current conversation window for each request. We intend to build support for this into Spring's form tag library: The form tags should be able to pick up and re-submit a sort of window id automatically, taking precedence over the less specific session id.
Juergen
David Cheong says:
Added on January 16th, 2008 at 6:21 pmHi Juergen,
First of all, thank you for version 2.5 - I find the annotations a refreshing approach to xml configuration and it is very liberating.
I'm also looking into the new annotation approach to SpringMVC and have a similar concern to Ilya Boyandin in the sense that I am not comfortable wit using @SessionAttributes. There's something I don't understand in your follow up post, namely reobtaining the object via @ModelAttribute.
I have found if I have a jsp which does not submit all the attributes of the model object (eg Pet), that the resulting Pet object obtained via @ModelAttribute isn't fully populated. I have tried to map the setupForm to both RequestMethod.GET and RequestMethod.POST hoping it would be called in a form submission and thus act more like formBackingObject() but the AnnotationMethodHandlerAdapter appears to only pick up on GET and one POST handler (I think).
So I'm unclear about what the right way of implementing the same SFC's behaviour without using session attributes and without requiring my jsp to repost every single form attribute?
All help appreciated.
dave
Dave Cheong says:
Added on January 18th, 2008 at 6:54 amJust wanted to add that I've managed to come up with a combination which works for me - no session attributes and jsp forms which do not require all attributes of the command object to be posted.
Instead of relying on a method (eg setupForm) which is mapped with @RequestMapping(method = RequestMethod.GET) to retrieve my command object, I use a method annotated with @ModelAttribute("commandName") to do it instead - ie treat it like any other reference data.
This allows me to have a solution more like SFC's formBackingObject() because methods which are annotated with ModelAttribute are called *always* and *before* RequestMethod annotated methods are called.
For example, I've found the following combination to work best:
// always called and before handleGet and handlePost
@ModelAttribute("pet")
public Pet retrieve(@RequestParam("id")long id) {
return petService.findById(id);
}
@RequestMapping(method = RequestMethod.GET)
public String handleGet(@ModelAttribute("pet")Pet pet) {
// note: pet parameter is required though not used in order to have the binder
// instantiated with all the custom editors set
return "petForm";
}
@RequestMapping(method = RequestMethod.POST)
public String handlePost(@ModelAttribute("pet")Pet pet, BindingResult result) {
System.out.println("pet = " + pet);
petValidator.validate(pet, result);
if (result.hasErrors()) {
// simple redisplay the form
return "petForm";
}
else {
// save and redirect to avoid browser's repost dialogs on refresh
petService.save(pet);
return "redirect:/pet/edit.do?id=" + pet.getId();
}
}
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
I'm not sure if my solution follows the intended design, but it works and is relatively clean without the need to inherit any base classes or declare alternate/additional HandlerAdapters. If there's a better way which I'm missing out on, please share.
thanks,
dave
Vernon says:
Added on January 23rd, 2008 at 6:31 pmHow I can configure an interceptor with an annotated controller? I can't find this subject in the reference documentation.
surajz shres says:
Added on February 26th, 2008 at 1:37 pmyou can do something like
surajz shres says:
Added on February 26th, 2008 at 1:39 pm<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<list></list>
</property>
</bean>
Ram says:
Added on March 17th, 2008 at 6:29 amI get the following exception when I add component scan tag to the context
nested exception is java.lang.NoSuchMethodError: getBeanDefinitionDefaults
Caused by:
java.lang.NoSuchMethodError: getBeanDefinitionDefaults
at org.springframework.context.annotation.ComponentScanBeanDefinitionParser.configureScanner(ComponentScanBeanDefinitionParser.java:99)
at org.springframework.context.annotation.ComponentScanBeanDefinitionParser.parse(ComponentScanBeanDefinitionParser.java:83)
at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:69)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1114)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1104)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:133)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:90)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:458)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:353)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
Am I missing any thing here..
cheers
ram
David J. M. Karlsen says:
Added on May 28th, 2008 at 9:27 amI really like the new annotation based stuff - and I don't see any specific need to stick with the 2.0 stuff which required inheritance and interface implementations - other that I now have to call the Validators by hand. I've got two questions:
-What will be preferred in the 3.x series? Will the inheritance based stuff be deprecated in favour of the @nnotated MVC stuff?
-I can't see any branches in CVS for spring 3.0. Has it moved to SVN/other repo? Or hasn't the branch been born yet?
Juergen Hoeller (blog author) says:
Added on May 28th, 2008 at 1:04 pmThe Spring Framework 3.x series will definitely feature the @MVC approach as primary usage model. We do indeed plan to deprecate the inheritance-based form controllers completely, with the 3.0 reference documentation covering the @MVC approach only.
There is no branch for Spring 3.0 yet. We will create that branch in a revised SVN repository structure for the Spring Framework project - probably in late June. We are working on various 3.0 features already but not in publicly visible repositories at this point…
Juergen
Plus Tc says:
Added on June 10th, 2008 at 7:48 am@RequestMapping("/imageContent")
public void streamImageContent(@RequestParam("name") String name, OutputStream outputStream)
throws IOException {
this.imageDatabase.streamImage(name, outputStream);
}
Thansk man..Good job..
surajz sh says:
Added on July 9th, 2008 at 1:48 pm[quote comment="100859"]I get the following exception when I add component scan tag to the context
nested exception is java.lang.NoSuchMethodError: getBeanDefinitionDefaults
Caused by:
java.lang.NoSuchMethodError: getBeanDefinitionDefaults
at org.springframework.context.annotation.ComponentScanBeanDefinitionParser.configureScanner(ComponentScanBeanDefinitionParser.java:99)
at org.springframework.context.annotation.ComponentScanBeanDefinitionParser.parse(ComponentScanBeanDefinitionParser.java:83)
at org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:69)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1114)
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1104)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:133)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:90)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:458)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:353)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
Am I missing any thing here..
cheers
ram[/quote]
You need to include AnnotationMethodHandlerAdapter also
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors"><list></list></property>
</bean>
Tobias says:
Added on August 14th, 2008 at 6:45 amHello, I've been converting a site from old 2.0 Spring without annotations to Spring 2.5 with the @MVC annotions (like @Controller, @RequestMapping & similar. However there was a problem with edit forms, the preopopulated values where simply not there (inputs all empty). The object was still in the view though, since I outside the form tag could do c:out and read it. You say
[quote post="236"]With respect to @ModelAttribute: This is essentially just a declarative form of calling ModelMap.addAttribute[/quote]
HOWEVER I've tried several methods with success:
view.addObject("resident", r); // this was enough with Spring 2.0
view.getModel().put("resident", r); // made no difference
view.getModelMap().addAttribute("resident", r); // made no difference
My editform is STILL empty. I experimented around & the ONLY way to get it to work is with an annotated method
@ModelAttribute("resident")
public Resident createCommand(@RequestParam(value = "residentid", required = false) final Integer id) {
debug("createCommand called, residentId: " id);
return (id == null || id
Tobias says:
Added on August 18th, 2008 at 3:04 am@ModelAttribute("resident")
public Resident createCommand(@RequestParam(value = "residentid", required = false) final Integer id) {
debug("createCommand called, residentId: " id);
return (id == null || id
Tobias says:
Added on August 27th, 2008 at 6:08 ambut that should not be needed you say. I can buy that you now have to/should write modelMap.addAttribute(..) instead of modelAndView.addObject(..) now but not that you are FORCED to write that extra @ModelAttribute annotated method which I find somewhat less logical. I prefer to see what is stored in the modelAndView/modelMap to be sent to the view. Please advice & explain how this works in more detail.
One a sidenote, can someone pls confirm that modelAttribute & commandName is two names for the same thing? This doc suggests exactly that http://static.springframework.org/spring/docs/2.5.x/reference/spring-form.tld.html#spring-form.tld.form
Regards (sorry for multiposts, textlimit was too low)
BFranklin says:
Added on August 31st, 2008 at 8:04 pmIt is good to see this site with good responses. We are using Spring MVC 2.5.x annotation controllers. We love it. Almost all controllers performs certain common tasks such as Creating Logged User from the request, Checking for any "ErrorMsg" code in the request to add to the BindingResult etc. How do I have a common class to do this controller specific common tasks before processing a requested annotated controller? I looked into HandlerInterceptor, but there is no way to get the Model Attribute and BindingResult. Any suggestions, would be really appreciated..
Ghani says:
Added on September 9th, 2008 at 6:00 amHi,
Can you please send me the source code of this sample.
Thanks in advance.
Chad LaVigne says:
Added on September 25th, 2008 at 9:18 pmHi Juergen,
I've been using Spring 2.5 annotation based MVC since it came out and I still can’t believe how much I like it. I read this blog a while ago and had the same question as Solomon about annotation based form bean validation. Are there any plans to implement something like that in an upcoming release? If not, does the Spring team accept contributions? I really wanted to be able to just tag a command object's properties with a validation annotation and have them validated, without having to extend classes, override methods, etc. I've created such a solution using Spring AOP, two annotations and the Jakarta commons validation library. It allows you to annotate the fields on a command object with things like @ValidationField(required=true,creditcard=true) to have them validated. When validation fails, error messages are placed on the binding result which are displayed via the form:errors tag - just like the existing Spring type checking validation that happens when values are bound to a command object. Mirroring other Spring annotation based MVC configuration, you just make one config entry and from then on, no more configuration is necessary; you simply annotate your form beans as you write them. I have found it to be a very simple and satisfying solution and I thought that perhaps others could benefit from it. Anyway, I saw that I could make an enhancement request at http://www.springframework.org/development but didn’t see an area to submit code contributions so figured I’d ask you about it here. Would your team be interested in evaluating this solution to consider it as a contribution to the project?
Chad
Chad LaVigne says:
Added on October 7th, 2008 at 12:38 pmJuergen,
Please disregard my last post, I found the Spring modules site with the annotation based validation. That's exactly what I was looking for, thanks for adding it. For anyone reading this that is interested here's the link: https://springmodules.dev.java.net/docs/reference/0.8/html_single/#d0e9699.
Chad