Spring MVC Controller没有返回正确的视图

时间:2013-10-27 16:53:52

标签: java ajax spring spring-mvc

当用户请求官员/用户页面时,如果 cookie 中有userName我想向用户显示官员/用户详细信息,我有一个存储在cookie中的userName(jeff)。我使用 ajax请求来获取详细信息。

ajax 请求转到控制器并获取数据但是当我将视图返回给用户时对象< / strong>是 null 。因此,没有数据绑定到该对象。然后视图为空。我想向用户返回具有人员/用户数据的对象。

Under是我的代码和firebug中请求的屏幕截图。请告诉我我哪里出错了。

来自视图的Ajax请求

<script type="text/javascript"> 
  function getCookie(name) {
    var regexp = new RegExp("(?:^" + name + "|;\s*"+ name + ")=(.*?)(?:;|$)", "g");
    var result = regexp.exec(document.cookie);
    return (result === null) ? null : result[1];
  }

  var userName = getCookie("userName");
  console.log(getCookie("userName"));

  if(userName != null & userName != 'Guest'){
     alert('Redirecting to get officer');

    $.ajax({
            type:'POST',
        url:'getOfficer/'+ userName + '.htm',
        contentType: "application/json",
        async: false,
        cache: false, 
        data:userName                   
        });     
    }

控制器

 @RequestMapping(value="getOfficer/{userName}.htm", method = RequestMethod.POST)
 public ModelAndView getOfficer(@PathVariable String userName,@ModelAttribute Officers officer, 
BindingResult result,ModelMap m,Model model,HttpServletRequest request,  
HttpServletResponse response) {

 logger.info("In get Officer by userName");
 try{
    model.addAttribute("officers",officerManager.getOfficer(userName));
 }catch(Exception e){
    logger.error("Exception In Officer Controller getOfficer/{userName} " + e.getMessage());
    request.setAttribute("error",e.getMessage());
 }

 logger.info("about to return new officer_registration");
 logger.info("Officer Badge Number is "+officer.getBadgeNo());
 logger.info("Officer First and last name is "+officer.getfName() + " - " + officer.getlName());

 return new ModelAndView("officer_registration");    

}

使用Logger.info消息记录错误

我注意到这条线表明模型为空。为什么呢?

