Blogs

SpringSource Blog

Ajax Simplifications in Spring 3.0

Keith Donald

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

Share this Post
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • DZone
  • LinkedIn
  • Slashdot
  • Technorati
  • TwitThis
 

178 responses


  1. How 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?


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


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


  4. Hi Jose,

    I'll try to answer some of your questions:

    • I assume you're asking about using @PathVariable or @RequestParameter in addition to @RequestBody to define a more flexible URL structure. This should work fine.
    • In the example, I am posting a JSON structure consisting of multiple parameters and mapping that to a JavaBean. Jackson supports mapping primitives, dates, nested beans, and collections. The type conversion mechanism the Jackson ObjectMapper uses is also extensible (as the sample also shows).
    • Yes, you should take care when serializing persistent entities managed by JPA or Hiberante. If an entity is detached and Jackson attempts to serialize a untouched collection property, a LazyInitializationException will be thrown. To prevent this, developers should look to eagerly initialize such a Collection when they know its needed by the client. If the Collection is irrelevant, you can use @JsonIgnore to instruct Jackson not to touch it. Finally, you can also consider introducing a distinct service layer and keeping persistent entities internal to those services. I've found this to be a good technique when the domain layer of my application is fairly complex, as a Service allows me to encapsulate that complexity behind a simpler, user-oriented interface.
    • At this time, the Jackson JSON processor does not provide support for cyclical references. This is on their roadmap and noted here. An overview of Jackson's latest 1.4 release along with some of the plans for 1.5 are discussed here.

    Best regards,

    Keith


  5. I 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.


  6. Rostislav,

    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


  7. Re: 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).


  8. Helpful post. Thanks


  9. what is the package org.springframework.samples.mvc.ajax.json?


  10. Does 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?


  11. Emiliano,

    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


  12. Andrew,

    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


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


  14. Karthik,

    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


  15. Hi,

    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


  16. Sebastian,

    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


  17. Hello,

    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?


  18. I 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 , and no parameter name information found in class file either


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


  20. hi,

    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


  21. Great!! 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


  22. When 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?


  23. There 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?


  24. Llyod, u can concat "?sid=' Math.random()" at the end of your url.


  25. According 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?


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


  27. @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?


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


  29. When 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…


  30. JC 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


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


  32. Emil,
    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.


  33. thanks Keith, I'll try :)


  34. I 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


  35. Keith, 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.


  36. Keith,
    How can i get the validationMessages at front-end, the code like this
    "if (!failures.isEmpty()) {
    response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
    return validationMessages(failures);"
    }
    but the "" code seems not work .


  37. Keith,
    I guess that i can't get the validationMessages is due to the "response.setStatus(HttpServletResponse.SC_BAD_REQUEST);",I don't know why did you want to do like this .


  38. Hi Keith,

    I was looking into testing the examples on your blog. I was successful running the mvc-basic example but I am having a hard time getting the mvc-ajax example working. I imported the project into my Eclipse IDE and it builds successfully but when I try to install I get a failure:

    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.0.2:testCompile (default-testCompile) on project org.springframework.samples.mvc.ajax: Compilation failure
    /workspace/Eclipse/mvc-ajax/trunk/src/test/java/org/springframework/samples/mvc/ajax/account/AccountJsonBindingTests.java:[101,31] cannot find symbol
    symbol : constructor String(byte[],java.nio.charset.Charset)
    location: class java.lang.String
    -> [Help 1]

    Do you have any suggestions?

    Thanks so much for the tutorials.


  39. Keith,

    The problem is that even though the maven-compiler-plugin is configured to use JDK 1.5, the source code you're having a problem with is using a JDK 1.6 method.

    You can change to use JDK 1.6 or edit the AccountJsonBindingTests.java to use a JDK 1.5 method.

    HTH

    -JC


  40. Thanks for troubleshooting my error. I added another JRE library in my Eclipse IDE to compile this project using JDK 1.6 and now it works.

    Thanks Again


  41. Hi,

    I want to try out mvc-ajax and followed your initial instructions:

    - import project to Eclipse (as Existing Maven project)
    - Maven Build SUCCESSFUL
    - Ran Eclipse-Project-Clean (no error)
    - Went to browser and typed: http://localhost:8080/mvc-ajax

    Instead of seeing the Welcome page, I got a "404 …Sun GlassFish Enterprise Server v2.1.1".

    Any idea for me to where to look first?

    Please Help. THANKS.


  42. Hi,

    Does mvc-ajaxc demonstrate @RequestBody, @ResponseBody, Marshalling, UnMarshalling, XML-data-to-Object,.vice versa &…etc.?

    If not, can you please point me to a sample project that does the above?

    Many Thanks


  43. I am very sorry about my last comment with the question of what mvc-ajax does. I certainly need to read first, then ask. My apology.

    I want to run mvc-ajax but still getting "404…".

    Any ideas and info will be greatly appreciated.


  44. This may be useful to those playing with the mvc-ajax sample.
    Problem Statement:
    How to cope with additional / child objects within the Account object (e.g. create a class 'Person' containing as properties firstName, and lastName – then create an instance of 'Person' inside the Account object that's used as the modelAttribute for the createForm). The problem arises when you add new input fields in the create form that have paths as follows:
    and
    You should notice that the binding works perfectly but a problem occurs on the submit event, namely that you'll now need to explicitly look for fields that contain a '.' and create appropriate child objects in your json object before calling postJSON.
    Here's a sample function I used to handle the problem by finding all form text input elements, checking their path, and creating a child object if the path contains a '.' :


    $.fn.serializeHierarchicalObject = function() {

    var objectToPost = {};
    function add(objectToPost, pathProperty, actualValue) {
    if (pathProperty.length == 1)
    objectToPost[pathProperty[0]] = actualValue;
    else{
    if (objectToPost[pathProperty[0]] == null)
    objectToPost[pathProperty[0]] = {};
    add(objectToPost[pathProperty[0]], pathProperty.slice(1), actualValue);
    }
    };

    this.find('input[type="text"]').each(function() {
    add(objectToPost, $(this).attr('name').split('.'), $(this).val());
    });
    return objectToPost;
    };

    You then simply replace the statement :
    var account = $(this).serializeObject();
    with:
    var account = $(this).serializeHierarchicalObject();

    and you should see your Account, as well as any child objects being correctly serialized on the server side….hope it helps!

    Andy M


  45. Hi there,

    I've been trying to get automatic JSON-deserializing working with @RequestParameter instead of @RequestBody. But can't seem to figure out how to get Spring to recognize that a deserializer is needed for my parameters.

    You've indicated above that Spring knows it needs Jackson's help deserializing because the request's content-type is set to "application/json", which allows the example application to work perfectly when using jQuery/etc. to post to the controller as defined:

    @RequestMapping(method=RequestMethod.POST)
    public @ResponseBody Map create(@RequestBody Account account, HttpServletResponse response)

    I've been trying to get this automatic mapping working (as i think others have hinted at in their comments) with url-parameters instead of post-body. I've changed the method signature and annotations as follows:

    @RequestMapping(method=RequestMethod.GET)
    public @ResponseBody Map create(@RequestParameter Account account, HttpServletResponse response)

    modifying the javascript and passing in the same JSON string as the "account" url-parameter fails because Spring/Jackson doesn't know the string needs to be deserialized to an Account object, and fails because it sees I'm attempting to pass a String instead of an Account to the method. Is this a use-case that existing annotations can handle? if not, can you think of where I'd need to start with building custom mapping logic?

    Thanks,

    J


  46. Thanks very much, Andy; for the detailed info above.

    Much Obliged


  47. great post, thanks!!!

    .. but i have a problem:

    the getAvailability method in AccountController receive the "name" parameter: "@RequestParam String name" but the string is duplicate. Example:

    GET http://localhost:8080/spring-ajax/account/availability?name=costa

    String name = "costa,costa"

    Why?
    Thanks :)


  48. This article does not explain the important point of the usage of JSon in Spring MVC.

    MappingJacksonHttpMessageConverter can only handle { "key" : "value" } style of JSon.

    You should explicitly specify that 'MappingJacksonHttpMessageConverter' can not handle the 'key=value' style.

    In this example, JSON.stringify() is defined. This is a point which you should explain.

    Many javasciprt libraries doesn't send the style of JSON.


  49. @Jeff

    Annotate your interfaces rather than your implementations. This solved the same problem for me.


  50. @emilime

    Don't forget to annotate your class with jaxb annotation (@XmlRootElement …)!

    jackson can process 'vanilla' bean, not jaxb.


  51. It is so complicated. JavaScript along with Java annotation look like an Egypt scripts to me. I was working with Java 8 years and I barely can read these examples :-( I wish author would go over more details. At lease a reference

    $('#name').blur(function() {

    Starting from what is that ? What $ means ? what #name ? what is blur method does ? Is it a standard JavaScript ? I am using AJAX trough ZK framework, it is pure Java – no annotations, no these $$$$###$$ elements :-)


  52. @sokolov, "$" is just a (specially named, mind you) javascript function, it is actually just an alias for another javascript function called "jQuery". This function is also the name of the javascript framework that they are using in the examples. You can get more info at http://www.jquery.org.

    I do agree with you, though, that a lot of the Spring documentation assumes a lot of "framework knowledge", which makes adapting the examples harder than it has to be (No offense Keith, I appreciated this post).


  53. @Dan_Mace, i don't think the problem you solved was the same as mine.
    The problem I'm seeing seems to stem from the difference between the magic that Spring is performing on request-body vs. request-parameter annotations. In the first example I gave (as in the original blog example), Spring knows to use Jackson to deserialize the request-body because it has a mime-type of application/json or similar, whereas in the second example, Spring doesn't know what to do with the JSON inside the request-parameter because request-parameters have no concept similar to mime-type, Spring's just looking to pass a String to the constructor of whatever object the annotated method expects (which fails because the POJO doesn't understand JSON).
    Is that the problem you were able to solve by moving the annotations to the interface? That doesn't do anything for me.


  54. @Jeff
    I tried to check http://www.jquery.org. And these guys made the same assumption that I know what $XXX is. They use the pattern everywhere. To say more I have been using some jQuery libraries for a while (like tabs for example and date picker). Nothing really required from me knowledge of what this $XXX syntax means. I really would like to read more about it but even the most basic example on jQuery website takes it as granted that reader knows what it is.

    http://docs.jquery.com/Tutorials:How_jQuery_Works

    For example
    $(document).ready(function(){
    $("a").click(function(event){
    alert("Thanks for visiting!");
    });
    });

    how I supposed to know what is $(document) or $("a"). Why document is without quotes and "a" is in quotes ?


  55. Jeff,

    No offense taken. I appreciate the constructive feedback on our documentation. It helps us make it better. I also especially appreciate feedback on functionality you'd like to implement in your application using Spring. It helps us write other articles like these.

    I do expect folks will take the time to checkout, deploy, and study the sample code for themselves, of course. There is no substitute for working code, and there are many nuggets to find when you take the time to go through it & seek to understand it. When writing this article, I focused on highlighting the Ajax scenarios, but also expected folks to dig in a bit deeper on their own. I actually did link to the jQuery project as one resource. Absolutely, I recommend web developers today ensure they have a solid JavaScript foundation, as well as a working knowledge of a popular toolkit such as jQuery or Dojo. Just knowing Java isn't enough…

    Keith


  56. Hi Keith,

    Could you please reply to Jose's comment regarding command object validation. I am also interested in seeing your opinion and approach on this one.

    Petar


  57. Hi Keith,

    When I am trying to deploy the application I modified the sample mvc-ajax in my owne but I am getting this error when I try to hit the create button could you please let me know whats the root cause of this problem Do I need to do some changes to the config file…

    DEBUG [org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping] – Mapping [/reports/factoryValidationReport.de] to handler 'com.nike.de.reports.controller.reports.FactoryValidationReportController@1697023'
    2010-06-01 04:26:50,781 DEBUG [org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver] – Resolving exception from handler [com.nike.de.reports.controller.reports.FactoryValidationReportController@1697023]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded' not supported
    2010-06-01 04:26:50,796 DEBUG [org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver] – Resolving exception from handler [com.nike.de.reports.controller.reports.FactoryValidationReportController@1697023]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded' not supported
    2010-06-01 04:26:50,796 DEBUG [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] – Resolving exception from handler [com.nike.de.reports.controller.reports.FactoryValidationReportController@1697023]: org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded' not supported
    2010-06-01 04:26:50,796 DEBUG [org.springframework.web.servlet.DispatcherServlet] – Null ModelAndView returned to DispatcherServlet with name 'de': assuming HandlerAdapter completed request handling


  58. Hi Keith,

    I'd really appreciate if you could answer the question I posted regarding the validation that doesn't take place when you submit an ajax post with wrong data type.

    Thanks,

    Jose


  59. Hello,

    I'm getting the following exception when trying to post a JSON string to the server and have it automatically deserialised to a Java Bean, as in the example shown above:

    org.codehaus.jackson.map.JsonMappingException: No default constructor found for type [simple type, class com.xyz.ItemSearch]: can not instantiate from JSON object (need to add/enable type information?)

    The root cause of this is that ItemSearch is an interface. How do I enable "type information" such that the deserialiser knows it should use ItemSearchImpl instead (apart from changing the parameter type in the controller to use ItemSearchImpl)?

    The main problem is that ItemSearch has a getter which returns another interface, I've tried using @JsonSerialize, but no luck.

    Thank you,

    Silvio


  60. Dear all,

    My "demo" Web Service written based on clinic.roo is running fine on my local Tomcat. As far as I am concerned, I can use any Browser as a client to access and consume its Services simply by specify a URL to it e.g. http://localhost/demo brings up the Home page.

    Now, "demo" is running on a Tomcat in the network. I expect any browser opened up within this network can act as a Web Client to the "demo" Web Service simply by specifying a URL to it e.g. "http://192.168.xx.xx/demo" or "http://192.168.xx.xx:8080/demo" to bring up the Home page. Am I wrong?

    Do I need to write a separate RESTFUL Web client using RestTemplate or any good old web client in order to access and consume "demo"'s Web Services? Under what circumstance do I need a separate RESTFUL web client written up as a consumer? In a Remote access situation?

    As far as I am concerned, clinic.roo is a Web Service with Web client built in. If I send an HTTPRequest from a client machine to "clinic" running in a network Tomcat, the HTTPResponse will be received by the client machine. The business logic to process this HTTPResponse message can be written inside this Web Service "demo" module as well. Am I wrong?

    Please straighten me out. I need your advice.

    Many Thanks.


  61. Jose A and Petar:

    There is a difference in the Binding & Validation lifecycle between "plain form-backing JavaBean" and @RequestBody bind targets. See http://jira.springframework.org/browse/SPR-6740 that tracks this issue.

    So yes, if Jackson cannot bind the POSTed JSON to your @RequestBody Object due to a type mismatch or other error, an Exception will be thrown and your @Controller's handler method cannot prevent that. Declaring a BindingResult argument immediately after a @RequestBody argument has no effect, while declaring a BindingResult immediately after a plain form-backing JavaBean gives you the ability to handle any bind errors yourself. @Valid is also not supported for @RequestBody bind targets, while it is supported for plain JavaBean targets.

    As a workaround, I would consider binding your JSON to a more generic structure such as Map, then doing more strongly-typed Map->JavaBean binding & validation from within your @Controller handler method under your control. You could then handle any bind and validation errors yourself.

    Can you elaborate a little on exactly what kind of JSON->Object mapping failures can occur in your case and how you'd like to handle them? Also, what validation do you need to run? That would help.

    Keith


  62. Hi,

    My "demo" Web Service written based on clinic.roo is running fine on my local Tomcat. As far as I am concerned, I can use any Browser as a client to access and consume its Services simply by specify a URL to it e.g. http://localhost/demo brings up the Home page.

    Now, "demo" is running on a Tomcat in the network. I expect any browser opened up within this network can act as a Web Client to the "demo" Web Service simply by specifying a URL to it e.g. "http://192.168.xx.xx/demo" or "http://192.168.xx.xx:8080/demo" to bring up the Home page. Am I wrong?
    Do I need to write a RESTFUL Web client using RestTemplate or any good old web client in order to access and consume "demo"'s Web Services? Under what circumstance do I need a separate RESTFUL web client written up as a consumer? In a Remote access situation?

    As far as I am concerned, clinic.roo is a Web Service with Web client built in. If I send an HTTPRequest from a client machine to "clinic" running in a network Tomcat, the HTTPResponse will be received by the client machine. The business logic to process this HTTPResponse message can be written inside this Web Service "demo" module as well. Am I wrong?

    Please straighten me out. I need your advice.

    Many Thanks.


  63. The Spring MVC ajax example is very interesting. Especially coming from the Spring.Net world. I do have a source of frustration that maybe you can help resolve.

    Where would I find documentation to support the scenario where JSP's do not play a part and only json is passing between the server and client? I guess directly from the controller in the response?

    Basically it would be one or two base HTML pages with minimal markup, JavaScript library imports (ExtJS) and the server sending/receiving json. The page's behavior and configuration dynamically changes based on AJAX requests/responses and the json contained within them.

    We currently do this in our .Net apps using Spring.Net, JavaScript and custom handlers (ashx's) quite easily.

    Research on the Web and in my growing Spring library has turn up multiple examples of just transmitting json with AJAX but these are from Spring 2.5 before formal AJAX support. I can't find a clear statement if those approaches are deprecated in favor of the latest version of Spring.

    So what is the preferred approach? Assuming that there are improvements in 3.0 then where would I go for this information? Then of course when I get there, is the information complete or will it address my questions piecemeal?

    Any direction you could provide would be greatly appreciated.


  64. "$.fn.serializeHierarchicalObject = function() {

    var objectToPost = {};
    function add(objectToPost, pathProperty, actualValue) {
    if (pathProperty.length == 1)
    objectToPost[pathProperty[0]] = actualValue;
    else{
    if (objectToPost[pathProperty[0]] == null)
    objectToPost[pathProperty[0]] = {};
    add(objectToPost[pathProperty[0]], pathProperty.slice(1), actualValue);
    }
    };
    Dear Andy (Manson),

    I got back to this issue just today and reread your suggested code (below). BTW, thank you so very much for that.

    I am using Spring 3, Hibernate 3 and all available annotations and code was generated by Roo.

    Where should I put these different chunks of code in my project? Can you please elaborate a bit on which java files do they belong to?

    Many Thanks.

    [Your code]
    $.fn.serializeHierarchicalObject = function() {

    var objectToPost = {};
    function add(objectToPost, pathProperty, actualValue) {
    if (pathProperty.length == 1)
    objectToPost[pathProperty[0]] = actualValue;
    else{
    if (objectToPost[pathProperty[0]] == null)
    objectToPost[pathProperty[0]] = {};
    add(objectToPost[pathProperty[0]], pathProperty.slice(1), actualValue);
    }
    };

    this.find('input[type="text"]').each(function() {
    add(objectToPost, $(this).attr('name').split('.'), $(this).val());
    });
    return objectToPost;
    };

    You then simply replace the statement :
    var account = $(this).serializeObject();
    with:
    var account = $(this).serializeHierarchicalObject();


  65. Since I cannot edit what I just posted, I'd like to clarify the cut-&-paste mistake made on it.

    Please ignore the 1st code-paragragh and look for "Dear Andy (Manson)" as the start of my posting.

    Thanks.


  66. Mimi,

    Looking at the example project 'mvc_ajax' that comes with Spring 3 Samples, the code block above could be put inside a script block inside the 'createForm.jsp' page…or (probably neater)…could be placed inside the file 'json.min.js'. If you check the 'json.min.js' file, you'll see a function called serializeObject. The serializeHierarchicalObject function I've suggested would basically replace that functionality, allowing you to serialize both a 'flat object' like the 'Account' object in the sample, or a more complex object such as:


    public class Account {

    private Long id;
    ....(other properties)
    private Person person;

    ...getters and setters...

    }

    We'll assume that the Person class looks like:


    public class Person {

    private Long id;
    private String forename;
    private String surname;
    private Date dateOfBirth;
    ...any other properties you need (Social Sec Number etc)

    //empty constructor
    Public Person()
    { }
    ...getters and setters

    }

    In your createForm.jsp, you could now have e.g. some more input fields whose 'path' property could be person.forename , person.surname etc.

    The script 'serializeHierarchicalObject' will ensure that the Account, and its child object 'Person' are correctly posted to the server by appending finding the '.' after "person", getting the value of "forename", "surname" etc and adding them to a 'Person' Object inside the JSON object that is serialized.

    Hope this helps.

    Andy M


  67. Thank you so very much, Andy.

    Your explanation is precise and very clear. I shall try it out.

    p.s. I am not using json. I shall put it in my createForm.jspx.

    Much Obliged…Mimi


  68. If I may have a follow-up question:

    My classes 'Account', 'Person' are POJOs and managed by Hibernate 3.

    Should I put the serializeHierarchicalObject js inside my Account createForm.jspx and add the empty constructor (I think free from Hibernate, will ascertain) for 'Person' and that will do?

    Many Thanks again…Mimi


  69. Typo above

    "p.s. I am not using json…"

    For some reasons, my head was thinking of Jackson json. I meant Jackson json.


  70. Hi Mimi,

    In regards to Hibernate – I've not actually tried this with Hibernate persistence, but I believe that it should work exactly as normal – Hib will see the Person object inside of the Account object after the form is posted, and it should get persisted just fine.

    Andy M


  71. Hi,

    I'm currently trying out this Ajax support but am having problems with the @JsonIgnore annotation. I have a Form object which contains an ArrayList of Institution objects(Institution is a JPA managed entity and has several one-to-many relationships). I have tried to add the JsonIgnore annotation to the field with a one-to-many relationship but it jackson still tries to serliaze that property and I get a lazy initialization exception. Can any there help? Here's some sample code :

    mvc-config.xml(configuration for jackson):

    SomeController.java :

    @Controller
    public class SomeForm
    {
    public @ResponseBody SomeForm handleRequest(….)
    {
    return someForm;
    }
    }

    SomeForm.java :

    public class SomeForm
    {
    //insert setters/getters for institutions property

    private ArrayList institutions;
    }

    Institution.java :
    @Entity
    @Table(name="some_table")
    pubic class Institution
    {
    @OneToMany
    @JoinColumn(name="some_column")
    @JsonIgnore
    public getSomeEntities() { return someEntities; }

    private List someEntities;
    }


  72. Solved my problem above. I added the code in the org.springframework.samples.ajax.json package and my annotations are working.

    Does anyone know why this is? Does spring ignore Json annotations by default without the extra code provided in the sample?


  73. In the paragraph starting "Underneath the covers", there are dead links to HttpMessageConverter and MappingJacksonHttpMessageConverter.


  74. Keith –

    Does SVN also have the right versions of jars that needs to be used. I am having trouble with @ResponseBody.


  75. I have not had any issues with mvc-ajax sample project myself. I did check into your problem, Java Developer, and used it as an opportunity to go ahead and upgrade the samples to the latest Spring Framework release (3.0.3). I also upgraded Jackson (to 1.5.3) and Log4j (to 1.2.16). Everything looks good from here.

    Best,
    Keith


  76. I was able to get the versions right later on but I was still having issues getting the app to run in Tomcat. Might have done something wrong in haste.

    Thanks for upgrading the samples and listing the release numbers. Will check it out today and let you know.

    How about loading the libraries into SVN ?


  77. Thanks Keith –

    I was able to get the compiled code into Eclipse quickly. Your list along with validation-api-1.0.0.GA and urlrewritefilter-3.2.0 (added jakarta-taglibs-standard-1.1.2,commons-logging-1.1.1-bin) and I was all set.

    However I get the following error on the application URL -

    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'accountController' defined in file [....AjaxSpringSelfBuild\WEB-INF\classes\org\springframework\samples\mvc\ajax\account\AccountController.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [javax.validation.Validator]: : Error creating bean with name 'org.springframework.validation.beanvalidation.LocalValidatorFactoryBean#0': Invocation of init method failed; nested exception is javax.validation.ValidationException: Unable to find a default provider; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.validation.beanvalidation.LocalValidatorFactoryBean#0': Invocation of init method failed; nested exception is javax.validation.ValidationException: Unable to find a default provider


  78. I got the error since I haven't included hibernate-validator. I should have tried Maven build initially. I got the jars from pom.xml and have the application running.

    But when I enter the create account screen and click on "Create". The URL changes to http://localhost:8080/account but I get a "The requested resource (/account) is not available." exception.

    Where should I be looking to troubleshoot ?

    Sorry about spamming the blog with posts.


  79. Its looks like my urlrewrite.xml is not working right for /scripts/**. When I paste the js code into the jsp the AJAX calls work alright.

    Jun 22, 2010 1:33:07 AM org.apache.catalina.core.ApplicationContext log
    INFO: org.tuckey.web.filters.urlrewrite.UrlRewriter DEBUG: processing outbound url for /app/scripts/jquery-1.4.min.js
    Jun 22, 2010 1:33:07 AM org.apache.catalina.core.ApplicationContext log
    INFO: org.tuckey.web.filters.urlrewrite.RuleBase DEBUG: Outbound Rule 0 run called with /app/scripts/jquery-1.4.min.js
    Jun 22, 2010 1:33:07 AM org.apache.catalina.core.ApplicationContext log
    INFO: org.tuckey.web.filters.urlrewrite.RuleBase DEBUG: matched "from"
    Jun 22, 2010 1:33:07 AM org.apache.catalina.core.ApplicationContext log
    INFO: org.tuckey.web.filters.urlrewrite.utils.WildcardMatcher DEBUG: found 1
    Jun 22, 2010 1:33:07 AM org.apache.catalina.core.ApplicationContext log
    INFO: org.tuckey.web.filters.urlrewrite.utils.WildcardMatcher DEBUG: replaced sb is /scripts/jquery-1.4.min.js
    Jun 22, 2010 1:33:07 AM org.apache.catalina.core.ApplicationContext log
    INFO: org.tuckey.web.filters.urlrewrite.UrlRewriter DEBUG: "Outbound Rule 0" matched
    Jun 22, 2010 1:33:07 AM org.apache.catalina.core.ApplicationContext log
    INFO: org.tuckey.web.filters.urlrewrite.UrlRewriter DEBUG: processing outbound url for /scripts/jquery-1.4.min.js

    I have got the scripts folder under the WebContent folder in my Dynamic Web Project.


  80. te


  81. I'm having some trouble installing a a die-roller with database lookup for my site. Could Ajax work as a solution?


  82. Hi,

    I am planning to POST a JSON object (request criteria) to server. How can I get that JSON object as a JAVA object in MVC controller.

    for ex: JSON Object is var jsonObj = {"name":"name1", "age":"23","address":{"street":"street1", "lane":"lane1"}};

    and I want to prepare a java object as per the JSOn object as below
    class Criteria{
    private String name;
    private int age;
    private Address address;
    }
    class Address{
    private String street;
    private String lane;
    }

    Thanks in Advance,
    Manoj


  83. @Manoj:

    First you need to POST the JSON as a serialized String in the Request body with a MIME-Type of Application/JSON (Check your JavaScript toolkit docs for details), not as POST form parameters.

    Second declare a method in your Controller with the following annotations (just as a example)
    public void doSomeThing(@RequestBody Criteria criteria).

    Important info: your parameter classes (and that includes all used inner classes) must be creatable with a default constructor, because the Jackson objectMapper will be unable to deserialize your classes otherwise; the error messages that Spring (at least in 3.02) shows in that case are somewhat unhelpful …


  84. Keith,

    Having Ajax support integrated with Spring is indeed exciting. No longer do I need to bring in DWR just for Ajax remoting.

    Could you clarify on whether Spring Ajax supports server-to-browser exception propagation similar to the way DWR does?

    While hoping that the answer is "yes", I made the following hacks to mvc-ajax app:
    1) use JQuery.ajax() with json datatype in the checkAvailability() js function, as it provides an error callback with the exception object,
    2) modified AccountController.AvailabilityStatus() to in turn throwing RuntimeException and ResourceNotFoundException

    Alas, that was insufficient for the fortune goddess, as the exception object returned in the checkAvailability() error callback was "undefined". I suspect that the Exception type thrown by the controller needs some other handling outside of a @ResponseStatus annotation. Could you please advise on whether there is a way to this?

    Hoping for a regret-free departure from DWR…

    -Mary


  85. I downloaded the spring samples and deployed the mvc-ajax example in my Tomcat server. I am able to load the application but when I put anything in the name field and tab out or click out nothing happens. I've tried with several different names and random text nothing. I am using Firefox 3.6.8 on Windows 7. Any ideas?


  86. I am a moron, never mind my last comment! :)


  87. Hi,
    really useful article. however i need some help with the json (de)serializations. the main problem is that i'm using a non-standard, non-annotated model, which has model map services, but i'm still not capable of tweaking the mvc-ajax sample to work with it. can you please help me plug my model map services before the serialization and after the deserialization? or if can guide me to another tutorial for making custom (de)serializations, so i can swap the object needed (de)serialization with the map provided by my services

    many thanks in advance
    nas


  88. Hi

    I am using Spring and jQuery to pass a form as an object. My pojo includes nullable floats. However, when the fields are empty, Jackson throws an Exeption:

    org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.lang.Float from String value ": not a valid double value

    What do I have to do in order to allow empty values in the form field?

    Thanks
    Er


  89. @er:

    Either don't pass the field from jQuery when its empty in the generated JSON or create a custom Jackson JSON Deserializer which can deal with an empty string.


  90. Hi,

    I am really excited to use these features. Can we use the Multipart Resolver as well with the example you provided with Ajax and Spring 3.0 example?

    All I am looking for is to check will the MultipartResolver of Spring works with the above concept?

    Thanks
    Venkat


  91. Keith,

    I found this post very useful. Thank you very much!

    JK


  92. Hi Keith:

    I've just recently run into problems with Spring MVC ajax with Jackson on Glassfish 2.1:

    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.AnnotationMethodHandlerAdapter#0': Cannot create inner bean '(inner bean)' of type [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter] while setting bean property 'messageConverters' with key [6]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#8': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter]: Constructor threw exception; nested exception is java.lang.VerifyError: Cannot inherit from final class
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:281)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:125)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:355)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:153)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1317)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1076)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:574)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:442)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:458)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:339)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:306)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
    at javax.servlet.GenericServlet.init(GenericServlet.java:270)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1100)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1023)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4969)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:5376)
    at com.sun.enterprise.web.WebModule.start(WebModule.java:345)
    at com.sun.enterprise.web.LifecycleStarter.doRun(LifecycleStarter.java:58)
    at com.sun.appserv.management.util.misc.RunnableBase.runSync(RunnableBase.java:304)
    at com.sun.appserv.management.util.misc.RunnableBase.run(RunnableBase.java:341)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)

    Any ideas?


  93. Ajax is not working with Tiles for me. I cannot find anywhere how to configure Tiles and Ajax.

    Please help


  94. I was using the solution in the mvc-ajax project, including the magic setup code …ajax.json packages and for some reason (perhaps an upgrade to a different version of something) it stopped working. I would get the dreaded 406 and then sometimes a NullPointer exception when Jackson was trying to find a converter for a type.

    For those of you that are struggling with the example, you can just put Jackson on your classpath and start using @ResponseBody. You can also modify the example projects tests to use just the Jackson converter to test your objects for JSON serialization issues. You'll miss some of the features that are in the example project, though.


  95. So i see a solution provided below to resolve the problem of an object inside an object. How about a list of objects inside an object ?

    So Account –> List

    I get the JsonMappingException: Unrecognized field for people[0].firstName –

    Any suggestions ??

    Thank you

    This may be useful to those playing with the mvc-ajax sample.
    Problem Statement:
    How to cope with additional / child objects within the Account object (e.g. create a class 'Person' containing as properties firstName, and lastName – then create an instance of 'Person' inside the Account object that's used as the modelAttribute for the createForm). The problem arises when you add new input fields in the create form that have paths as follows:
    and
    You should notice that the binding works perfectly but a problem occurs on the submit event, namely that you'll now need to explicitly look for fields that contain a '.' and create appropriate child objects in your json object before calling postJSON.
    Here's a sample function I used to handle the problem by finding all form text input elements, checking their path, and creating a child object if the path contains a '.' :

    $.fn.serializeHierarchicalObject = function() {

    var objectToPost = {};
    function add(objectToPost, pathProperty, actualValue) {
    if (pathProperty.length == 1)
    objectToPost[pathProperty[0]] = actualValue;
    else{
    if (objectToPost[pathProperty[0]] == null)
    objectToPost[pathProperty[0]] = {};
    add(objectToPost[pathProperty[0]], pathProperty.slice(1), actualValue);
    }
    };

    this.find('input[type="text"]').each(function() {
    add(objectToPost, $(this).attr('name').split('.'), $(this).val());
    });
    return objectToPost;
    };

    You then simply replace the statement :
    var account = $(this).serializeObject();
    with:
    var account = $(this).serializeHierarchicalObject();

    and you should see your Account, as well as any child objects being correctly serialized on the server side….hope it helps!

    Andy M


  96. Hi, could u plz I want to use this example with Login Spring Security (j_spring_security_check)
    plz tell me how in details


  97. So I have the controllers and everything working. My problem is I want to internationalize the JSON before returning it to my js call. Does anyone have any examples of internationalizing the JSON data before or after putting in the @ResponseBody Model to be returned to the calling JS? I am rendering JSPs and using Ajax calls. The JSPs are internationalized by calling the return modelandview(), but the json objects are not.


  98. Thanks for the serializeHierarchicalObject JavaScript function! It really helped me. During form submission I had this exception:
    JsonMappingException: Unrecognized field "person.firstName"


  99. You can get your custom ConversionService to be used for JSONDeserialization with a minor edit to the FormatAnnotationIntrospectorin the example project linked to above.

    @Override
    public Object findDeserializer(Annotated a)
    {
    if (a instanceof AnnotatedMethod)
    {
    AnnotatedMethod method = (AnnotatedMethod) a;
    TypeDescriptor typeDescriptor = getTypeDescriptorForDeserializer(method);
    for (Annotation ann : typeDescriptor.getAnnotations())
    {
    if (isHandled(ann))
    {
    return new ConvertingDeserializer(this.conversionService, typeDescriptor);
    }
    }

    //Haven't found anything yet
    TypeDescriptor setterType = getTypeDescriptorForUnknownDeserializer(method);
    try
    {
    return new ConvertingDeserializer(this.conversionService, setterType);
    }
    catch(Exception e)
    {
    System.out.println("Ballbags" e);
    }
    }
    return null;
    }


  100. Thanks for the great insight. How about an approach for degrability?
    http://forum.springsource.org/showthread.php?t=98018


  101. Thanx 4 the article.

    But i tried the same and end up getting 406 error


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

    What is the best way to handle these error messages back on the jsp? I'm working with revision 591 of the mvc-ajax project. Given what I understand, the jsp does nothing in the case of and HTTP 400, and the tags add no functionality to this example (beyond what can be accomplished with tags).

    Is there a clean way to handle validation errors when posting JSON to the server?


  103. @tia

    Try this: http://www.ibm.com/developerworks/web/library/wa-restful/


  104. great post. i wanna share also a spoon-feed tutorial on Spring MVC

    http://www.adobocode.com/spring/a-spring-web-mvc-tutorial

    hope it will help people!


  105. I have tried to combine a POST (not json) (which means I can use @ModelAttribute) and return json and it seems to work. I use this from a jQuery ui tab to bind to my model and validate as per a normal post method that would be called on a submit and also display the same errors that the spring errors tag would display, as well as using the relevant css class on fields that have been marked in error.

    My form commandName and any input field paths are setup to bind to my model as per normal.

    The signature in the Controller is

    @RequestMapping(value= "/save", method=RequestMethod.POST)
    public @ResponseBody ValidationErrorsForJsonResponse save(@ModelAttribute("client") @Valid Client client, BindingResult result, SessionStatus status, HttpServletRequest request)

    Inside this method I check the BindingResult and create and return a ValidationErrorsForJsonResponse object which looks like this.

    public class ValidationErrorsForJsonResponse {

    private boolean inError;

    private List errorMessages = new ArrayList();

    private List fieldNames = new ArrayList();

    public ValidationErrorsForJsonResponse(BindingResult result, RequestContext requestContext) {
    if (result.hasErrors()) {
    this.inError = true;
    for (ObjectError error : result.getAllErrors()) {
    errorMessages.add(requestContext.getMessage(error, false));
    }
    for (FieldError fieldError : result.getFieldErrors()) {
    fieldNames.add(fieldError.getField());
    }
    }
    }

    public boolean isInError() {
    return inError;
    }

    public List getErrorMessages() {
    return errorMessages;
    }

    public List getFieldNames() {
    return fieldNames;
    }

    }

    The code in the controller method is:

    RequestContext context = new RequestContext(request);

    if (result.hasErrors()) {
    return new ValidationErrorsForJsonResponse(result, context);
    }

    // more custom validation if needed and not covered by @Valid
    // similarly create and return new ValidationErrorsForJsonResponse

    //All OK – save
    //create and retun a new ValidationErrorsForJsonResponse
    //(this will have no error messages as the BindingResult has no errors)

    And the javascript…
    //span with an id jsonErrors to look like the span displayed by the spring errors tag
    var errorsDisplayElement = $("#jsonErrors");
    errorsDisplayElement.empty(); //empty it from previously displayed errors
    //NOT $.postJSON and Spring will do the binding here and serialize the form
    $.post("/save", $("form").serialize(), function(data) {
    //data is ValidationErrorsForJsonResponse
    if (data.inError) {
    //add error messages in errors span
    $.each(data.errorMessages, function(i, item){
    errorsDisplayElement.append(item ");
    });
    errorsDisplayElement.children("br").last().remove();
    //add an error class to any fields in error
    //same as would have used in cssErrorClass
    $.each(data.fieldNames, function(i, item){
    var field = $("[name='" item "']");
    field.addClass("fieldError");
    });
    } else {
    //do what you need to do if no errors
    //in my case go to the next tab
    }
    });

    I have briefly tested this in one scenario only and it works. Now I need to battle test it a bit.

    Keith, anything glaringly wrong with this approach?


  106. Very nice solution.


  107. Keith,
    i have the same problem with the Checkboxes JC Mann has. The binding does not work because of the hidden field ("_something"). What is the proper way to resolve this issue? Can you give me a hint how to write an own DataBinder for checkboxes?

    Thx in advance,

    kleino


  108. Http Post with request "content-type=application/x-www-form-urlencoded" form not working in Spring MVC 3.
    After posting a request, I am getting Http Status code 415: The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ().

    Ref Code:
    In AccountController:
    @RequestMapping( method=RequestMethod.POST)
    public @ResponseBody Map create(@RequestBody Account account, HttpServletResponse response)

    It seems that FormHttpMessageConverter (used in case of @RequestBody) is not able to bind target class as @ModelAttribute does . Do we need to replace @ModelAttribute instead of @RequestBody ?

    Any Other Solution ?


  109. Hello, i took your trunk src today. Tests give below error. any suggestions?

    org.springframework.core.convert.ConversionFailedException: Unable to convert value "1000" from type 'java.lang.String' to type 'java.math.BigDecimal'; nested exception is java.lang.IllegalArgumentException: Unable to parse '1000'
    	at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:40)
    	at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:183)
    	at org.springframework.samples.mvc.ajax.json.ConvertingDeserializer.deserialize(ConvertingDeserializer.java:28)
    	at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:135)
    	at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:221)
    	at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:391)
    	at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:287)
    	at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:1588)
    	at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1172)
    	at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:132)
    	at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:154)
    	at org.springframework.samples.mvc.ajax.account.AccountJsonBindingTests.testAnnotationDrivenJsonConversion(AccountJsonBindingTests.java:51)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at junit.framework.TestCase.runTest(TestCase.java:168)
    	at junit.framework.TestCase.runBare(TestCase.java:134)
    	at junit.framework.TestResult$1.protect(TestResult.java:110)
    	at junit.framework.TestResult.runProtected(TestResult.java:128)
    	at junit.framework.TestResult.run(TestResult.java:113)
    	at junit.framework.TestCase.run(TestCase.java:124)
    	at junit.framework.TestSuite.runTest(TestSuite.java:232)
    	at junit.framework.TestSuite.run(TestSuite.java:227)
    	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: java.lang.IllegalArgumentException: Unable to parse '1000'
    	at org.springframework.format.support.FormattingConversionService$ParserConverter.convert(FormattingConversionService.java:238)
    	at org.springframework.format.support.FormattingConversionService$2.convert(FormattingConversionService.java:127)
    	at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:37)
    	... 30 more
    Caused by: java.text.ParseException: 1000
    	at org.springframework.format.number.AbstractNumberFormatter.parse(AbstractNumberFormatter.java:56)
    	at org.springframework.format.number.CurrencyFormatter.parse(CurrencyFormatter.java:79)
    	at org.springframework.format.number.CurrencyFormatter.parse(CurrencyFormatter.java:1)
    	at org.springframework.format.number.AbstractNumberFormatter.parse(AbstractNumberFormatter.java:1)
    	at org.springframework.format.support.FormattingConversionService$ParserConverter.convert(FormattingConversionService.java:236)
    	... 32 more
    

  110. Hello, i took your trunk src today. Tests give below error. any suggestions. Is this a bug?

    org.springframework.core.convert.ConversionFailedException: Unable to convert value "1000" from type 'java.lang.String' to type 'java.math.BigDecimal'; nested exception is java.lang.IllegalArgumentException: Unable to parse '$1,000'
    	at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:40)
    	at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:183)
    	at org.springframework.samples.mvc.ajax.json.ConvertingDeserializer.deserialize(ConvertingDeserializer.java:28)
    	at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:135)
    	at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:221)
    	at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:391)
    	at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:287)
    	at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:1588)
    	at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1172)
    	at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:132)
    	at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:154)
    	at org.springframework.samples.mvc.ajax.account.AccountJsonBindingTests.testAnnotationDrivenJsonConversion(AccountJsonBindingTests.java:51)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	at java.lang.reflect.Method.invoke(Method.java:597)
    	at junit.framework.TestCase.runTest(TestCase.java:168)
    	at junit.framework.TestCase.runBare(TestCase.java:134)
    	at junit.framework.TestResult$1.protect(TestResult.java:110)
    	at junit.framework.TestResult.runProtected(TestResult.java:128)
    	at junit.framework.TestResult.run(TestResult.java:113)
    	at junit.framework.TestCase.run(TestCase.java:124)
    	at junit.framework.TestSuite.runTest(TestSuite.java:232)
    	at junit.framework.TestSuite.run(TestSuite.java:227)
    	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: java.lang.IllegalArgumentException: Unable to parse '1000'
    	at org.springframework.format.support.FormattingConversionService$ParserConverter.convert(FormattingConversionService.java:238)
    	at org.springframework.format.support.FormattingConversionService$2.convert(FormattingConversionService.java:127)
    	at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:37)
    	... 30 more
    Caused by: java.text.ParseException: 1000
    	at org.springframework.format.number.AbstractNumberFormatter.parse(AbstractNumberFormatter.java:56)
    	at org.springframework.format.number.CurrencyFormatter.parse(CurrencyFormatter.java:79)
    	at org.springframework.format.number.CurrencyFormatter.parse(CurrencyFormatter.java:1)
    	at org.springframework.format.number.AbstractNumberFormatter.parse(AbstractNumberFormatter.java:1)
    	at org.springframework.format.support.FormattingConversionService$ParserConverter.convert(FormattingConversionService.java:236)
    	... 32 more
    

  111. Hey, it's all great, but as far as Portlet environment is concerned I can't seem to find answers anywhere about this :

    https://jira.springsource.org/browse/SPR-7344


  112. Let's try my first question again since I cannot edit my post:


    What do the and tags in your createForm.jsp page do? You're submitting these using AJAX, so what are these here for?

    Thanks,
    James


  113. Hi Keith,

    Sorry for all the posts, but your blog software keeps killing any HTML I try to post. Here is the HTML from my example above:


    <div id="form" class="form">
    <form id="sign_up_form" action="/signuptest.do" method="post">
    <div>
    <h3 id="contact_information">Contact Information</h3>
    <input type="text" name="firstname" value="james" id="first_name" />
    <input type="text" name="lastname" value="m" id="last_name" />
    <input type="text" name="companyname" value="test" id="company" class="wide" />
    <input type="text" name="email" value="test2@testing.com" id="email_address" class="wide" />
    <input type="text" name="subdomain" value="test2" id="subdomain" />

    As you can see above, no non-HTML markup.

    And my original question should make more sense with the JSTL/Spring Taglibrary markup in place:


    What do the <form:form> and <form:input> tags in your createForm.jsp page do? You're submitting these using AJAX, so what are these here for?

    Thanks,
    James


  114. How can i send multiple objects thru ajax and fetch them in controller for manipulation???

    For Example, can my jsp page shows 100 Employees, I select all of them and click on submit.. Now my controller should get a list consisting of 100 Employee objects…


  115. Rahul,

    What I did is serialized my data into JSON and then use Jackson or Gson to deserialize the JSON back to objects. With a list of objects it will be tricky but once you figure it out it will be a clean solution.

    I would recommend you receive them in the method using the RequestBody annotation.

    James


  116. @James,

    Thanx…
    The figuring out part seems to be a hard one :)


  117. @James – Good post. Almost all search results on 'Ajax Spring' takes me to this page only.

    Anyway we could do this without using annotation? Or am I asking totally stupid?


  118. @James, the form tags are used to render the page with properly formatted values. For example you'll see the balance field which is a monetary amount, the equity allocation is a percent, and the renewal date is also properly formatted. After the tags have generated the HTML of course they play no further role on the client side regardless of how the form is submitted.


  119. Can somebody tell , how it works for Spring MVC portlets using @ResourceMapping/ResourceURL?


  120. Hi,

    How can you post collections to the server using the @RequestBody tag to map automatically? I downloaded the example app & added a an array list of Message classes to the Account class with appropriate getter & setter:

    private List messages = new ArrayList ();

    The Message class just has one instance variable called name.

    I added the following to the createForm.jsp:

    Message

    When I click the create button the following json post is made:

    {"name":"name","balance":"£1,000.00","equityAllocation":"60%","renewalDate":"28/01/12","messages[0].name":"test"}

    And it gives me the following error:

    org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "messages[0].name"

    How can I map collections automatically using @RequestBody without parsing the post myself?

    thanks,
    Richard


  121. I'm using @ResponseBody and @RequestBody for my REST JSON service. Things work fine in fact great. Problem starts when handling exceptions. What I've done is in my Controller class I've defined one method to handle any uncaught exceptions. Below is the signature of the method annotated with @ExceptionHandler

    @ExceptionHandler( Exception.class )
    public @ResponseBody ErrorDetails handleUncaughtExceptions( Exception ex, HttpServletRequest req )

    What I'm trying to do is any exception which is not handled will be handled over here in handleUncaughtExceptions class which will return details like error code, error desc bundled in ErrorDetails class. I want the client to return it as JSON string and hence I annotated it with ResponseBody annotation.

    Doing so doesnt work as expected. I'm expecting a JSON string like {"errorCode":"000","errorDesc":"System Error","ticketNumber":"1381675273"}, but what I'm getting is complete stack trace. Does @ResponseBody does not work with @ExceptionHandler or am I doing something wrong.

    Regards,
    - Jay


  122. @Jay: to only way I got that to work was to specify the return type as String and format the exception JSON manually. Not pretty but works:

    i.e.:

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String handleExceptions(Exception ex, HttpServletRequest request){

    }


  123. @lutz, thanks for the response. As of now what I've done is have returned ModelAndView which maps to a generic JSP. This JSP sets content-type to applicaiton/json and it returns a JSON string by reading the ErrorDetails object which I push in model in handleUncaughtExceptions method I mentioned.

    But this is not the clean solution. Hope to find some nice solution for this in future releases.

    Regards,
    - Jay


  124. @Jay, perhaps you are running into this issue?
    https://jira.springframework.org/browse/SPR-6693


  125. Sorry, the issue I meant to point to was this:
    https://jira.springframework.org/browse/SPR-6902


  126. @Rossen, yeah it seems like SPR-6902. Any idea when 3.0.6 is scheduled to release? Or there is any easy fix for this which I can apply to my 3.0.5 based code? Actually am using it for an application which will be going on production very soon.


  127. Folks,

    I have spend half a day trying to work this out. I would really appreciate it if somebody could help me out.

    Basically based on this demo.. I want to post some json data in ajax post to my mvc controller but that controller is not being called at all?

    See code below:

    Video.jsp
    ———
    var jsonStr = "{{dojoId: 'uni1', title: 'Lake', thumnailUrl: '/images/lake.jsp'},{dojoId: 'uni2', title: 'Orange', thumnailUrl: '/images/orange.jsp'}}";

    AM.xhrGet("saveVideoSelection", jsonStr, check);

    dojoAjax.js(Dojo Ajax Post)
    —————————
    AM.xhrPost = function(url, params, callback) {
    if (!params) params = {};
    dojo.addOnLoad(function () {
    dojo.xhrPost({
    url: url,
    content: params,
    timeout: 3000, // give up after 3 seconds
    handleAs: "json",
    handle: function(data,args){
    if(typeof data == "error"){
    console.warn("error!");
    console.log(args);
    contentNode.innerHTML = "Error found";
    } else {
    callback;
    //contentNode.innerHTML = data;
    }
    },
    load: callback
    });
    });
    };

    VideoController.Java
    ——————–
    @RequestMapping(method = RequestMethod.POST)
    public @ResponseBody String testsaveGallery(@RequestBody List videos) {
    try {
    ………
    } catch (IOException e) {
    throw new IllegalArgumentException("Couldn't parse json into a search request", e);
    }
    return "done";
    }

    Video.Java:
    ———–
    private int userOrder;
    private String dojoId;
    private String owner;
    private String title;
    private String thumnailUrl;
    private String htmlEmbedCode;
    private Date lastUpdated;

    Kind Regards,
    Fahd


  128. @Fahd

    I've alway had problems passing Lists into Spring MVC, but you might want to try to pass an actual list to it.

    "{{dojoId: 'uni1', title: 'Lake', thumnailUrl: '/images/lake.jsp'},{dojoId: 'uni2', title: 'Orange', thumnailUrl: '/images/orange.jsp'}}";

    This is not a list, it's not event valid JSON.
    a) Use "[" for lists
    b) Quote the id's : "dojoId": 'uni1'


  129. The sample project,ajax.json.FormatAnnotationIntrospector.java.
    public Object findDeserializer(Annotated a) {} has one error:
    Cannot override the final method from AnnotationIntrospector
    why?


  130. The sample code autowires the Validator in the AccountController constructor. When I run it locally it works fine. When I try and implement the same in my own controller constructor it complains about the javax.validation.Validator bean cannot be found.

    Can you tell me where the validator bean is configured in the context?

    Also have you got the validation working with the @Valid annotation on the Post JSON method?

    Another issue I have found if you have a checkbox in your form and you use the JTSL form tags it creates a hidden field with _ in front of the ID. This seems to cause problems with the binding. To get around this I modified the serializeObject with ignore any input name with _ in the front.


  131. I'm currently using Spring MVC 3.0 with ExtJS and I'm trying to find a way to customize my JSON binding into Java beans.

    Here is the JSON I'm sending to the server:

    [CODE]
    {
    "data":[{"name":"1","role":"ROLE_SENIOR_ANALYST","id":20114},{"name":"2","role":"ROLE_SENIOR_ANALYST","id":20115}]
    }
    [/CODE]

    In the server side I have the following java bean:
    [CODE]
    ublic class ViewBean {
    private List data;

    public ViewBean () {
    }

    public List getData() {
    return data;
    }

    public void setData(List data) {
    this.data = data;
    }
    }
    [/CODE]

    My Controller looks like:

    [CODE]
    @RequestMapping(value = "/save-permissions.json", method = RequestMethod.POST)
    public void saveRafaPermissions(@RequestBody ViewBean data) {
    System.out.println("PERMISSION ID: " data.getData().get(0).getId());
    System.out.println("PERMISSION NAME: " data.getData().get(0).getName());
    }
    [/CODE]

    Now, as you can imagine I don't have the [B]setId [/B]method in the Permission because I don't want to expose it, and this makes the [B]MappingJacksonHttpMessageConverter[/B] crash because it can't find the setId.

    Normally with binders I would detect if the class I'm trying to bind is an extension of one that can get from the database and just fetch it from the db and then set the values.

    How can I do the same here?

    I posted this on the springsource forum as well.


  132. I got the server part running.
    When I invoke the server per browser
    http://localhost:8888/message?message=hallo
    I receive the correct serialized JSON:
    {"message":"Hello to you too"}

    But I am not able to get this to work with javascript. I already tried JQUERY and Prototype. I used firebug in order to evaluate and it always says:
    Loading of the source failed:: http://localhost:8888/message?message=Hallo

    Why are the javascript frameworks not able to process the server response?


  133. @Rafael:

    I had a similar problem and I figure out that since I don't want the id being sent to server back, I added the following annotation on my class (assuming you are using jackson)

    @JsonIgnoreProperties({"id"})

    hope this helps.


  134. @Steve

    This issue could be as small as using the right quotes on your javascript page. (") can only contain (') and vice versa and since your json string contains double quotes(") try putting them in a variable under single quotes(') like below

    <input name='myJson' value='{"message":"Hello to you too"}' > </input>

    Hope this solves your problem.


  135. @Eddie Bragg

    See the following excerpt taken from sping reference doc:

    ——————————————————————————————————
    Spring provides full support for the JSR-303 Bean Validation API. This includes convenient support for bootstrapping a JSR-303 implementation as a Spring bean. This allows for a javax.validation.ValidatorFactory or javax.validation.Validator to be injected wherever validation is needed in your application.

    Use the LocalValidatorFactoryBean to configure a default JSR-303 Validator as a Spring bean:

    <bean id="validator"
    class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

    The basic configuration above will trigger JSR-303 to initialize using its default bootstrap mechanism. A JSR-303 provider, such as Hibernate Validator, is expected to be present in the classpath and will be detected automatically. "
    ——————————————————————————————————

    So just configure the above bean in your spring context and woooaaalaa…


  136. @Fahd

    Thx for the fast help. But I have problem with the server's response. The request is working fine and correctly processed. The response does not contain any text at all. Surprisingly it works inside the explorer but not in firefox or chrome. That tells me Im doing something fundamentally wrong and only the explorer is able to ignore it.


  137. Fixed. Never trigger your ajax call with the onclick attribute of html-.


  138. Very good post (REST and Spring is the future in the cloud ) but i have a problem :
    - i have made a check out of mvc-ajax sample and it runs perfectly on Spring tc server with maven
    - but i want to use the same logic with a project on google app engine :
    —> it always give me an UNSUPPORTED_MEDIA_TYPE error in my navigator.
    Why ?


  139. Firstly, thanks for the post – I found it a really helpful leg up. However, I've hit a snag (of course :-) )…

    if I use a method signature containing an @RequestBody all works well, but I have to manually invoke the validation framework as shown. The moment I try to use @Valid instead or as well I end up with an empty parameter object.

    So my question is: is there anyway to combine a JSON post with Spring's automatic validation/BindingResult capabilities?

    tia


  140. Thanks for your post, was very helpful !


  141. Hi,
    Thanks for this turorial,

    How to downlaod from :
    https://src.springframework.org/svn/spring-samples/

    and import them to eclipse or netbeans ?

    Thanks lot.

    John.


  142. Hi,
    Thanks for this turorial,

    How to downlaod mvc.ajax project or its war from :
    https://src.springframework.org/svn/spring-samples/

    and import them to eclipse or netbeans ?

    Thanks lot.

    John.


  143. I have a simple Spring MVC Roo generated app. I'm trying to read an xml file and return it as json-wrapped Response POJO but I'm getting java.lang.IllegalStateException: getOutputStream() has already been called for this response.

    here's the method:

    @RequestMapping(value="/json/fromxml/{filename}", method=RequestMethod.GET)
    public @ResponseBody Response readXml(@PathVariable("filename") String filename)
    {
    Response r = new Response();
    String xml ="";
    try
    {
    InputStream is = servletContext.getResourceAsStream("/xml/" filename ".xml");
    if (is != null) {
    Writer writer = new StringWriter();

    char[] buffer = new char[1024];
    try {
    Reader reader = new BufferedReader(
    new InputStreamReader(is, "UTF-8"));
    int n;
    while ((n = reader.read(buffer)) != -1) {
    writer.write(buffer, 0, n);
    }
    } finally {
    is.close();
    }
    xml = writer.toString();
    } else {
    xml = "";
    }

    }catch(Exception e)
    {
    r.setStatus(Response.STATUS.ERROR);
    return r;
    }
    JSONObject xmlJSONObject = null;
    try {
    xmlJSONObject = XML.toJSONObject(xml);
    } catch (JSONException e) {
    r.setStatus(Response.STATUS.ERROR);
    return r;
    }
    r.setStatus(Response.STATUS.OK);
    r.setBody(xmlJSONObject);
    return r;
    }

    Here's the stack trace:

    java.lang.IllegalStateException: getOutputStream() has already been called for this response at org.apache.catalina.connector.Response.getWriter(Response.java:611) at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198) at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125) at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118) at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:188) at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:118) at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:77) at org.apache.jsp.WEB_002dINF.layouts.default_jspx._jspService(default_jspx.java:83) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:386) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646) 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.apache.tiles.servlet.context.ServletTilesRequestContext.forward(ServletTilesRequestContext.java:241) at org.apache.tiles.servlet.context.ServletTilesRequestContext.dispatch(ServletTilesRequestContext.java:222) at org.apache.tiles.renderer.impl.TemplateAttributeRenderer.write(TemplateAttributeRenderer.java:44) at org.apache.tiles.renderer.impl.AbstractBaseAttributeRenderer.render(AbstractBaseAttributeRenderer.java:106) at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:670) at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:690) at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:644) at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:627) at org.apache.tiles.impl.BasicTilesContainer.render(BasicTilesContainer.java:321) at org.springframework.web.servlet.view.tiles2.TilesView.renderMergedOutputModel(TilesView.java:124) at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250) at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1047) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:817) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549) at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 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.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:127) 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:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:662)


  144. Is that possible to do with spring mvc portlet ?


  145. Hi,

    I am unable to download the sample repoisitory mvc-ajax if you could send to my mail it will be very helpful


  146. omg omg omg…
    it's make me confuse…

    !@#$%^&*


  147. Hi guys,

    in my application submitted data are validated correctly and a map with errors is returned to the client; however, on the client I can't understand how to display these errors. Should I achieve it with JS, or Spring can automatically bind it to ? When the returned map has an error I can see it in the response content as "{"tag":"size must be between 2 and 30","name":"size must be between 2 and 30"}". My application is based on the mvc-ajax sample.

    Any help are really appreciated.

    -Cyril


  148. Hi guys,

    Just something for those complaining about SC_BAD_REQUEST and not being able of retrieving error messages:

    Instead of returning a BAD_REQUEST, try returning a SC_ACCEPTED, probably it wasn't meant to be used this way. But in this case is practical approach for distinguishing among a success post,and a failure one and at the same time being able of retrieving error codes.

    I am not completely happy with this way of using the http code, so if someone gets something better it will be welcome.

    Jesus


  149. Hi! I have simple resource which should return JSON array, but it returns object in which is array:

    @RequestMapping(value = "/types", method = RequestMethod.GET)
    public List types() {
    ArrayList list=new ArrayList();
    list.add(new JsonObject("Audi"));
    list.add(new JsonObject("Mercedes"));
    return list;
    }
    Where JsonObject is simple class with three String atributes (value,id,label).

    Returns:

    {"jsonObjectList":[{"value":"Audi","id":"Audi","label":"Audi"},{"value":"Mercedes","id":"Mercedes","label":"Mercedes"}]}

    But I need:

    [{"value":"Audi","id":"Audi","label":"Audi"},{"value":"Mercedes","id":"Mercedes","label":"Mercedes"}]

    How to achieve that?


  150. @matejuh: You are are missing the @ResponseBody Annotation on the returned List:

    public @ResponseBody List types()


  151. I solved the problem. What I needed was to migrate on 3.1 and use what did the trick.


  152. I needed migrate to Spring 3.1, and set a property on the MappingJacksonJsonView bean called extractValueFromSingleKeyModel to true to remove the wrapper.


  153. Hi,

    I am trying to run mvc-ajax in Netbeans IDE and am getting the error below that I am not able to resolve. mvc-basic example worked fine. Would really appreciate advise on this error.

    Many thanks,radhika

    ERROR]Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project mvc-ajax: Compilation failure: Compilation failure:
    [ERROR]/Users/radhika/NetBeansProjects/mvcajax/src/main/java/org/springframework/samples/mvc/ajax/json/ConversionServiceAwareObjectMapper.java:[20,32] cannot find symbol
    [ERROR]symbol : constructor SerializationConfig(org.codehaus.jackson.map.ClassIntrospector,org.codehaus.jackson.map.AnnotationIntrospector,org.codehaus.jackson.map.introspect.VisibilityChecker.Std,)
    [ERROR]location: class org.codehaus.jackson.map.SerializationConfig
    [ERROR]/Users/radhika/NetBeansProjects/mvcajax/src/main/java/org/springframework/samples/mvc/ajax/json/ConversionServiceAwareObjectMapper.java:[21,34] cannot find symbol
    [ERROR]symbol : constructor DeserializationConfig(org.codehaus.jackson.map.ClassIntrospector,org.codehaus.jackson.map.AnnotationIntrospector,org.codehaus.jackson.map.introspect.VisibilityChecker.Std,)
    [ERROR]location: class org.codehaus.jackson.map.DeserializationConfig
    [ERROR]-> [Help 1]
    [ERROR]
    [ERROR]To see the full stack trace of the errors, re-run Maven with the -e switch.
    [ERROR]Re-run Maven using the -X switch to enable full debug logging.
    [ERROR]
    [ERROR]For more information about the errors and possible solutions, please read the following articles:
    [ERROR][Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException


  154. Hi,
    I am using spring-MVC 3/Jquery for portlet development on lifery. At page rander time portlets will not contain any data except that empty place-holder (a jsp with empty div) with loading effect. At the same time one ajax call will be activated from each portlet to fetch the server side data to display in the portlet. Data will be formed using CMS some webservice/DB call and finally returned and fill to the portlet placeholder by Jquery. Also I have multiple views for each portlet depending on user preferences and role.
    1Approach: To do all data computation/formation (CMS ws/DB call html css) in controller and append it in one stringbuffer and write it back depending on view required to be rander. (traditional one)
    2Approach: create different jsps (each jsp will contain its specific CMS ws/DB call html css) for all type of views and depending upon user preferences return that jsp from ajax controller.

    Problem with first approach is since I am returning complete view for a portlet so there will be lot of developer effort while creating string buffer.

    Second approach I am not sure whether it works efficiently or not.

    What would be bast how I will do it from spring I am new to JSON so can i use it in my case?
    Please help


  155. I am new to Spring and just imported the mvc-ajax into my IDE eclipse/STS.
    ran mvn clean install and got all the dependencies as well. but when i try to run this on tomcat i get the following stacktrace because of which i get HTTP 404 requested resource is not available. Please help. also for some reason in my IDE i have a lot of red markers i.e errors. do i need to manually add all jars as well in the lib folder?

    SEVERE: Exception starting filter characterEncodingFilter
    java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterEncodingFilter
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1523)
    at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:415)
    at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:397)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:118)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:252)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:372)
    at org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:98)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4584)
    at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5262)
    at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5257)
    at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    Aug 26, 2011 6:25:24 PM org.apache.catalina.core.StandardContext startInternal
    SEVERE: Error filterStart
    Aug 26, 2011 6:25:24 PM org.apache.catalina.core.StandardContext startInternal
    SEVERE: Context [/mvc-ajax] startup failed due to previous errors
    Aug 26, 2011 6:25:24 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler ["http-bio-8080"]
    Aug 26, 2011 6:25:24 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler ["ajp-bio-8009"]
    Aug 26, 2011 6:25:24 PM org.apache.catalina.startup.Catalina start
    INFO: Server startup in 292 ms


  156. Hi,
    can someone please help me? i posted my error a week ago but not replies.

    i got the mvc-ajax/trunk, ran mvn clean install successfully but unable to run http://localhost:8080/mvc-ajax/
    as soon as i do run on server using Tomcat v 7.0 i get the following error. Someone please help me in resolving this. i am using jre6.

    Aug 31, 2011 4:18:41 PM org.apache.catalina.core.AprLifecycleListener init
    INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jre6\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:/Program Files/Java/jre6/bin/client;C:/Program Files/Java/jre6/bin;C:/Program Files/Java/jre6/lib/i386;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\ant\apache-ant-1.8.2\bin;C:\eclipse;;.
    Aug 31, 2011 4:18:42 PM org.apache.tomcat.util.digester.SetPropertiesRule begin
    WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:mvc-ajax' did not find a matching property.
    Aug 31, 2011 4:18:42 PM org.apache.coyote.AbstractProtocol init
    INFO: Initializing ProtocolHandler ["http-bio-8080"]
    Aug 31, 2011 4:18:42 PM org.apache.coyote.AbstractProtocol init
    INFO: Initializing ProtocolHandler ["ajp-bio-8009"]
    Aug 31, 2011 4:18:42 PM org.apache.catalina.startup.Catalina load
    INFO: Initialization processed in 507 ms
    Aug 31, 2011 4:18:42 PM org.apache.catalina.core.StandardService startInternal
    INFO: Starting service Catalina
    Aug 31, 2011 4:18:42 PM org.apache.catalina.core.StandardEngine startInternal
    INFO: Starting Servlet Engine: Apache Tomcat/7.0.19
    Aug 31, 2011 4:18:42 PM org.apache.catalina.core.StandardContext filterStart
    SEVERE: Exception starting filter characterEncodingFilter
    java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterEncodingFilter
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1523)
    at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:415)
    at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:397)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:118)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:252)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:372)
    at org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:98)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4584)
    at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5262)
    at org.apache.catalina.core.StandardContext$2.call(StandardContext.java:5257)
    at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
    Aug 31, 2011 4:18:42 PM org.apache.catalina.core.StandardContext startInternal
    SEVERE: Error filterStart
    Aug 31, 2011 4:18:42 PM org.apache.catalina.core.StandardContext startInternal
    SEVERE: Context [/mvc-ajax] startup failed due to previous errors
    Aug 31, 2011 4:18:42 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler ["http-bio-8080"]
    Aug 31, 2011 4:18:42 PM org.apache.coyote.AbstractProtocol start
    INFO: Starting ProtocolHandler ["ajp-bio-8009"]
    Aug 31, 2011 4:18:42 PM org.apache.catalina.startup.Catalina start
    INFO: Server startup in 302 ms


  157. Hi,

    I am creating an application with DOJO at view layer and SpringMVC at controller layer. I am trying to populate a combobox within a form in JSP page with a list which is present at controller and marked as @ModelAttribute.
    When I use values property of the combobox definetely list.toString() gets called and a comma-separated value is displayed within combobox.
    The controller class is given below:
    @Controller
    public class CreateItemController extends BaseController {

    @ModelAttribute("brandList")
    public @ResponseBody List getBrandList() {
    List brandList = new ArrayList();
    brandList.add("Brand A");
    brandList.add("Brand B");
    brandList.add("Brand C");
    return brandList;
    }

    @ModelAttribute("itemList")
    public List getItemList() {
    List itemList = new ArrayList();
    itemList.add("item A");
    itemList.add("item B");
    itemList.add("item C");
    return itemList;
    }

    @ModelAttribute("companyList")
    public List getCompanyList() {
    List companyList = new ArrayList();
    companyList.add("company A");
    companyList.add("company B");
    companyList.add("company C");
    return companyList;
    }

    @ModelAttribute("categoryList")
    public List getCategoryList() {
    List categoryList = new ArrayList();
    categoryList.add("category A");
    categoryList.add("category B");
    categoryList.add("category C");
    return categoryList;
    }

    @ModelAttribute("description")
    public String getDescription(){
    return "My description";
    }

    @RequestMapping(value = "/createItem.htm", method = RequestMethod.GET)
    public void executeForm(Model model) {
    model.addAttribute(new ItemForm());
    }

    @RequestMapping(value = "/createItem", method = RequestMethod.GET)
    public String execute() {
    return "redirect:createItem.htm";
    }

    @RequestMapping(value = "/saveItem.htm", method = RequestMethod.POST)
    public void simple(@ModelAttribute ItemForm itemForm, Model model) {
    model.addAttribute("name", itemForm.getName());
    model.addAttribute("description", itemForm.getDescription());
    model.addAttribute("expectedPrice", itemForm.getExpectedPrice());
    model.addAttribute("parent", itemForm.getParent());
    model.addAttribute("company", itemForm.getCompany());
    model.addAttribute("brandList", itemForm.getBrandList());
    model.addAttribute("categoryList", itemForm.getCategoryList());
    model.addAttribute(itemForm);
    }
    }

    The JSP page is here:

    Save It
    Cancel

    function submitForm() {
    var button = dijit.byId("submitButton");
    dojo.connect(button, "onClick", function(event) {
    //Stop the submit event since we want to control form submission.
    event.preventDefault();
    event.stopPropagation();

    //The parameters to pass to xhrPost, the form, how to handle it, and the callbacks.
    //Note that there isn't a url passed. xhrPost will extract the url to call from the form's
    //'action' attribute. You could also leave off the action attribute and set the url of the xhrPost object
    //either should work.
    var xhrArgs = {
    form: dojo.byId("dataForm"),
    handleAs: "text",
    load: function(data) {
    dojo.byId("response").innerHTML = "Form posted.";
    },
    error: function(error) {
    //We'll 404 in the demo, but that's okay. We don't have a 'postIt' service on the
    //docs server.
    dojo.byId("response").innerHTML = "Form posted.";
    }
    }
    //Call the asynchronous xhrPost
    dojo.byId("response").innerHTML = "Form being sent…"
    var deferred = dojo.xhrPost(xhrArgs);
    });
    }
    dojo.addOnLoad(submitForm);

    I am trying to populate all the 4 combo boxes present in the form from the ModelAttributes present in controller.

    Please provide me some pointers or solution for this problem.

    Regards,

    Bipul Sinha.


  158. There seems to be some problem with the JSP content being submitted. Hence, re-submitting it
    <!–

    Save It
    Cancel

    –>


  159. Here is the combobox code snippet without using angular brackets.
    div dojoType="dijit.form.ComboBox" title="Brand:" id="createItembrand" jsId="brandList" name="brandList" value="${brandList}"

    Regards,

    Bipul Sinha


  160. xxxxxxxxxxxxxxxxxxxxxxxxxx


  161. @huang hairong

    I'm having the same problem with Glassfish 3.1. Apparently it comes with Jackson 1.7.1 in which this method is declared final.

    If you update the POM in the project, you will get compilation error.

    Thank you,

    AT.


  162. Hi,
    I run mvc-ajax from Netbeans, the welcome page displays fine , I clicked in :
    Ajax @Controller Example

    Create Account form display, I filled up the text fileds,

    BUT when I pressed button Create I got this error :

    description The server refused this request because the request entity is in a format not supported by the requested resource for the requested method ().

    Your help is appreciated.
    Thanks


  163. Great job Keith! I have a question that is puzzling me. I'm using Spring-MVC and Spring Android and leveraging Jackson and GSon respectively. When I specify @ResponseBody on my method, Android slurps up the Gson (JSON) perfectly. However, If I remove the @ResponseBody and allow the ContentNegotiatingViewResolver to do its thing, I receive:

    09-14 17:50:31.456: ERROR/AndroidRuntime(21577): Caused by: java.lang.RuntimeException: Unable to invoke no-args constructor for class [Lcom.androidologist.gb.beans.Brew;. Register an InstanceCreator with Gson for this type may fix this problem.

    The server side is returning a List. What is it about @ResponseBody that differs? When I access the URL from Chrome, I get the exact same JSON structure as per a TextPad5 FileDiff.

    Peace,
    Scott


  164. With Glassfish 3.1 (Jackson 1.7.x or higher) findDeserializer in FormatAnnotationIntrospector will error. Change the method signature to:
    public Object findDeserializer(Annotated a, BeanProperty property)


  165. Thanks Keith —

    Actually, the error when not using ResponseBody is occurring in Android GSON, not the server.

    Peace,
    Scott


  166. Hate to be a "me too" broken complainer, but I'm seeing this with a fresh svn checkout and current STS version.
    Note, I also needed to add the version to the pom for the maven-compiler-plugin to get mvn to stop complaining:

    org.apache.maven.plugins
    maven-compiler-plugin
    2.3.2

    INFO : org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping – Mapped URL path [/account/] onto handler 'accountController'
    INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory – Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3fb133bc: defining beans [accountController,jacksonConversionServiceConfigurer,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.validation.beanvalidation.LocalValidatorFactoryBean#0,org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.config.viewControllerHandlerAdapter,org.springframework.web.servlet.config.viewControllerHandlerMapping,org.springframework.web.servlet.handler.MappedInterceptor#1,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0,org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0,localeResolver,messageSource,org.springframework.web.servlet.view.InternalResourceViewResolver#0]; root of factory hierarchy
    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.AnnotationMethodHandlerAdapter#0': Initialization of bean failed; nested exception is java.lang.NoSuchMethodError: org.codehaus.jackson.map.SerializationConfig.(Lorg/codehaus/jackson/map/ClassIntrospector;Lorg/codehaus/jackson/map/AnnotationIntrospector;Lorg/codehaus/jackson/map/introspect/VisibilityChecker;Lorg/codehaus/jackson/map/jsontype/SubtypeResolver;)V
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:442)
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:458)
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:339)
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:306)
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
    at javax.servlet.GenericServlet.init(GenericServlet.java:160)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1190)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1103)
    at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:813)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:135)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.traceNextValve(HttpRequestOperationCollectionValve.java:112)
    at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:94)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)
    Caused by: java.lang.NoSuchMethodError: org.codehaus.jackson.map.SerializationConfig.(Lorg/codehaus/jackson/map/ClassIntrospector;Lorg/codehaus/jackson/map/AnnotationIntrospector;Lorg/codehaus/jackson/map/introspect/VisibilityChecker;Lorg/codehaus/jackson/map/jsontype/SubtypeResolver;)V
    at org.springframework.samples.mvc.ajax.json.ConversionServiceAwareObjectMapper.(ConversionServiceAwareObjectMapper.java:20)
    at org.springframework.samples.mvc.ajax.json.JacksonConversionServiceConfigurer.postProcessAfterInitialization(JacksonConversionServiceConfigurer.java:40)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1426)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    … 34 more


  167. Bruce, I just tried it and it worked for me. It sounds like a mismatch in the version of Jackson JSON.


  168. Anybody can help me with the question raised in this POST

    http://forum.springsource.org/showthread.php?114350-With-the-Jackson-library-in-the-application-classpath-MVC-still-uses-flexjson&p=380058#post380058

    ?


  169. Regarding the jackson version, the pom specs jackson 1.6.4:

    org.codehaus.jackson
    jackson-mapper-asl
    1.6.4

    And those are the only version I find in the project:

    find . -name \*jack\*
    ./target/dependency-maven-plugin-markers/org.codehaus.jackson-jackson-core-asl-java-source-sources-1.6.4.resolved
    ./target/dependency-maven-plugin-markers/org.codehaus.jackson-jackson-mapper-asl-java-source-sources-1.6.4.resolved
    ./target/mvc-ajax-1.0.0-SNAPSHOT/WEB-INF/lib/jackson-core-asl-1.6.4.jar
    ./target/mvc-ajax-1.0.0-SNAPSHOT/WEB-INF/lib/jackson-mapper-asl-1.6.4.jar

    Any other suggestions to check?


  170. Day three and still scratching head. When *not* using @ResponseBody on a controller method, where is the response written inside the HttpServletResponse object? Right now, the only way Gson is able to deserialize the returned JSON to Android application is if I use the @ResponseBody annotation. I am perplexed as to how a response could be returned any other way than response.getOutputStream().

    The same JSON payload is returned regardless of the annotation when using the browser as a client.


  171. Thanks a lot for your tutorial..
    but i try to make jqGrid with SpringMVC.
    You can see it here..
    http://springjquery.blogspot.com/

    it says
    Error 406 NOT_ACCEPTABLE

    HTTP ERROR 406
    Problem accessing /IsForCabSys/cityGridView.html. Reason:
    NOT_ACCEPTABLEPowered by Jetty://

    Why is it occur.?
    Please help me friend..


  172. Hi guys, I gave this demo a try and when I click "create", I got a prompt from window browser asking me to save or open a file which is type of application/json, and the content is:{"id":10}, what's going wrong? I extracted this demo from svn, and tried firefox and IE9. Any help is highly appreciated!


  173. Regarding the spring->jackson deserialization chain, you mention:

    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.

    Given that, how can one obtain a reference to the ObjectMapper to define additional customizations?

    Specifically, I'm looking for a way to define what java class type is passed in to the deserializer. I want to define whether the controller attempts to parse a base or derived class.

    I don't want to use polymorphism as I know at runtime which class a controller should expect. I'm sharing controller code between 2 apps that use different variations of the data types.

    Is this possible? – to set the class type here:
    @Valid @RequestBody ObjectType obj) {
    to ObjectType or a subclass thereof via wiring or other startup config?


  174. Hi,

    I just tried this but when click Create button, nothing happened. Nothing submitted to server.

    Anyone can help?

    many thanks


  175. please ignore my question

    After using sts, everything runs fine


  176. Hey Lace,

    open the browser debugger and check what it shows you. Also, when you said "Nothing submitted to server" you already check the DEBUG messages and you are sure that "Nothing submitted to server", don't you?


  177. I've followed this MVC AJAX sample in But I couldn't get my controller return visa @ResponseBody to my javascript caller. Here are what I did:

    In JS:
    $.getJSON("enrollment/get_info", { countryCode: "GB" }, function(myInfo) {
    alert("myInfo = " myInfo);
    });

    In Controller:
    @Controller
    @RequestMapping("/enrollment")
    public class EnrollmentController{
    @RequestMapping(value="/get_info", method=RequestMethod.GET)
    public @ResponseBody String getInfo(@RequestParam String countryCode) {
    System.out.println("countryCode = " countryCode);
    return "Your info";
    }
    }

    In servlet-context.xml:

    And I do have the following jars in my WEB-INF/lib
    jackson-core-asl-1.6.4.jar
    jackson-mapper-asl-1.6.4.jar

    I'm using springframework 3.0.6

    I can see the following in my tomcat log:
    countryCode = GB
    2011-11-06 10:24:47,601 DEBUG [DispatcherServlet] DispatcherServlet with name 'springAppServlet' processing GET request for [/myapp/spring/enrollment/get_info]
    2011-11-06 10:24:47,601 DEBUG [DefaultAnnotationHandlerMapping] Mapping [/enrollment/get_info] to HandlerExecutionChain with handler [com.mycom.myapp.spring.controller.EnrollmentContro ller@1484a8a] and 2 interceptors
    2011-11-06 10:24:47,601 DEBUG [DispatcherServlet] Last-Modified value for [/myapp/spring/enrollment/get_info] is: -1
    2011-11-06 10:24:47,603 DEBUG [HandlerMethodInvoker] Invoking request handler method: public java.lang.String com.mycom.myapp.spring.controller.EnrollmentContro ller.getInfo(java.lang.String)
    2011-11-06 10:24:47,606 DEBUG [AnnotationMethodHandlerAdapter] Written [Your info] as "application/json" using [org.springframework.http.converter.StringHttpMessa geConverter@d8326d]
    2011-11-06 10:24:47,606 DEBUG [DispatcherServlet] Null ModelAndView returned to DispatcherServlet with name 'springAppServlet': assuming HandlerAdapter completed request handling
    2011-11-06 10:24:47,607 DEBUG [DispatcherServlet] Successfully completed request

    I can see that the controller was prossing the request, but just couldn't return back to the javascript caller since its alert() never shown.

    The other interesting thing is that sometime the request couldn't even reseach the controller without changing any of code/configuration.

    What's wrong? Do I need the java classes in org.springframework.samples.mvc.ajax.json from this sample for my controller? Currently I'm not using them for my controller.

    Appreciate your help!
    Jason


  178. Regarding my previous entry, I found that when I turned on Firebug in my Firefox browser, I can actually see the returnning string "Your info" in Firebug console. It's good news to me. At least the controller returned the string back to my browser. Firebug pointed to the line 126 of jquery-1.4.min.js (from the sample repository). Still need to figure out why jquery is not reaching my callback.

    I actually prefer a synchrounous in my app. Wonder if there is a way to do that. Currently, I'm using
    $.getJSON("enrollment/get_info", { countryCode: "GB" }, function(myInfo) {
    // something to do with myInfo
    });

    Jason

19 trackbacks

Leave a Reply