REST in Spring 3: @MVC

In the last couple of years, REST has emerged as a compelling alternative to SOAP/WSDL/WS-*-based distributed architectures. So when we started to plan our work on the next major release of Spring – version 3.0, it was quite clear to us that we had to focus on making the development of 'RESTful' Web services and applications easier. Now, what is and isn't 'RESTful' could be the topic of a whole new post all together; in this post I'll take a more practical approach, and focus on the features that we added to the @Controller model of Spring MVC.
A Bit of Background
Ok, I lied: there is some background first. If you really want to learn about the new features, feel free to skip to the next section.
For me, work on REST started about two years ago, shortly after reading the highly recommended book RESTful Web Services from O'Reilly, by Leonard Richardson and Sam Ruby. Initially, I was thinking about adding REST support to Spring Web Services, but after working a couple of weeks on a prototype, it became clear to me that this wasn't a very good fit. In particular, I found out that I had to copy most of the logic from the Spring-MVC DispatcherServlet over to Spring-WS. Clearly, this was not the way to go forward.
Around the same time we introduced the annotation-based model of Spring MVC. This model was clearly an improvement to the former, inheritance-based model. Another interesting development at that time was the development of the JAX-RS specification. My next attempt was to try and merge these two models: to try and combine the @MVC annotations with the JAX-RS annotations, and to be able to run JAX-RS applications within the DispatcherServlet. While I did get a working prototype out of this effort, the result was not satisfactory. There were a number of technical issues which I won't bore you with, but most importantly the approach felt 'clunky' and unnatural for a developer who was already used to Spring MVC 2.5.
Finally, we decided to add the RESTful functionality to features to Spring MVC itself. Obviously, that would mean that there would be some overlap with JAX-RS, but at least the programming model would be satisfactory for Spring MVC developers, both existing and new ones. Additionally, there are already three JAX-RS implementations offering Spring support (Jersey, RESTEasy, and Restlet). Adding a fourth to this list did not seem a good use of our valuable time.
RESTful features in Spring MVC 3.0
Now, enough of the background, let's look at the features!
URI Templates
A URI template is a URI-like string, containing one or more variable names. When these variables are substituted for values, the template becomes a URI. For more information, see the proposed RFC.
In Spring 3.0 M1, we introduced the use of URI templates through the @PathVariable annotation. For instance:
@RequestMapping("/hotels/{hotelId}")
public String getHotel(@PathVariable String hotelId, Model model) {
List<Hotel> hotels = hotelService.getHotels();
model.addAttribute("hotels", hotels);
return "hotels";
}
When a request comes in for /hotels/1, that 1 will be bound to the hotelId parameter. You can optionally specify the variable name the parameter is bound to, but when you compile your code with debugging enabled that is not necessary: we infer the path variable name from the parameter name.
You can also have more than one path variable, like so:
@RequestMapping(value="/hotels/{hotel}/bookings/{booking}", method=RequestMethod.GET)
public String getBooking(@PathVariable("hotel") long hotelId, @PathVariable("booking") long bookingId, Model model) {
Hotel hotel = hotelService.getHotel(hotelId);
Booking booking = hotel.getBooking(bookingId);
model.addAttribute("booking", booking);
return "booking";
}
This would match requests like /hotels/1/bookings/2, for instance.
You can also combine the use of Ant-style paths and path variables, like so:
@RequestMapping(value="/hotels/*/bookings/{booking}", method=RequestMethod.GET)
public String getBooking(@PathVariable("booking") long bookingId, Model model) {
...
}
and you can use data binding, too:
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
@RequestMapping("/hotels/{hotel}/dates/{date}")
public void date(@PathVariable("hotel") String hotel, @PathVariable Date date) {
...
}
The above would match /hotels/1/dates/2008-12-18, for instance.
Content Negotiation
In version 2.5, Spring-MVC lets the @Controller decide which view to render for a given request, through its View, view name, and ViewResolver abstractions. In a RESTful scenario, it is common to let the client decide the acceptable representations, via the Accept HTTP header. The server responds with the delivered representation via the Content-Type header. This process is known as content negotiation.
One issue with the Accept header is that is impossible to change it in a web browser, in HTML. For instance, in Firefox, it's fixed to
So what if you want to link to a PDF version of a particular resource? Looking at the file extension is a good workaround. For example, http://example.com/hotels.pdf retrieves the PDF view of the hotel list, as does http://example.com/hotels with an Accept header of application/pdf.
This is what the ContentNegotiatingViewResolver does: it wraps one or more other ViewResolvers, looks at the Accept header or file extension, and resolves a view corresponding to these. In an upcoming blog post, Alef Arendsen will show you how to use the ContentNegotiatingViewResolver.
Views
We also added some new Views to Spring MVC, particularly:
- the AbstractAtomFeedView and AbstractRssFeedView, which can be used to return an Atom and RSS feed,
- the MarshallingView, which can be used to return an XML representation. This view is based on the Object/XML Mapping module, which has been copied from the Spring Web Services project. This module wraps XML marshalling technologies such as JAXB, Castor, JiBX, and more, and makes it easier to configure these within a Spring application context,
- the JacksonJsonView, for JSON representations of objects in your model. This view is actually part of the Spring JavaScript project, which we'll talk about more in a future blog post.
Obviously, these work great in combination with the ContentNegotiatingViewResolver!
HTTP Method Conversion
Another key principle of REST is the use of the Uniform Interface. Basically, this means that all resources (URLs) can be manipulated using the same four HTTP method: GET, PUT, POST, and DELETE. For each of methods, the HTTP specification defines exact semantics. For instance, a GET should always be a safe operation, meaning that is has no side effects, and a PUT or DELETE should be idempotent, meaning that you can repeat these operations over and over again, but the end result should be the same.
While HTTP defines these four methods, HTML only supports two: GET and POST. Fortunately, there are two possible workarounds: you can either use JavaScript to do your PUT or DELETE, or simply do a POST with the 'real' method as an additional parameter (modeled as a hidden input field in an HTML form). This latter trick is what the HiddenHttpMethodFilter does. This filter was introduced in Spring 3.0 M1, and is a plain Servlet Filter. As such, it can be used in combination with any web framework (not just Spring MVC). Simply add this filter to your web.xml, and a POST with a hidden _method parameter will be converted into the corresponding HTTP method request.
As an extra bonus, we've also added support for method conversion in the Spring MVC form tags. For example, the following snippet taken from the updated Petclinic sample:
<form:form method="delete">
<p class="submit"><input type="submit" value="Delete Pet"/></p>
</form:form>
will actually perform an HTTP POST, with the 'real' DELETE method hidden behind a request parameter, to be picked up by the HiddenHttpMethodFilter. The corresponding @Controller method is therefore:
@RequestMapping(method = RequestMethod.DELETE)
public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
this.clinic.deletePet(petId);
return "redirect:/owners/" + ownerId;
}
ETag support
An ETag (entity tag) is an HTTP response header returned by an HTTP/1.1 compliant web server used to determine change in content at a given URL. It can be considered to be the more sophisticated successor to the Last-Modified header. When a server returns a representation with an ETag header, client can use this header in subsequent GETs, in a If-None-Match header. If the content has not changed, the server will return 304: Not Modified.
In Spring 3.0 M1, we introduced the ShallowEtagHeaderFilter. This is a plain Servlet Filter, and thus can be used in combination any web framework. As the name indicates, the filter creates so-called shallow ETags (as opposed to a deep ETags, more about that later). The way it works is quite simple: the filter simply caches the content of the rendered JSP (or other content), generates a MD5 hash over that, and returns that as a ETag header in the response. The next time a client sends a request for the same resource, it use that hash as the If-None-Match value. The filter notices this, renders the view again, and compares the two hashes. If they are equal, a 304 is returned. It is important to note that this filter will not save processing power, as the view is still rendered. The only thing it saves is bandwith, as the rendered response is not sent back over the wire.
Deep ETags are a bit more complicated. In this case, the ETag is based on the underlying domain objects, RDMBS tables, etc. Using this approach, no content is generated unless the underlying data has changed. Unfortunately, implementing this approach in a generic way is much more difficult than shallow ETags. We might add support for deep ETags in a later version of Spring, by relying on JPA's @Version annotation, or an AspectJ aspect for instance.
And more!
In a following post, I will conclude my RESTful journey, and talk about the RestTemplate, which was also introduced in Spring 3.0 M2. This class gives you client-side access to RESTful resources in a fashion similar to the JdbcTemplate, JmsTemplate, etc.
Similar Posts
- REST in Spring 3: RestTemplate
- Adding an Atom view to an application using Spring's REST support
- Pluggable styling with SpringSource Slices
- AOP Context Binding With Named Pointcuts
- Annotated Web MVC Controllers in Spring 2.5











