Ajax Simplifications in Spring 3.0

In my last entry, I walked you through several enhancements in Spring 3 for web application development. A number of you expressed interest in a follow-up entry focused on Ajax remoting. Spring 3 provides a lot in this area to take advantage of. Read on, and I'll walk you through it.
Spring and Ajax Overview
For the purposes of this article, when I say Ajax, I'm talking about the web browser's ability to communicate with a web server asynchronously using JavaScript. On the server-side, Spring provides the programming model for defining web services, including services consumed by JavaScript clients. On the client-side, nobody rolls their own Ajax framework these days, either. Most use an established JavaScript framework such as jQuery or Dojo.
Support for Ajax Clients
Until version 3, Spring did not ship support for Ajax remoting. That didn't stop our users from extending Spring to get it, or integrating other options themselves. Some used DWR, especially in the period before the rise of the JavaScript frameworks. More recently, REST-style remoting with JSON as the data exchange format has become more popular, especially because jQuery and co. make it so easy to do.
Now that Spring 3 is out, official support for Ajax remoting with JSON is provided as part of Spring MVC. This includes support for generating JSON responses and binding JSON requests using the Spring MVC @Controller programming model. In this article, I'm going to focus on using this support to implement several Ajax use cases. Like my last post, I'll do this by walking you through a sample application you can experiment with yourself.
MVC Ajax Sample
mvc-ajax has been designed to illustrate Spring MVC's JSON support. The project is available in our spring-samples Subversion repository, is buildable with Maven, and is importable into STS / Eclipse. mvc-ajax has the same structure as the mvc-basic project presented in my previous entry. In fact, the Spring configuration is identical between the two.
Start your review by deploying the project to your servlet container and accessing the welcome page at localhost:8080/mvc-ajax. Since I use STS, I did this by first importing the project into the IDE, then deploying it to the built-in Tomcat / tc-server instance.
Getting JSON from the Server
From the welcome page, activate the "Ajax @Controller Example" link. You will see a form to create a new Account. When you tab out of the Name field, your browser will ask the server if the name you just entered is available. If it is not, an error message will be displayed and the form will remain disabled until you enter a name that is available. The client-side JavaScript handling this resides in /WEB-INF/views/account/createForm.jsp and looks like:
$(document).ready(function() {
// check name availability on focus lost
$('#name').blur(function() {
checkAvailability();
});
});
function checkAvailability() {
$.getJSON("account/availability", { name: $('#name').val() }, function(availability) {
if (availability.available) {
fieldValidated("name", { valid : true });
} else {
fieldValidated("name", { valid : false,
message : $('#name').val() + " is not available, try " + availability.suggestions });
}
});
}
Nothing Spring-specific here, just standard jQuery JavaScript.
On the server-side, the Controller for the account/availability resource is standard Java with some Spring MVC annotations:
@RequestMapping(value="/availability", method=RequestMethod.GET)
public @ResponseBody AvailabilityStatus getAvailability(@RequestParam String name) {
for (Account a : accounts.values()) {
if (a.getName().equals(name)) {
return AvailabilityStatus.notAvailable(name);
}
}
return AvailabilityStatus.available();
}
AvailabilityStatus is a plain Java Value Object with two properties: an availability flag that tells the client if the user name is available, and an array of alternatives to suggest if the name you want is not available. The @ResponseBody annotation instructs Spring MVC to serialize the AvailabilityStatus to the client. Spring MVC automatically serializes to JSON because the client accepts that content type.
Underneath the covers, Spring MVC delegates to a HttpMessageConverter to perform the serialization. In this case, Spring MVC invokes a MappingJacksonHttpMessageConverter built on the Jackson JSON processor. This implementation is enabled automatically when you use the mvc:annotation-driven configuration element with Jackson present in your classpath.
Pretty cool, huh? Try creating an Account, then creating another one with the same name. You should see an error message suggesting alternate names. Turn on Firefox's Firebug or Safari's Web Inspector to debug the asynchronous interaction.
Posting JSON to the Server
Spring MVC also provides support for sending JSON to the server. I have found the need for this to be less common, simply because posting form parameters is often sufficient. Nevertheless, JSON provides a flexible data-interchange format that richer JavaScript clients can conveniently work with. The ability to map JSON to a server-side Java Object for processing can be a useful feature in those cases.
In the sample, a JavaScript event handler intercepts the form submit event and posts the form data as JSON. The server returns the id of the newly created Account, which is then used to display a modal confirmation dialog:
$("#account").submit(function() {
var account = $(this).serializeObject();
$.postJSON("account", account, function(data) {
$("#assignedId").val(data.id);
showPopup();
});
return false;
});
On the server-side, the Controller is more standard Java with Spring MVC annotations:
@RequestMapping(method=RequestMethod.POST)
public @ResponseBody Map<String, ? extends Object> create(@RequestBody Account account, HttpServletResponse response) {
Set<ConstraintViolation<Account>> failures = validator.validate(account);
if (!failures.isEmpty()) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return validationMessages(failures);
} else {
accounts.put(account.assignId(), account);
return Collections.singletonMap("id", account.getId());
}
}
Here, the @RequestBody annotation instructs Spring MVC to map the body of the HTTP request to an Account object. Spring MVC knows to map from JSON because the client set the request Content Type to application/json.
The create method also validates the Account object. If there are validation errors, a HTTP 400 is returned with the error messages, otherwise a HTTP 200 is returned with the assigned account ID.
Summary
Spring 3 provides first-class Ajax support with JSON as part of the Spring MVC module. This includes support for generating JSON responses and binding JSON requests using the Spring MVC @Controller programming model in conjunction with the Jackson JSON processor. In this article, I showed you how this support works. I hope you found this post useful, and look forward to hearing more of your experiences putting Spring 3 to work in your own applications!
Similar Posts
- Java to JavaScript Compilation with AJAX and Spring Integration
- MVC Simplifications in Spring 3.0
- Request-Reply JMS with Spring 2.0
- REST in Spring 3: @MVC
- Using a Hybrid Annotations & XML Approach for Request Mapping in Spring MVC











