Announcement Announcement Module
Collapse
No announcement yet.
$.getJSON() problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • $.getJSON() problem

    I am creating a spring mvc3.0 application.... i have the jquery-1.3.2.js added to the project.... I have the following javascript function which i call on the submit button click....

    function checkUser() { var uname=$('#username').val(); var pword=$('#password').val(); alert(uname); alert(pword);

    $.getJSON("login.html",{username: uname, password: pword},
    function(message){
    alert(message);
    });
    }

    i am using spring mvc 3.0..... Following is the controller that i use...

    package com.web.controller;

    import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMap ping; import org.springframework.web.bind.annotation.RequestMet hod; import org.springframework.web.bind.annotation.RequestPar am; import org.springframework.web.bind.annotation.ResponseBo dy;

    @Controller
    public class LoginController
    {
    @RequestMapping("/login.html")
    public @ResponseBody String getLoginStatus(@RequestParam("username") String username, @RequestParam("password") String password)
    {
    System.out.println("\n\nin login controller\n\n");
    if(username=="apoorvabade" & password=="apoorva123")
    {
    return "Login successful!!!";
    }
    else
    {
    return "Login failed";
    }
    }
    }

    when i click on the submit button, the function corresponding to the /login.html action is not invoked.... i am using the DispatcherServlet to map the requests to the following....

    here is the spring-servlet.xml


    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schem...ring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <context:component-scan base-package="com.web.controller" />

    <bean id="viewResolver"
    class="org.springframework.web.servlet.view.Intern alResourceViewResolver">
    <property name="prefix">
    <value>/WEB-INF/jsp/</value>
    </property>
    <property name="suffix">
    <value>.jsp</value>
    </property>
    </bean>

    </beans>


    web.xml:


    <!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd" >

    <web-app>
    <display-name>Spring Ajax Tutorial Project</display-name>
    <servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>
    org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>*.html</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    </web-app>


    Can anybody tell me the problem please?

  • #2
    I tried the mvc-ajax example in the springsource samples... Even that is not working.... required alerts, messages are not displayed.... Do i need to add anything pther than the normal jquery.js file to unable the jquery ajax calls? PLease help... Its urgent!!!

    Comment


    • #3
      Hi,

      I think you need better understanding of Spring webmvc's mechanics. The way you configured mvc, this is what happens: your json request maps correctly to the getLoginStatus method, but at the end of that method you either return "Login successful" or "Login failed" and thus at the end of method execution your controller tries to navigate to either /WEB-INF/jsp/Login%20successful.jsp or /WEB-INF/jsp/Login%20failed.jsp and I don't think either of them exists. To make this work the way you intend to, you must use a custom view definition which is based upon org.springframework.web.servlet.view.XmlViewResolv er and transforms your Model into a json string, and configure this view resolver in your xml with a priority higher than your InternalResourceViewResolver (see the section about chaining resolver in the Spring reference).
      This, by the way, is exactly what Spring Json does, so please at least consider using that to help you out (I can see you have chosen not to use DWR, which I suggested as the simplest solution for ajax).

      Comment


      • #4
        Actually Spring MVC3.0 is internally using the JacksonJson library.... so i need not require to use any other external library... that is what i have figured out out of http://blog.springsource.com/2010/01...in-spring-3-0/.... And yes.. I understand what you are saying/... I am very new to this concept in all.. Both spring mvc and jquery...

        Comment


        • #5
          Ok, I wasn't aware of this new feature. I have checked the example on the site you have given and it works perfectly for me, did you try to deploy that as it is, without changing anything?

          As I understand , the new json integration will only work if you meet this 2 requirements:

          1) You use the <mvc:annotation-driven/> directive in your webmvc config AND
          2) Jackson is on your classpath.

          By looking at your spring-servlet.xml (please next time use the CODE tag to post code) I see not only that you are not using the <mvc:annotation-driven/>, but also that you are using old 2.5 schema and you are missing the mvc xsd at the beginning of your file.
          So basically, you are trying to use a new, advanced feature available only with latest Spring release but you are using old configuration (and maybe also old Spring, did you update to latest release?). You understand that this could never work; I suggest you install the example in the site and study it more before you try to code your own Spring - Json example.

          Comment


          • #6
            Yes.. I did try the mvc-ajax example... It doesnt give any error... But unfortunately it is not showing any behaviour as expected... eg: If the name exists while creating a new account, it gives "not available" with available list of names.. And that too when tab out of the name field.... It is giving some error if try to create a new account... I dint do any changes here...
            Rest points that you said, I will definitely look into them.... ANd will try to study the example more in details...

            Comment


            • #7
              I have a very silly doubt but may i know when you say Jackson should be in the classpath, does that mean the folder having all the jackson libraries should be in the classpth?

              Comment


              • #8
                It means the jackson jars should be in your web application classpath, either put them in your WEB-INF/lib directory or (if you want to use them with more than one application running on the same server) add it to the application server startup classpath.

                Comment


                • #9
                  Mvc-Ajax Neither BindingResult nor plain target object for bean name 'XXX' available

                  even i am having the same issue.. when i run mvc-ajax i am not getting any errors .. but when i implement same in my own project i am getting "Neither BindingResult nor plain target object for bean name 'employee' available as request attribute" ..

                  I even tried adding <bean id = "employee" class= "com.abc.basic.crud.Employee" /> to mvc-config.xml ..

                  but didnt work .i have done same config as in mvc-ajax ..

                  Any solution found for this thread ?Please post ..

                  Comment


                  • #10
                    Krishna,

                    posting your configuration and controller class would be a good starting point...

                    Comment


                    • #11
                      my issue is different form apoorvabade's issue . sorry for the wrong statement in my previous question.

                      thanks for the immediate reply .here is my controller , mvc-config.xml ,app-config.xml.employeebeans.xml and employeeList.jsp .

                      All get requests are working fine. when i added post related code, when accessing http://localhost:8080/myfirstspring3/emp i am getting the error
                      "Neither BindingResult nor plain target object for bean name 'employee' available as request attribute" Appreciate your help.

                      EmployeeController.java

                      Code:
                      /* all imports */
                      
                      @Controller
                      @RequestMapping(value="/emp")
                      public class EmployeeController {
                      	
                          private Map<Integer, Employee> accounts = new ConcurrentHashMap<Integer, Employee>();
                      	
                      	private Validator validator;
                      	
                      	@Autowired
                      	private EmployeeDao employeeDao;
                                 //setters getters for employeeDao
                      
                      	@Autowired
                      	public EmployeeController(Validator validator) {this.validator = validator;}
                      	
                      	
                      	@RequestMapping(method=RequestMethod.GET)
                      	public ModelAndView getEmployeeList(Model model) {
                      		
                      		String now = (new Date()).toString();
                      		Map<String, Object> myModel = new HashMap<String, Object>();
                              myModel.put("now", now);
                              myModel.put("employees", getEmployeeDao().getEmployees());
                      
                              return new ModelAndView("emp/employeeList", "model", myModel);
                      
                      	}
                      	
                      	@RequestMapping(value="{empid}", method=RequestMethod.GET)
                      	public @ResponseBody Employee get(@PathVariable int empid) {
                      		Employee emp = getEmployeeDao().getEmployee(empid);
                      		if (emp == null) {
                      			throw new ResourceNotFoundException(empid);
                      		}
                      		return emp;
                      	}
                      	
                      	@RequestMapping(method=RequestMethod.POST)
                      	public @ResponseBody Map<String,? extends Object> processForm(@RequestBody @ModelAttribute("employee") Employee employee, BindingResult result, Map model) {
                      		Set<ConstraintViolation<Employee>> failures = validator.validate(employee);
                      		if (!failures.isEmpty()) {
                      			//response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                      			return validationMessages(failures);
                      			//return null;
                      		} else {
                      			getEmployeeDao().updateEmployee(employee);
                      			return  Collections.singletonMap("message","success");
                      		}
                      	}
                      	
                      	
                      	private Map<String, String> validationMessages(Set<ConstraintViolation<Employee>> failures) {
                      		Map<String, String> failureMessages = new HashMap<String, String>();
                      		for (ConstraintViolation<Employee> failure : failures) {
                      			failureMessages.put(failure.getPropertyPath().toString(), failure.getMessage());
                      		}
                      		return failureMessages;
                      	}
                      
                      	
                      	
                      }

                      app-config.xml

                      <?xml version="1.0" encoding="UTF-8"?>
                      <beans xmlns="http://www.springframework.org/schema/beans"
                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                      xmlns:context="http://www.springframework.org/schema/context"
                      xsi:schemaLocation="
                      http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-3.0.xsd
                      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

                      <!-- Scans the classpath of this application for @Components to deploy as beans -->
                      <context:component-scan base-package="com.abc.basic" />

                      <!-- Application Message Bundle -->
                      <bean id="messageSource" class="org.springframework.context.support.Reloada bleResourceBundleMessageSource">
                      <property name="basename" value="/WEB-INF/messages/messages" />
                      <property name="cacheSeconds" value="0" />
                      </bean>

                      <!-- Configures Spring MVC -->
                      <import resource="mvc-config.xml" />
                      <import resource="employee-beans.xml" />

                      </beans>


                      employee-beans.xml

                      <?xml version="1.0" encoding="UTF-8"?>
                      <beans xmlns="http://www.springframework.org/schema/beans"
                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                      xmlns:context="http://www.springframework.org/schema/context"
                      xsi:schemaLocation="
                      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

                      <bean class="org.springframework.beans.factory.annotatio n.RequiredAnnotationBeanPostProcessor"/>
                      <bean id = "employeeDao" class= "com.abc.basic.crud.hardcoded.EmployeeDaoImpl" />
                      <bean id = "employee" class= "com.abc.basic.crud.Employee" />


                      </beans>


                      mvc-config.xml

                      <?xml version="1.0" encoding="UTF-8"?>
                      <beans xmlns="http://www.springframework.org/schema/beans"
                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                      xmlns:mvc="http://www.springframework.org/schema/mvc"
                      xsi:schemaLocation="
                      http://www.springframework.org/schema/beans http://www.springframework.org/schem...-beans-3.0.xsd
                      http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

                      <!-- Configures the @Controller programming model -->
                      <mvc:annotation-driven />

                      <!-- Forwards requests to the "/" resource to the "welcome" view -->
                      <mvc:view-controller path="/" view-name="welcome"/>

                      <!-- Configures Handler Interceptors -->
                      <mvc:interceptors>
                      <!-- Changes the locale when a 'locale' request parameter is sent; e.g. /?locale=de -->
                      <bean class="org.springframework.web.servlet.i18n.Locale ChangeInterceptor" />
                      </mvc:interceptors>

                      <!-- Saves a locale change using a cookie -->
                      <bean id="localeResolver" class="org.springframework.web.servlet.i18n.Cookie LocaleResolver" />

                      <!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
                      <bean class="org.springframework.web.servlet.view.Intern alResourceViewResolver">
                      <property name="prefix" value="/WEB-INF/views/"/>
                      <property name="suffix" value=".jsp"/>
                      </bean>

                      </beans>

                      Comment


                      • #12
                        Code:
                        employeeList.jsp
                        
                        <%@ include file="/WEB-INF/views/include.jsp" %>
                        <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
                        <html>
                        <head>
                        	<head>
                        		<title>Employees</title>
                        		<link rel="stylesheet" href="<c:url value="/styles/blueprint/screen.css" />" type="text/css" media="screen, projection">
                        		<link rel="stylesheet" href="<c:url value="/styles/blueprint/print.css" />" type="text/css" media="print">
                        		<!--[if lt IE 8]>
                        			<link rel="stylesheet" href="<c:url value="/styles/blueprint/ie.css" />" type="text/css" media="screen, projection">
                        		<![endif]-->
                        		<link rel="stylesheet" href="<c:url value="/styles/blueprint/print.css" />" type="text/css" media="print">
                        		<link rel="stylesheet" href="<c:url value="/styles/popup.css" />" type="text/css" media="screen, projection">
                        		<script type="text/javascript" src="<c:url value="/scripts/jquery-1.4.min.js" /> "></script>
                        		<script type="text/javascript" src="<c:url value="/scripts/json.min.js" /> "></script>
                        	</head>
                        
                        </head>
                        <body>
                            <table align=center border =1>
                            
                                <c:forEach items="${model.employees}" var="emp">
                                 <tr>
                                 <td><a href=javascript:showPopup(<c:out value="${emp.empid}"/>);><c:out value="${emp.empid}"/></a></td>
                                 <td> <c:out value="${emp.empname}"/></td>
                                 <td> <c:out value="${emp.designation}"/></td>
                                 <td> <c:out value="${emp.sal}"/></td>
                                 </tr>
                            
                              
                            </c:forEach>
                            
                            </table>
                            
                            
                            <div id="mask" style="display: none;"></div>
                        		<div id="popup" style="display: none;">
                        			<div class="span-8 last">
                        			
                        				
                        				<form:form id="employee" commandName="employee" action="emp" method="post">
                        				  	<fieldset>		
                        						<legend>Employee Details</legend>
                        						<p>
                        							<form:label	 for="empid" path="empid" cssErrorClass="error">emp Id</form:label><br/>
                        							<form:input path="empid" /><form:errors path="empid" />
                        						</p>						
                        						<p>
                        							<form:label	 for="empname" path="empname" cssErrorClass="error"> emp Name</form:label><br/>
                        							<form:input id="empname" path="empname" /><form:errors path="name" />
                        						</p>
                        						<p>	
                        							<form:label for="designation" path="designation" cssErrorClass="error">Designation</form:label><br/>
                        							<form:input path="designation" /><form:errors path="designation" />
                        						</p>
                        						<p>
                        							<form:label for="sal" path="sal" cssErrorClass="error">Salary</form:label><br/>
                        							<form:input path="sal" /><form:errors path="sal" />
                        						</p>
                        						<p>	
                        							<input id="create" type="submit" value="Create" />
                        						</p>
                        					</fieldset>
                        				</form:form>	
                        				<p align=right>
                        				
                        					<a href="#" onclick="closePopup();" >Close</a>
                        					</p>
                        			</div>			
                        		</div>		
                        </body>
                        
                        <script type="text/javascript">	
                        
                        
                        $(document).ready(function() {
                        	// check name availability on focus lost
                        	///$('#id').blur(function() {
                        		//if ($('#id').val()) {	
                        			//checkAvailability();
                        		//}
                        	//});
                        	$("#employee").submit(function() {
                        		var employee = $("#employee").serializeObject();
                        		$.postJSON("emp", employee, function(data) {
                        			$("#empname").val(data.message);
                        			
                        		});
                        		return false;				
                        	});
                        });
                        
                        function showPopup(id) {
                        	$.getJSON("emp/" + id, function(employee) {
                        		$("#empid").val(employee.empid);
                        		$("#empname").val(employee.empname);
                        		$("#designation").val(employee.designation);
                        		$("#sal").val(employee.sal);
                        	});			
                        	$('body').css('overflow','hidden');
                        	$('#popup').fadeIn('fast');
                        	$('#mask').fadeIn('fast');
                        }
                        function closePopup() {
                        	$('#popup').fadeOut('fast');
                        	$('#mask').fadeOut('fast');
                        	$('body').css('overflow','auto');
                        	
                        }
                        
                        </script>
                        </html>
                        error stack is

                        org.apache.jasper.JasperException: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'employee' available as request attribute
                        org.apache.jasper.servlet.JspServletWrapper.handle JspException(JspServletWrapper.java:491)
                        org.apache.jasper.servlet.JspServletWrapper.servic e(JspServletWrapper.java:413)
                        org.apache.jasper.servlet.JspServlet.serviceJspFil e(JspServlet.java:313)
                        org.apache.jasper.servlet.JspServlet.service(JspSe rvlet.java:260)
                        javax.servlet.http.HttpServlet.service(HttpServlet .java:717)
                        org.springframework.web.servlet.view.InternalResou rceView.renderMergedOutputModel(InternalResourceVi ew.java:238)
                        org.springframework.web.servlet.view.AbstractView. render(AbstractView.java:250)
                        org.springframework.web.servlet.DispatcherServlet. render(DispatcherServlet.java:1063)
                        org.springframework.web.servlet.DispatcherServlet. doDispatch(DispatcherServlet.java:801)
                        org.springframework.web.servlet.DispatcherServlet. doService(DispatcherServlet.java:719)
                        org.springframework.web.servlet.FrameworkServlet.p rocessRequest(FrameworkServlet.java:644)
                        org.springframework.web.servlet.FrameworkServlet.d oGet(FrameworkServlet.java:549)
                        javax.servlet.http.HttpServlet.service(HttpServlet .java:617)
                        javax.servlet.http.HttpServlet.service(HttpServlet .java:717)
                        org.tuckey.web.filters.urlrewrite.NormalRewrittenU rl.doRewrite(NormalRewrittenUrl.java:195)
                        org.tuckey.web.filters.urlrewrite.RuleChain.handle Rewrite(RuleChain.java:159)
                        org.tuckey.web.filters.urlrewrite.RuleChain.doRule s(RuleChain.java:141)
                        org.tuckey.web.filters.urlrewrite.UrlRewriter.proc essRequest(UrlRewriter.java:90)
                        org.tuckey.web.filters.urlrewrite.UrlRewriteFilter .doFilter(UrlRewriteFilter.java:417)
                        org.springframework.web.filter.CharacterEncodingFi lter.doFilterInternal(CharacterEncodingFilter.java :88)
                        org.springframework.web.filter.OncePerRequestFilte r.doFilter(OncePerRequestFilter.java:76)

                        Comment


                        • #13
                          Hi,

                          I do see something odd in your configuration, that might (or might not) be the source of your problems. This concerns the usage of @RequestBody and @ResponseBody annotations:

                          - @ResponseBody should be put before the method signature and not after the public 'public' keyword;

                          - Even with this modification, @ResponseBody will not work for your method, since the return type is Map<String, ? extends Object> and Spring has no built-in HttpMessageConverter to handle this kind of object. My guess is you have a form with strings, dates and numbers and you wish that Spring could guess the type of object in which to put form fields by itself, which is asking too much. Use Map<String, String> instead; this way Spring will use its FormHttpMessageConverter for conversion, and then you must take care of type conversion manually in your controller or delegate this work to a service;

                          - Similar problem with @RequestBody: there is no built-in HttpMessageConverter for type Employee (which is a custom class you created) so Spring does not know how to map a request, which is a string, to this object. You should create your own HttpMessageConverter or, even better, ask yourself why you need to map the request to an object of this kind (maybe you don't even need to map the request at all?);

                          - Also, you can't mix @RequestBody and @ModelAttribute for the same attribute; just map your request body to a String (if you really need to) and your @ModelAttribute to the Employee object which is your form object.

                          I suggest you also take a look at this to clear your ideas before you proceed.

                          Comment


                          • #14
                            Below is the code snippet from AccountController in mvc-ajax project which i got from Spring source blog .

                            Code:
                            	@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());
                            		}
                            	}
                            - @Responsebody: 'create' method returning a Map Map<String, ? extends Object> and is placed after public . mvc-ajax is running perfectly in eclipse .
                            I tried ur suggestion but didnt work.
                            - @Requestbody : if there is no built-in HttpMessageConverter in spring .. then how the above code is working .i searched mvc-ajax code and all files
                            and there is no custom HttpMessageConverter for 'Account' .Am i missing any configuration ?
                            -@modelAttribute : i am just trying ways to get rid of the error so added it .. i removed it ..
                            - thanks for the link

                            Comment


                            • #15
                              Hi,

                              the example you are following works because the controller maps a JSON request and

                              Spring MVC knows to map from JSON because the client set the request Content Type to application/json.
                              I focused on the controller part and didn't notice you were using JSON/ajax because I didn't even look at the jsp; now that I took a closer look, everything seems fine to me as long as you have the Jackson jars on your classpath (and you drop the @ModelAttribute).

                              I suggest you start by removing the BindingResult result and Map model from your post method (since you aren't using them in the method body, why declaring them as attributes?) and then begin to simplify your code to make it step by step closer to that of the working example. This way you may find what's wrong and hopefully be able to correct it.

                              Comment

                              Working...
                              X