Kris says:
Added on March 8th, 2009 at 8:12 pmIf I would just like to use REST capabilities as a way to expose some of our data(actually we have a desktop client app that is the main app but want to provide a REST API for integration scenarios), can we use Spring REST support. What I am trying to say is that we don't have any web based UI we are just tyring to expose the API via REST. I am tasked to recommend and right now I am ready to go with Jersey and I happen to see this post.
Philip says:
Added on March 8th, 2009 at 11:11 pmExcellent overview of the new Spring REST capabilities. I look forward to introducing these concepts to our development teams when Spring 3.0 is released. I really like the annotated approach to controllers, of which Spring REST annotations are a natural progression. Excellent work.
Also, thanks for the "behind the scenes" look at the planning/prototyping of these features. I wish our management would more "officially" support such prototyping efforts.
Web Mapping Services says:
Added on March 9th, 2009 at 12:05 amInformative thanks for sharing.
regards
SBL Geomatics
hatim says:
Added on March 9th, 2009 at 3:46 am@Philip
Any ideas when would that be happening (Spring 3.0 release)
Ben says:
Added on March 9th, 2009 at 4:36 amExcellent plan. What's even better is that it fits really nicely with the strategies I've already been using … it'll just make it easier to strip out some of my existing boiler-plate code. Typical Spring-yness.
Looking forward to Spring 3.0 with anticipation.
Juergen Hoeller (blog author) says:
Added on March 9th, 2009 at 8:20 amWith respect to the Spring Framework 3.0 release date…
Our current roadmap looks as follows: We'll do 3.0 M3 at the end of March; then we'll move on to the first release candidate which is expected in late April. Depending on RC feedback, the Spring 3.0 final release will follow soon after.
Now, in order to get there, you guys playing with our 3.0 milestones ahead of the RC1 release would be of great value
Phil Wills says:
Added on March 9th, 2009 at 1:13 pmI've been experimenting with the RequestMapping/PathVariable, RestTemplate and OXM and so far it's been a very pleasant experience. One thing which would potentially reduce boiler plate even further would be to have an XML HttpMessageConverter based around the OXM Unmarshaller and Marshaller interfaces.
Arjen mentions the JacksonJsonView in the post. This doesn't appear to be in the bundle of 3.0M2, so I was wondering whether he's just highlighting it's existence within Spring-JS, or if it's planned to be merged into the Spring core?
Arjen Poutsma (blog author) says:
Added on March 9th, 2009 at 2:49 pm@Phil
Thanks!
As for the JacksonJsonView, there are no plans to move it to the core at this time.
Michael says:
Added on March 9th, 2009 at 5:22 pmI have quite a bit of code using the existing javax.ws.rs.* annotations.
Why create new annotations?
Arjen Poutsma (blog author) says:
Added on March 9th, 2009 at 5:27 pm@Michael
We did not create new annotations, we extended the ones we already introduced in Spring 2.5.
Michael says:
Added on March 9th, 2009 at 5:47 pmI just noticed that as I was writing some code with Spring 2.5.
Maybe I could just create handlers for @PathParam/@Path/@ProduceMime and port my code over that way.
That might be fun.
Karthik says:
Added on March 9th, 2009 at 7:39 pmThe REST support looks cool. Do Spring controllers work with JSON payload as well in addition to usual form post ?
Basically I would like to submit a form through Ajax but not with usual query params as payload, but as a JSON string from the client.
thanks,
Karthik
Kim says:
Added on March 10th, 2009 at 4:00 pmFantastic! I struggled to wrangle Spring MVC 2.0 into a RESTful web service for well over a year. This is very welcome news!
Aditya says:
Added on March 10th, 2009 at 9:27 pmI remember you mentioning something about JAX-RS support in Spring at a Spring conference. Is it going to part of Spring 3.0 RC/Final? Is ContentNegotiatingResolver meant to provide the functionality of @ProduceMime? We are hoping that Alef's post on ContentNegotiatingResolver will make it clear to us on how it can resolve a MarshallingView or RssView etc depending on "Accept" header or extension etc.
Arjen Poutsma (blog author) says:
Added on March 11th, 2009 at 7:04 am@Aditya
We were thinking about adding support to JAX-RS in a way similar to our JAX-WS support, but I don't think there is any SPI in JAX-RS which allows us to do this in a consistent way across many JAX-RS implementations. Also, the fact that all major JAX-RS implementations already have Spring support makes this less necessary.
Alef Arendsen says:
Added on March 14th, 2009 at 10:12 pm@Aditya
yes, my post will cover that… Not for a MarshallingView but for an AtomFeedView. I'll post it next Monday.
cheers,
Alef
Aditya says:
Added on March 17th, 2009 at 10:31 amThank you Arjen & Alef for the clarification.
Grzegorz Borkowski says:
Added on March 18th, 2009 at 8:27 amI've experimented a bit with Spring 3.0, and have written an article "Test drive of Spring 3.0 Milestone 2 REST support" about my impressions. You may find it here: http://grzegorzborkowski.blogspot.com/2009/03/test-drive-of-spring-30-m2-rest-support.html
Hope you find it useful for further development of Spring REST support.
Viraf Karai says:
Added on March 20th, 2009 at 12:49 pmSpringSource is doing a great job with enhancements and each new release has substantially richer functionality compared to earlier versions. The core Spring framework is now pretty massive and it appears that the framework has been rapidly shedding XML in favor of annotations. I realize that a lot of Spring users don't necessarily like using XML. I've identified at least the following annotations in the core Spring framework (3.0)
• @Autowired
• @Component
• @Controller
• @InitBinder
• @ManagedAttribute
• @ManagedOperation
• @ManagedOperationParameters
• @ManagedOperationParameter
• @ManagedResource
• @PathVariable
• @PostConstruct
• @PreDestroy
• @Repository
• @RequestMapping
• @Required
• @Resource
• @Service
• @Transactional
May I humbly recommend that SpringSource provide an annotation cheat-sheet in the documentation with brief use-cases as well as configuration entries needed to activate each annotation e.g. . I deeply appreciate the efforts that you and the rest of the SpringSource team have expended to make Spring a key Java enterprise framework. The REST support in Spring MVC looks fantastic and I'm going to try it out soon.
Wei says:
Added on March 24th, 2009 at 2:44 pmIt is great to have REST feature in the Spring MVC. I can't wait to use it in my projects. Where I can access a reference documentation in the subject? I can't see any reference documentations in the new package 3.0.0 M2 other than API.
Arjen Poutsma (blog author) says:
Added on March 25th, 2009 at 5:10 am@Wei: there is no reference documentation yet, just the API docs and Petclinic sample at https://fisheye.springframework.org/browse/spring-framework/trunk/org.springframework.samples.petclinic. We hope to have more documentation in Milestone 3, and complete it in the RC phase.
Karthik says:
Added on April 1st, 2009 at 5:38 pmHow much work would it be to throw in an @Interceptor annotation for the MVC Controllers?
or may be support multiple interceptors as well through @Interceptors
@Interceptors([
@Interceptor(MyInterceptor.class)
@Interceptor(MyInterceptor.class)
])
?
Steven B says:
Added on April 10th, 2009 at 12:22 pmWill there be any JSF integration? Spring 2.5.6 is a real let down for JSF users. I love Spring MVC, but Spring Source provides no samples or documentation integrating JSF and Spring MVC, only Spring WebFlow, which is a poor fit for 98% of applications (most apps don't use conversation scope and need to be bookmarkable with out creating a flow for literally every page in your application).
Spring is leaving us with the choice of great support for primitive JSP/HTML views via MVC and poor support for anything other than complex worksflows if we want to use JSF.
Jamie says:
Added on April 11th, 2009 at 5:15 amApologies if this is a real newbie question or the wrong place to ask it, but is it possible to externalize and share the same URI definition between the @RequestMapping annotation and the code that builds the URLs?
e.g.
In the petshop code is something like:
@RequestMapping("/owners/{ownerId}")
and in the jsp is something like:
and if you change the structure of the url, you have to track down all the places that this URI definition exists (you'd have to do that anyway if the parameters changed, but I'm referring to just a change like "foo/owners/{ownerId}").
Also, out of curiosity, if you (lost your mind and) decided you no longer wanted RESTful urls, could you change your URI definition to: "owners?ownerId={ownerId}"?
Jamie says:
Added on April 11th, 2009 at 5:17 amoops – that missing jsp code is:
<spring:url value="owners/{ownerId}" var="ownerUrl">
<spring:param name="ownerId" value="${owner.id}"/>
</spring:url>
Boyan says:
Added on April 18th, 2009 at 7:19 amI started introducing Spring 3.0 a while ago, and I see REST features are widely used. It sounds interesting and useful, but there are things I don't like. (But maybe I am just making newbie mistakes). The thing I don't like is @RequestMapping annotation. Using that we are specifying url in java file. I don't think that's right place for that, xml file would be much prettier solution. Maybe I am thinking in old fashion way ( in "Spring 2.0 way" ), but I don't see this feature as really convenient.
Consider scenario Jamie mentioned in the post above mine: if you want to change url from "owners/{ownerId}" to "foo/owners/{ownerId}" you have to change value of @RequestMapping annotation, that means you have to recompile that java class! If that configuration is placed in xml file you wouldn't have to recompile. The same thing is for @PathVariable annotation. ( when I mentioned this, I have to say that I more prefer Struts2 actions and their style of binding parameters to class properties – without annotations)
I was talking about all this to my colleagues, and our opinion is that we don't like so much configuration placed in annotations (that means in .java file), we like Spring 2.0 way – xml configuration. Is it possible in Spring 3.0?
Vijay says:
Added on April 30th, 2009 at 6:14 pmI completely agree with Boyan et. al. While I am not averse to having the controllers use annotation based configuration, I would love to see a functionally equivalent XML based routing configuration, for those who would rather not use it. The current model, IMHO, has the following problems:
1. URL mapping is scattered all over the place. If I have 15 controllers, with 10 methods each (and note that there's the issue of each method potentially having a completely different URL that it can match), a newbie would have to look at 150 potential places to map a given URL to the controller action it resolves to. Admittedly, having good conventions and oversight will alleviate this problem, but seems too easy to have things go awry.
2. As Boyan mentioned, any changes to the mapping requires a recompile.
3. The same controller method cannot be mapped to multiple urls (or at least I can't figure out how to do it
), allowing different views to be driven by the same controller.
4. A somewhat minor thing. There is now way to write a controller w/o Spring dependencies.
Btw, It would be nice to have mappings that are pattern based, such as, a way to map /somepath/{method} to handler SomePathController, method {method}.
Boyan says:
Added on May 9th, 2009 at 1:08 pmGood point, Vijay!
Can someone of Spring officials share his opinion about this with us?
Arjen Poutsma (blog author) says:
Added on May 9th, 2009 at 3:14 pm@Vijay & Boyan:
Ad 1 & 2: Rossen wrote a post about combining XML and annotations a while ago. They key idea is to use XML for the course-grainined mappings, and annotations for further disambiguation. Check it out!
Ad 3:The @RequestMapping annotation allows for multiple paths as a String array, so you can map multiple urls to the same controller method.
Ad 4: It was never possible to write a controller for MVC without having Spring dependencies. Previously, you had to implement the controller interface, or extend from one of the base classes. I would say that the Spring dependency has become less with @MVC, now that we use annotations, since these are only necessary at compile time, not at runtime.
Nicolas Zozol says:
Added on May 10th, 2009 at 11:34 pmHi,
I'm also using REST, without Spring, everyday. I would like to know a little more about your security approach.
Would you use Authorization header, jsessionid or hash in cookies ? Does Spring implement a Digest authentication support ?
Thanx,
Nicolas
ramesh says:
Added on May 27th, 2009 at 4:34 amI have upgraded my project to use spring3.0.0.M2. When I tried to access my application I have seen the below error in console.
log4j:WARN No appenders could be found for logger (org.apache.commons.httpclient.HttpClient).
log4j:WARN Please initialize the log4j system properly.
returnCode –> 500
Apache Tomcat/6.0.16 – Error report HTTP Status 500 – type Exception reportmessage description The server encountered an internal error () that prevented it from fulfilling this request.exception javax.servlet.ServletException: Servlet.init() for servlet LogReaderDispatcher threw exception
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:619)
root cause org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/LogReaderDispatcher-servlet.xml]; nested exception is java.lang.NoClassDefFoundError: org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:394)
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:316)
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:284)
org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:93)
org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:125)
org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:418)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:348)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:427)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:341)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:307)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
javax.servlet.GenericServlet.init(GenericServlet.java:241)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:619)
root cause java.lang.NoClassDefFoundError: org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor
org.springframework.core.type.classreading.SimpleMetadataReader.getAnnotationMetadata(SimpleMetadataReader.java:54)
org.springframework.core.type.filter.AnnotationTypeFilter.matchSelf(AnnotationTypeFilter.java:68)
org.springframework.core.type.filter.AbstractTypeHierarchyTraversingFilter.match(AbstractTypeHierarchyTraversingFilter.java:55)
org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.isCandidateComponent(ClassPathScanningCandidateComponentProvider.java:252)
org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:192)
org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:201)
org.springframework.context.annotation.ComponentScanBeanDefinitionParser.parse(ComponentScanBeanDefinitionParser.java:83)
org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(NamespaceHandlerSupport.java:72)
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1291)
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1281)
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:135)
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:92)
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:475)
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:372)
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:316)
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:284)
org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:93)
org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:125)
org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:418)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:348)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:427)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:341)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:307)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
javax.servlet.GenericServlet.init(GenericServlet.java:241)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:619)
note The full stack trace of the root cause is available in the Apache Tomcat/6.0.16 logs.Apache Tomcat/6.0.16
Can any one please help me out?
Even I have spring.core package in my web-inf/lib folder.
Arjen Poutsma (blog author) says:
Added on May 27th, 2009 at 5:54 am@ramesh
This blog is not the proper place to ask for help. Did you try the Community Forums?
Thorsten says:
Added on June 30th, 2009 at 11:22 amThe lack of standards support is a little bit annoying.
The missing support for JSR 311 and description languages like WSDL 2.0 or WADL leads to not portable implementations and the support in IDE's is always incomplete. Another view is the usability by users (generating of client stubs, test clients, …)
I would say, that there are already
threeFOUR JAX-RS implementations offeringSpringSTANDARDS support (Jersey, RESTEasy, CXF and Restlet).It's always a good use of valueable time to support standards and interoperability… I hope you will add a fifth framework to the group of JAX-RS compliant frameworks.
Stefan Magnus Landrø says:
Added on August 12th, 2009 at 5:52 amThis is great news to the java world!
Currently I see two issues though:
- How to determine format inside controller? (you probably need different data in the different scenarios)
- How to test the request mappings?
A standard(Convention over configuration) CRUD request mapping system, like in rails, would also be nice.
Cheers,
Stefan
Vineeth says:
Added on October 14th, 2009 at 2:40 pmWhat are your thoughts on the thread http://forum.springsource.org/showthread.php?t=79114
opensource mad man says:
Added on October 18th, 2009 at 9:55 pmHow to upload file use annotation?
Please provide examples.
Thank you.
Fabio says:
Added on December 4th, 2009 at 9:07 amConsider a method like this:
@RequestMapping(value="/businessFunctions", method=RequestMethod.POST)
public void post(@RequestBody String body) {
BusinessFunction bfToInsert = deserializeJson(body);
aclService.insertBusinessFunction(bfToInsert);
}
What do I have to return? My GET method works perfectly returning a string with @RequestBody annotation. I suppose POST doesn't have to return anything else than a Response code 201. The question is…. HOW?
Michal says:
Added on January 15th, 2010 at 7:27 amMy MarshallingView (Spring 3.0.0.RELEASE) seems to be picking only ONE object from a ModelAndView object and it picks the first one by key (alphabetically). Is that desired?
Scott Frederick says:
Added on January 15th, 2010 at 2:14 pm@Michal, are you using Jaxb2Marshaller? If so, I have this same problem and I definitely don't think it is desired behavior. I submitted an issue to Spring concerning this behavior: http://jira.springframework.org/browse/SPR-6577. You can vote for the issue if you agree it is a problem.
There is a workaround. When you define the MarshallingView bean in your Spring XML config file, set the "modelKey" property on the view bean to tell it which object from the ModelAndView to marshall. It is not a good solution, but it works.
Michal says:
Added on January 18th, 2010 at 5:07 pm@Scott
I tried all kinds of marshallers. I don't think it's a marshaller issue at all! I believe it is the implementation of the locateToBeMarshalled method that causes problem and I added an issue as well, please take a look:
http://blog.springsource.com/2009/03/08/rest-in-spring-3-mvc/
I think this is the problem – I even tried different marshallers.
André Faria Gomes says:
Added on February 2nd, 2010 at 11:49 amIt's it possible to use this without an extension like .do or .action in the URIs?
Cause I tried map the dispatcher servlet with /* but then I got some erros when trying to load other resources like scripts (js), images and static pages.
I just would like to use http://domain/users/name insted of http://domain/users/name.do
André Faria Gomes says:
Added on February 2nd, 2010 at 12:03 pmIt sems that there is a solution for the problem I've pointed right here http://stackoverflow.com/questions/2047774/spring-mvc-rest-static-files-unaccessible-because-of-url-pattern
Thanks, Anyway….
juan says:
Added on March 9th, 2010 at 9:36 amHello Arjen,
I built a class called SiteMap (implementing BeanFactoryAware) that builds a list of my app's URIs. When clients hit my root context, I'll serve out an XHTML5 representation of this sitemap for further discovery (I could possibly even serve a WADL).
In fear of re-inventing the wheel, do you have similar functionality already?
Also, it will be great if RequestMapping could be made more granular, e.g.
@RequestMappings){
@RequestMapping("/sales_channel/{region}",
@Arguments({@Argument(0, uri="/regions")}))
})
Or…
@RequestMappings){
@RequestMapping("/foo/{bar}/{baz}",
@Arguments({
@Argument(0, uri="/bars"),
@Argument(1, doc="This is a free-text field, first 30 characters accepted.")}))
})
The first one tells my client that the variable "region" has options in the result provided by the call to "/regions".
In the second one instead we provide documentation stating that the second argument is a free-text field.
I'd like to be able to have a self-documenting system like this.
Thanks,
Juan