Grzegorz Borkowski says:
Added on January 25th, 2010 at 3:58 amHow mouch control over JSON serialization do I have in the above scenario? Suppose AvailabilityStatus were an @Entity with many X-to-N relationships, some of them being lazy, how can I tell the JSON serializer not to touch those fields, so that lazy initialization exception are not thrown?
Jose Noheda says:
Added on January 25th, 2010 at 9:57 amI like the approach. I miss several things here though:
* A mixed solution with POST and REST-style URLs (if able)
* Several parameters in the method call. DWR remotes any method with any number of parameters of any type (primitives, beans, collections, …). I'm not sure $.post can handle that cleanly.
* Like in the above comment, what about serializing JPA objects? Any kind of limits?
* How are object graph cycles managed? Is the same object serialized twice?
Keith Donald (blog author) says:
Added on January 25th, 2010 at 12:32 pmGood to hear from you Gzegorz.
See here and here. Jackson itself provides annotations to customize the serialization and de-serialization process. @JsonIgnore should give you what you want for your lazy loading case.
You can also customize the Jackson ObjectMapper instance to plugin in custom serializers and de-serializers. This provides a greater degree of control. If you look at the ajax.json utility package in the sample project, we did exactly this to integrate the Spring 3 ConversionService. This extension makes Jackson aware of Spring conversion annotations such as @DateTimeFormat and @NumberFormat when serializing/de-serializing JSON.
Best regards,
Keith
Keith Donald (blog author) says:
Added on January 25th, 2010 at 2:57 pmHi Jose,
I'll try to answer some of your questions:
Best regards,
Keith
Rostislav says:
Added on January 25th, 2010 at 3:42 pmI was looking for something like this recently but there wasn't anything that fresh available. Thanks!
Is there a recommended approach how something like simple innerHTML injection can be achieved?
Our application uses stateless JSF 2 Facelet templates on top of the REST support in Spring 3. We're using JSON for some small things but now I have almost implemented a partial page rendering which is natively supported by the JSF framework. It's still work in progress but I haven't seen something similar using Spring MVC and I'm looking for ideas. Let me know if you need contributions in this area.
Jeremy Grelle says:
Added on January 25th, 2010 at 6:13 pmRostislav,
The approach you mention sounds similar to what we currently do in the Spring JavaScript module (see http://www.springsource.org/webflow for some background if you're not familiar with it), where we can request a number of fragments (in the typical Spring MVC case individual Tiles definitions) to be rendered and automatically insert them in the page. Basically, we take the returned HTML, create DOM nodes from it, and replace any existing nodes with matching id's with the new content. This was very much inspired by the approach generally taken in JSF component libraries, and that is now available as a standard part of JSF 2 via the built-in client-side Ajax library.
That said, I think building upon Spring 3's REST support offers some additional ways of approaching this, especially if you are aiming for statelessness on the server. You could generally think of a typical human-readable HTML page as a composition of multiple HTML resources. A typical Spring MVC View is a rendering of that composition. For refreshing parts of the page via Ajax, you might consider making those smaller individual resources that you need to refresh available under their own addressable URL. Each of those individual resources might either map to an individual Facelets template, or you could actually provide the response directly by invoking your own partial rendering algorithm on the larger Facelets composition. Then it's just a matter of handling that response client-side. jQuery, Dojo and other such frameworks both make this pretty easy to accomplish and would be good choices if you want to augment the functionality provided by the JSF Ajax library (which requires the response to be in a specific format, so is not ideal for handling such simple RESTful responses). For example, continuing with the Accounts example, the simplest possible way to do it with jQuery would be something like the following to replace an existing DOM element with an id of "account" with the result of a GET request:
$("#account").load("account/2");
We're very interested in exploring the use of JSF 2 in a stateless way with Spring 3 and I would be interested to hear more feedback about your experiences there and anything you think might be a good addition to Spring 3.1 to support this style. Drop me a line at jeremy dot grelle at springsource dot com if you'd like to discuss further.
Cheers,
Jeremy
Jeremy Grelle says:
Added on January 25th, 2010 at 6:14 pmRe: Handling cyclical references and possibly uninitialized Hibernate relationships – as Keith mentioned, the best way to do this is to either tell Jackson to ignore those fields via @JsonIgnore, or to point Jackson to a custom serializer/deserializer for those fields. Providing a custom serializer/deserializer not only solves the cyclical references and LazyInitialization problem, but also allows you to follow the RESTful practice of representing relationships between resources as links. Following certain formalized approaches to this, such as that specified by JSON-Referencing, can have additional benefits if your chosen client-side framework has built-in support said approach (Dojo's support for JSON-Referencing, for example).
SMiGL says:
Added on January 26th, 2010 at 3:46 amHelpful post. Thanks
Emiliano says:
Added on January 26th, 2010 at 3:59 amwhat is the package org.springframework.samples.mvc.ajax.json?
Andrew Goode says:
Added on January 26th, 2010 at 10:05 amDoes Spring 3 provide support for remoting *any* stateless bean defined in the ApplicationContext e.g. a service bean distinct from the MVC layer? It doesn't sound like it.
I've found this to be a nice feature of DWR. My project uses service-layer beans to encapsulate distributed transactions via Spring AOP, which provide the backend for multiple web applications and web services. With DWR, we can remote these beans directly to JavaScript without the need to define an HTTP controller at all (DWR handles the details of HTTP and JSON serialization for us via simple Spring configuration), thus allowing a clean solution for transactional JavaScript services with less code.
Does Spring 3 provide (or even attempt to provide) similar features?
Keith Donald (blog author) says:
Added on January 26th, 2010 at 10:14 amEmiliano,
org.springframework.sampls.mvc.ajax.json contains an extension to Spring that integrates the Jackson JSON ObjectMapper with Spring 3's Type ConversionService. This makes Jackson aware of Spring type conversion annotations such as @DateTimeFormat and @NumberFormat when serializing and deserializing JSON. We expect this capability to be officially integrated into a future release of Spring Framework (see SPR-6731), and are also in contact with Tatu Saloranta, the lead developer of Jackson, about this.
In terms of how the extension works: Spring detects and invokes the JacksonConversionServiceConfigurer @Component when the application starts up. This BeanPostProcessor intercepts the initialization event for Spring MVC's AnnotationMethodHandlerAdapter, retrieves the default MappingJacksonHttpMessageConverter, and injects a custom Jackson ObjectMapper that uses our ConversionService.
This extension is purely optional and self-contained within that package. You can disable it by deleting the package or removing the @Component annotation from JacksonConversionServiceConfigurer. When you disable it, you'll notice the ability to serialize/de-serialize formatted dates and numbers using the format annotations goes away.
Best regards,
Keith
Keith Donald (blog author) says:
Added on January 26th, 2010 at 11:27 amAndrew,
Spring provides several other remoting options, including RPC-style remoting of service-layer beans. These other options are generally discussed here.
With that said, none of these other options are very convenient for a JavaScript client. When you want JavaScript-to-Java RPC, DWR is the best option available today in my opinion. As you pointed out, it is mature and also has good Spring integration.
I would consider, though, if JavaScript-to-Java RPC is more appropriate for your project compared to REST-based RPC. When using a framework like DWR, there is a stronger degree of coupling between your client and the server around the service interface and the specific nature of DWR. With REST, your service interface is uniform across all resources, and more emphasis is put on the message contract. In my experience this reduces coupling between the client and server, helps provides a simpler interface built around standard HTTP semantics (which has a number of benefits), and eases interoperability with multiple client types. In addition, today client-side frameworks like jQuery and Dojo combined with server-side frameworks like Spring MVC and JAX-RS make this REST-ful style of communication easy to do.
Hope this helps,
Keith
Karthik says:
Added on January 27th, 2010 at 1:32 amI believe we can configure ContentNegotiatingViewResolver and MappingJacksonJsonView to get json output. That way I can hopefully get rid of @ResponseBody annotation from the controller.
Also does it make sense for Spring MVC to automatically switch the normal binder to Json binder when it sees a request Content Type of application/json. That way I can get rid of @RequestBody as well
The controller can then be reused across ajax/non-ajax requests?
Keith Donald (blog author) says:
Added on January 27th, 2010 at 11:07 amKarthik,
Yes, instead of using @ResponseBody to instruct a HttpMessageConverter to write the response, you could use a MappingJacksonJsonView resolved by a ContentNegotiatingViewResolver. If you did this, you could remove @ResponseBody. In it's place, you'd need to add some global XML configuration. Also, you'd be serializing a model Map containing an "availabilityStatus" entry, instead of serializing the AvailabilityStatus object directly.
For the typical cases, though, I do not recommend resolving and rendering application-scoped Views when implementing REST-style web services. I recommend using the @ResponseBody model, as shown in the sample. It requires little to no special configuration to use and keeps the response handling rules local to the @Controller method.
For cases where you need to support an additional HTML representation of the resource, then the ViewResolver/View abstraction can add value. However, I find this to be a special case, not the typical case. If I don't need that, I favor the simpler @ResponseBody model.
Keith
Sebastian Beigel says:
Added on February 2nd, 2010 at 11:09 amHi,
I'm trying to do JSONP with these new feature in Spring MVC 3 — but I'm stuck. I think I need to provide my own view implementation, overriding MappingJacksonJsonView to wrap some Javascript callback function call around the JSON result — but the MappingJacksonHttpMessageConverter writes the JSON as I can see. How can I provide my own *JsonView implementation?
I also tried to use a ContentNegotiatingViewResolver defining my JsonView, but it's never called.
Thank you for your help
Sebastian
Jeremy Grelle says:
Added on February 3rd, 2010 at 2:51 pmSebastian,
Rather than extending MappingJacksonJsonView or MappingJacksonHttpMessageConverter for implementing JSONP, I would suggest just writing a simple servlet filter that:
1. Checks whether the request is asking for an appropriate media type where the JSONP callback would be allowed (you will likely need to use the file extension)
2. Checks for a callback parameter in the request
3. Wraps the servlet-generated response with the appropriate callback
The advantage to this approach would be that it would work whether using @ResponseBody or the ViewResolver/View abstraction to generate the JSON content.
That said, I must urge you to be very cautious about what data you expose using the JSONP technique, as this technique is highly susceptible to CSRF attacks. If you have a mix of data that is inherently public and safe to allow *anyone* to see along with with other more sensitive resources, one approach would be to segregate the public resources under a separate DispatcherServlet and applying the filter to only that servlet's path.
There are other techniques you can use that are safer…see this article for a good summary of the issues to be aware of:
http://www.sitepen.com/blog/2008/09/25/security-in-ajax/
- Jeremy
Hatim says:
Added on February 6th, 2010 at 10:50 pmHello,
I am trying to use this example in Spring Roo. For some reason I get the entire contents of an exception page when doing a JSON request (I can see JSON resquest/response in firebug)
Could it be some thing with the viewResolver?
Hatim says:
Added on February 6th, 2010 at 11:53 pmI was not able to use this example when putting the actions in Roo generated controllers.
After some debugging and help from http://jira.springframework.org/browse/SPR-5457 I just added
@RequestParam("name") and it works now (otherwise I would be getting the exception::
No parameter name specified for argument of type [java.lang.String], and no parameter name information found in class file either
J.A. says:
Added on February 15th, 2010 at 8:39 amHi Keith,
I've come across a behaviour that I think it's not quite correct…
Imagine that you submit the whole form (ajax post) and the input in balance is "asdf". What it's actually happening is that even before validating the form (@Valid annotation -> annotated Account bean) ConvertingDeserializer.deserialize() tries to convert "asdf" to BigDecimal and it throws a "java.text.ParseException: asdf" which stops the normal flow so the form never gets validated in the controller.
Shouldn't it catch that formatting exception somehow to let you go on with the validation? That's what correctly happened in the mvc-basic sample.
Do you have any workaround for this?
Kind regards,
Jose A.
vidya says:
Added on February 18th, 2010 at 6:40 amhi,
i am trying to do ajax by refering this example .but callback function is not calling and how to check whether response has been return or not using jquery
George Grooth says:
Added on February 19th, 2010 at 12:49 amGreat!! this site is doing really good work.Keep it up.
http://www.articlesbase.com/health-articles/advanced-acai-review-does-advanced-acai-really-work-1778693.html
Lloyd says:
Added on February 21st, 2010 at 7:14 pmWhen I deployed the sample war in this example on to Tomcat6.0.20,
any field errors as detected by Hibernate-Validator-4.0.2 cannot be reflected on the front JSP page, though I verified backend AccountController did actual validation. Why is it like that?
Lloyd says:
Added on February 21st, 2010 at 7:30 pmThere is a usability problem with this AJAX example. If the user submits account name "aaa", then closes popup, backs in the same (parent)browser, he types name "aaa" again, there is no AJAX communication with the server, since the first session is still alive. Any suggestion to solve this problem?
Manoj says:
Added on February 25th, 2010 at 4:02 amLlyod, u can concat "?sid=' Math.random()" at the end of your url.
emilime says:
Added on March 1st, 2010 at 7:26 pmAccording to documentation mvc:annotation-driven configures support for JSON, if Jackson is in the classpath and also XML if jaxb is present in the classpath. The example above shows that JSON support works great but trying to access 'account/availability' with accept header 'application/xml' gives 406 Not Acceptable response. But jaxb is in the classpath. So what's wrong? What is necessary to enable support for XML MarshallingHttpMessageConverter?
André says:
Added on March 10th, 2010 at 9:30 amHi everyone,
emilime, I have the same issue.
I put mvc:annotation-driven in my app-servlet.xml, but JSON automatic serializer does not
work. Did you have any success?
thanks.
emilime says:
Added on March 10th, 2010 at 9:49 am@Andrè yes, JSON works for me simply adding mvc:annotation-driven and jackson libraries to application classpath (I'm using jackson-core-asl-1.4.1.jar and jackson-mapper-asl-1.4.1.jar)
I suggest you to download the example of this post from svn to see the correct configuration.
My problem is with XML marshalling that, as I understand from reference, should work the same way adding Jaxb to classpath but this is not. Can you help me on this point Keith?
Daniel Vaughan says:
Added on March 10th, 2010 at 4:15 pmHi, I have documented my attempts with JSONP using Spring 3.0 here: http://www.bristol-gtug.org/?p=76. I would welcome suggestions for improvement.
JC Mann says:
Added on March 12th, 2010 at 9:50 amWhen I first read your article I was really impressed. Unfortunately, this didn’t last long.
I downloaded the sample code, built and tested it with no problems. Then I did something
completely crazy, I tried to make a minor modification to the code. I thought that it would
interesting to added a boolean flag to the Account object. So I added the field:
private boolean flagged;
And its getter and setter. Then I modified the createForm.jsp to a have a checkbox (according
to the documentation) for my newly added field:
Flagged
When I clicked the "Create" button on the web form, nothing happened. I checked the log
file and saw no errors or warnings. Weird. So, I dialed up the log level to DEBUG, and tried again.
That's when I saw an error in the log file:
DEBUG: org.springframework.web.servlet.DispatcherServlet – Could not complete request
org.codehaus.jackson.map.JsonMappingException: Unrecognized field "_flagged" ….
Wow. Really?
1) I had to set the logging to DEBUG to see an error?
2) Binding a boolean field to a checkbox doesn't work?
Dear failblog.org…
Keith Donald (blog author) says:
Added on March 12th, 2010 at 10:19 amJC Mann,
You have to keep in mind you are posting the form as JSON to the server, instead of submitting the form in the usual way (as encoded parameters in the request body). The Spring form checkbox tag you used has been authored with the assumption your posting standard form parameters, and Spring's own DataBinder is handlingthe binding to the Account form object on the server. However, in this example, Jackson, the JSON processor, is actually doing the binding, and it doesn't know about "special" checkbox binding conventions.
Regards,
Keith
emilime says:
Added on March 12th, 2010 at 12:08 pmKeith, can you give me a hint about my problem?
http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/#comment-171458
Thanks in advance
Keith Donald (blog author) says:
Added on March 12th, 2010 at 12:15 pmEmil,
Take a look at AnnotationDrivenBeanDefinitionParser. Look at what defines if "jaxb2Present". Set a breakpoint around line 179 and see if the Jaxb2RootElementHttpMessageConverter is indeed being registered like the MappingJacksonHttpMessageConverter is. Good luck! If you suspect a bug, don't hesistate to file a JIRA with a small sample that reproduces your failure.
emilime says:
Added on March 12th, 2010 at 12:22 pmthanks Keith, I'll try
Josephine says:
Added on March 16th, 2010 at 2:19 pmI have run the mvc-basic example with no problem. Now trying the mvc-ajax verbatim, and encountered the following stack trace. Have done "mvn clean install", restarted tomcat, to no avail. The dependency in pom.xml points to jackson-mapper-asl 1.4.2 without modification. No other info found in google. Thanks for your help in advance.
org.codehaus.jackson
jackson-mapper-asl
1.4.2
ERROR: org.springframework.web.servlet.DispatcherServlet – Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAd
apter#0': Initialization of bean failed; nested exception is java.lang.Error: Unresolved compilation problems:
The hierarchy of the type ConversionServiceAwareObjectMapper is inconsistent
The type org.codehaus.jackson.ObjectCodec cannot be resolved. It is indirectly referenced from required .class files
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:557)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:842)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:416)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:443)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:459)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:340)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:307)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
at javax.servlet.GenericServlet.init(GenericServlet.java:212)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1172)
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:808)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:599)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
at org.tuckey.web.filters.urlrewrite.NormalRewrittenUrl.doRewrite(NormalRewrittenUrl.java:195)
at org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:159)
at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:141)
at org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:90)
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:417)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.Error: Unresolved compilation problems:
The hierarchy of the type ConversionServiceAwareObjectMapper is inconsistent
The type org.codehaus.jackson.ObjectCodec cannot be resolved. It is indirectly referenced from required .class files
at org.springframework.samples.mvc.ajax.json.ConversionServiceAwareObjectMapper.(ConversionServiceAwareObjectMapper.java:14)
at org.springframework.samples.mvc.ajax.json.JacksonConversionServiceConfigurer.postProcessAfterInitialization(JacksonConversionServiceConfigurer.java:4
0)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFa
ctory.java:404)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1407)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512)
… 41 more
Josephine says:
Added on March 16th, 2010 at 5:24 pmKeith, the last issue is resolved. It is due to a loose class webapp and a jar webapp were deployed in the same name as mvc-ajax. After removing the jar webapp, the class in question is resolved and the app runs as specified. Sorry for the posting. Delete them if you'd like.