758511 [http-bio-8084-exec-9] DEBUG org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod  - Method [postOfficer] returned [ModelAndView: reference to view with name 'officer_registration'; model is null


758470 [http-bio-8084-exec-9] INFO  com.crimetrack.web.OfficerController  - In get Officer by userName
758470 [http-bio-8084-exec-9] INFO  com.crimetrack.jdbc.JdbcOfficersDAO  - Getting Officer in getOfficer(String userName)
758506 [http-bio-8084-exec-9] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing prepared SQL query
758506 [http-bio-8084-exec-9] DEBUG org.springframework.jdbc.core.JdbcTemplate  - Executing prepared SQL statement [SELECT * FROM crimetrack.tblofficers WHERE userName = ?]
758506 [http-bio-8084-exec-9] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Fetching JDBC Connection from DataSource
758508 [http-bio-8084-exec-9] DEBUG org.springframework.jdbc.core.StatementCreatorUtils  - Setting SQL statement parameter value: column index 1, parameter value [jeff], value class [java.lang.String], SQL type unknown
758510 [http-bio-8084-exec-9] DEBUG org.springframework.jdbc.datasource.DataSourceUtils  - Returning JDBC Connection to DataSource
758511 [http-bio-8084-exec-9] INFO  com.crimetrack.web.OfficerController  - about to return new officer_registration
758511 [http-bio-8084-exec-9] INFO  com.crimetrack.web.OfficerController  - Officer Badge Number is null
758511 [http-bio-8084-exec-9] INFO  com.crimetrack.web.OfficerController  - Officer First and last name is null - null
758511 [http-bio-8084-exec-9] DEBUG org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod  - Method [postOfficer] returned [ModelAndView: reference to view with name 'officer_registration'; model is null]
758511 [http-bio-8084-exec-9] DEBUG org.springframework.web.method.support.InvocableHandlerMethod  - Invoking [initBinder] method with arguments [org.springframework.web.servlet.mvc.method.annotation.ExtendedServletRequestDataBinder@b836456]
758512 [http-bio-8084-exec-9] DEBUG org.springframework.web.method.support.InvocableHandlerMethod  - Method [initBinder] returned [null]
758512 [http-bio-8084-exec-9] DEBUG org.springframework.web.servlet.DispatcherServlet  - Rendering view [org.springframework.web.servlet.view.JstlView: name 'officer_registration'; URL [/WEB-INF/jsp/officer_registration.jsp]] in DispatcherServlet with name 'crimetrack'
758512 [http-bio-8084-exec-9] DEBUG org.springframework.web.servlet.view.JstlView  - Rendering view with name 'officer_registration' with model {officers=com.crimetrack.business.Officers@5f305001, org.springframework.validation.BindingResult.officers=org.springframework.validation.BeanPropertyBindingResult: 0 errors} and static attributes {}
758512 [http-bio-8084-exec-9] DEBUG org.springframework.web.servlet.view.JstlView  - Added model object 'officers' of type [com.crimetrack.business.Officers] to request in view with name 'officer_registration'
758512 [http-bio-8084-exec-9] DEBUG org.springframework.web.servlet.view.JstlView  - Added model object 'userName' of type [java.lang.String] to request in view with name 'officer_registration'
758512 [http-bio-8084-exec-9] DEBUG org.springframework.web.servlet.view.JstlView  - Added model object 'org.springframework.validation.BindingResult.officers' of type [org.springframework.validation.BeanPropertyBindingResult] to request in view with name 'officer_registration'
758513 [http-bio-8084-exec-9] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - No bean named 'requestDataValueProcessor' found in org.springframework.beans.factory.support.DefaultListableBeanFactory@726b5b3c: defining beans [citizenManager,validateCitizenManager,citizenDao,citizenTypeManager,citizenTypeDao,markerManager,markerDao,crimeHotSpotManager,crimeHotSpotDao,crimeManager,crimeRegistrationValidation,crimeDao,colorManager,colorDao,monitoringTypeManager,monitoringTypeDao,monitoringManager,monitoringDao,ethnicityManager,ethnicityDao,crimeLevelManager,crimeLevelDao,crimeTypeManager,crimeTypeDao,statusManager,statusDao,crimeCategoryManager,crimeCategoryDao,maritalStatusManager,maritalStatusDao,occupationManager,occupationDao,officerManager,countryManager,countryDao,authenticationManager,loginDao,divisionManager,divisionDao,positionManager,positionDao,genderManager,genderDao,officerRegistrationValidation,validateUserManager,officerDao,dataSource,propertyConfigurer,transactionManager]; root of factory hierarchy
758513 [http-bio-8084-exec-9] DEBUG org.springframework.web.servlet.view.JstlView  - Forwarding to resource [/WEB-INF/jsp/officer_registration.jsp] in InternalResourceView 'officer_registration'
758514 [http-bio-8084-exec-9] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory  - No bean named 'requestDataValueProcessor' found in org.springframework.beans.factory.support.DefaultListableBeanFactory@726b5b3c: defining beans [citizenManager,validateCitizenManager,citizenDao,citizenTypeManager,citizenTypeDao,markerManager,markerDao,crimeHotSpotManager,crimeHotSpotDao,crimeManager,crimeRegistrationValidation,crimeDao,colorManager,colorDao,monitoringTypeManager,monitoringTypeDao,monitoringManager,monitoringDao,ethnicityManager,ethnicityDao,crimeLevelManager,crimeLevelDao,crimeTypeManager,crimeTypeDao,statusManager,statusDao,crimeCategoryManager,crimeCategoryDao,maritalStatusManager,maritalStatusDao,occupationManager,occupationDao,officerManager,countryManager,countryDao,authenticationManager,loginDao,divisionManager,divisionDao,positionManager,positionDao,genderManager,genderDao,officerRegistrationValidation,validateUserManager,officerDao,dataSource,propertyConfigurer,transactionManager]; root of factory hierarchy
758528 [http-bio-8084-exec-9] DEBUG org.springframework.web.servlet.DispatcherServlet  - Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@51dd475f
758528 [http-bio-8084-exec-9] DEBUG org.springframework.web.servlet.DispatcherServlet  - Successfully completed request

屏幕截图

userName为杰夫

这是来自firebug,它显示POST jeff.htm正在返回数据。我认为返回的视图不正确。

enter image description here

Officer_Registration.jsp

</head>
<body>
  <form:form id="officerRegistration" name="officerRegistration" method="post" modelAttribute="officers" action="officer_registration.htm">
  <ol>
  <li>
    <label>Badge No</label>
    <form:input path="badgeNo" id="badgeNo" title="Enter a Valid Badge Number"
      readonly="${badgeNoStatus}" class="formData" />
    <form:errors path="badgeNo" class="errors" />
    <label id="badgeNoErr"></label>
  </li>
  <li>
    <form:label for="userName" path="userName">User Name</form:label>
    <form:input path="userName" id="userName" title="Choose A Unique UserName"
      readonly="${userNameStatus}" class="formData" />
    <form:errors path="userName" class="errors" />
    <label id="userNameErr"></label>
  </li>
  <li>
    <label>Password</label>
    <form:password path="password" id="password" class="formData" />
    <form:errors path="password" class="errors" />
  </li>
  <li>
    <label>Re-Enter Password</label>
    <form:password path="password2" id="password2"
      class="formData" />
    <form:errors path="password2" class="errors" />
  </li>
  <li>
    <label>e-Mail Address</label>
    <form:input path="emailAdd" id="emailAdd" title="Enter eMail Address"
      class="formData" />
    <form:errors path="emailAdd" class="errors" />
  </li>
  <li>
    <label>First Name</label>
    <form:input path="fName" id="fName" title="Your First Name"
      class="formData" />
    <form:errors path="fName" class="errors" />
  </li>
  <li>
    <label>Last Name</label>
    <form:input path="lName" id="lName" title="Your Last Name"
      class="formData" />
    <form:errors path="lName" class="errors" />
  </li>
  <li>

5 个答案:

答案 0 :(得分:1)

而不是:

public ModelAndView getOfficer(...){...}

这样做:

public String getOfficer(...) {
    ...
    return "officer_registration";
}

Spring会将返回的String解释为视图名称,并使用您在方法中构建的模型。

答案 1 :(得分:1)

编辑:似乎这种做法无济于事。查看下一个提示

您返回新的清晰ModelAndView。

请改为尝试:

ModelAndView m = new ModelAndView("officer_registration");
m.addAllObjects(model.asMap());
return m;

编辑:这可以提供帮助

但是,如果您只想请求人员数据,那么最好创建另一种方法:

@RequestMapping(value="getOfficer/{userName}.ajax", method = RequestMethod.POST)
public @ResponseBody Officers getOfficerInfo(@PathVariable String userName) {
    return officerManager.getOfficer(userName);
}

别忘了添加jackson依赖项(http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-jaxrs)。

在第一种情况下,您将获得纯文本,该文本将是您的“officer_registration”页面的html(它看起来像“......”。所以从这样的文本中解析官员数据是不合理的

在第二种情况下,您将以json格式获取人员对象。因此,从中提取数据非常容易。

答案 2 :(得分:1)

查看问题中的最后一个图像,我可以看到您正在使用jQuery,看起来您正在收到包含HTML的回复。我假设你使用jQuery来发出ajax请求(例如使用$.ajax$.get)。假设你正在使用jQuery's ajax function。你的js代码看起来像是:

function getOfficerInfo(officerUserName) {
    var officerUrl = "/crimeTrack/getOffice/" + officerUserName + ".htm"
    $.ajax({
        url: officerUrl,
        type: "GET"
    });
}

这将向服务器发送一个GET请求,该请求将返回您在图像中查看的响应中显示的html。但是,此代码不处理响应。为了做到这一点,你需要在你传递给$.ajax函数的javascript对象中添加一个成功字段(或者你可以使用$.ajax函数返回一个承诺的事实,但让我们坚持下去基础知识:))。

function getOfficerInfo(officerUserName) {
    var officerUrl = "/crimeTrack/getOffice/" + officerUserName + ".htm"
    $.ajax({
        url: officerUrl,
        type: "GET",
        success: function(data) {
            $("#form-container").html(data);
        }
    });
}

当ajax请求成功时,将调用success函数,data变量将保存响应中的数据。在这里,我假设您在页面上有一个ID为form-container的元素,其内容可以替换为您的html响应。

请注意,此处没有错误处理,因此您还应添加error函数来处理超时,服务器端错误等。

最后。我建议您将数据作为JSON传输,只需更新现有表单中的值。 Spring非常支持使用@ResponseBody注释返回JSON。

答案 3 :(得分:1)

这一行

758511 [http-bio-8084-exec-9] DEBUG org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod  - Method [postOfficer] returned [ModelAndView: reference to view with name 'officer_registration'; model is null

打印出返回的model中的ModelAndView字段为null。此日志语句来自InvocableHandlerMethod#invokeForRequest,看起来像这样

if (logger.isTraceEnabled()) {
    logger.trace("Method [" + this.getMethod().getName() + "] returned [" + returnValue + "]");
}

您的@Controller处理程序方法会创建并返回一个新的ModelAndView对象

return new ModelAndView("officer_registration");    

接受ModelAndView的{​​{1}}构造函数未初始化其String字段。因此它仍然是model请不要惊慌。您的处理程序方法声明的参数nullModelMap都将传递类型Model的相同参数,该参数由一个BindingAwareModelMapHandlerMethodArgumentResolver参数的具体实现类为ModelMethodProcessorModelMapMethodProcessor。这两个都解决了为每个请求生成的ModelMap的目标参数。他们都会给出相同的实例。你宣布两者都是多余的。

即使返回的ModelAndViewContainer中的model字段为ModelAndView,在请求处理的下方,它也将与作为参数传递的null同步因此将包含您使用

设置的属性
BindingAwareModelMap

或错误属性,取决于。

您必须向我们展示您的model.addAttribute("officers",officerManager.getOfficer(userName)); 视图,并告诉我们您希望在ajax处理程序中看到的内容以获取更多详细信息。 请注意,ajax处理程序将收到从您的视图生成的响应。如果这是officer_registration,则ajax将看到一些HTML。这就是你想要的吗?

答案 4 :(得分:0)

感谢大家对问题的所有答案,但是你们都正确地确定了新的ModelAndView确实返回了一个新的Object。我观察到的是,在提出请求时,网址没有改变,它仍然是

http://localhost:8084/crimeTrack/officer_registration.htm

因为这是不正确的观点。

我决定在我的页面上添加一个按钮,以允许用户查看个人资料详细信息:

<button id= "view" class="btn" value ="save"   onclick= "submitPage('${pageContext.request.contextPath}/getOfficer/<%=request.getSession().getAttribute("userName")%>.htm');" type="button" ${viewbtn}>View Profile</button>

现在我所做的就是删除ajax请求并包含按钮,我按原样保留了控制器代码。当请求发出时,表单返回数据并且URL读取

http://localhost:8084/crimeTrack/getOfficer/jeff.htm

这很完美,我是Spring MVC的初学者,所以我无法解释为什么这对ajax请求起作用,因为它们都击中了控制器并且都使用了相同的返回语句。