Annotated Web MVC Controllers in Spring 2.5

Juergen Hoeller

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!

 

35 responses


  1. I'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.


  2. I'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


  3. Hi 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


  4. I 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/


  5. Thanks 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 :)


  6. Hey 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 :)


  7. Jorge,

    check out Restlet: 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.


  8. Hi 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?


  9. Hi Juergen,

    I was wondering if it's possible to define a bean as a "scoped proxy" using the Scope annotation?


  10. Jorge,

    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!


  11. Juergen,

    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.


  12. This 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?


  13. Stevie,

    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


  14. Dmitriy,

    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


  15. "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


  16. Well, there is JAX-RS RI called Jersey, if that helps: https://jersey.dev.java.net/

    Regards,
    Dmitriy.


  17. [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.


  18. Nice 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


  19. @Juergen: Where are the REST support plans you promised! We're dying for them over here.


  20. Juergen: 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.


  21. You 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


  22. Hans, 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


  23. Hi,
    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


  24. Hello 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.


  25. Ilya, 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


  26. Hi 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


  27. Just 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


  28. How I can configure an interceptor with an annotated controller? I can't find this subject in the reference documentation.


  29. you can do something like


  30. <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
    <list>&lt/list>
    </property>
    </bean>


  31. 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


  32. I 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?


  33. The 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


  34. @RequestMapping("/imageContent")
    public void streamImageContent(@RequestParam("name") String name, OutputStream outputStream)
    throws IOException {

    this.imageDatabase.streamImage(name, outputStream);
    }

    Thansk man..Good job..


  35. [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>

10 trackbacks

Leave a Reply