无法将 Ajax 映射到 Spring MVC 控制器

Trouble mapping Ajax to Spring MVC Controller

简短版本:

我需要知道在这里放什么:

$(document).ready(function() {
    $('#orgSearch').autocomplete({
        // what do I put for "source" ???
        source : '/getOrgsViaAjax'
    });
});

这里:

// What do I put for the arguments in `@RequestMapping` ?
// What do I put as the arguments for the method?
// What do I name the method?

@RequestMapping(value = "/getOrgsViaAjax", method = RequestMethod.GET)
public @ResponseBody String getOrgsViaAjax(@RequestParam("term") String query) {
    ...
}

让我的 Ajax 自动完成与 Spring MVC 控制器一起工作。


长版:

我正在尝试将 Ajax 自动完成 source 标记映射到我的 Spring MVC 控制器,但我无法使任何东西正常工作。

我尝试过的:

我有一个类似于此的 Spring MVC 控制器:

@Controller
@RequestMapping("/PersonAffiliations.html")
public class PersonAffiliationsController extends BaseController {

    @RequestMapping(value = "/getOrgsViaAjax", method = RequestMethod.GET)
    public @ResponseBody String getOrgsViaAjax(@RequestParam("term") String query) {

        System.out.println("getOrgsViaAjax -- Here");
        return "{\"Test OrgOne\":\"42695847\",\"Test OrgTwo\":\"84920493\",\"Test OrgThree\":\"22222222\",\"Test OrgFour\":\"42226589\"}";
    }

    // The controller methods below all work
    // I included them here just incase they're causing my issues
    @RequestMapping(method = RequestMethod.GET)
    public String getPerson(Map model, HttpServletRequest request) {
        ...
        return "PersonAffiliations";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String processForm(@Valid PersonForm objPersonForm, BindingResult result, Map model, HttpServletRequest request) {
        ...
        return "PersonAffiliations";            
    }

    @RequestMapping(params = "update", method = RequestMethod.POST)
    public String processNameForm(@Valid PersonAffiliationForm objPersonAffiliationForm, BindingResult result, Map model, HttpServletRequest request) {
        ...
        return "PersonAffiliations";            
    }

}

还有一个类似于此的 .jsp 页面:

<!DOCTYPE HTML><%@page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
<html>
    <script src="resources/js/jquery-1.12.4.js"></script>
    <script src="resources/js/jquery-ui.js"></script>
    <script type="text/javascript">
        $(document).ready(function() {

            console.log("here");
            console.log('${pageContext.request.contextPath}');

            $('#orgSearch').autocomplete({
                source : '${pageContext.request.contextPath}/PersonAffiliations/getOrgsViaAjax'
            });
        });
    </script>
    <head>
        <title>Person Affiliation Editor</title>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    </head>
    <body>
        <form:form name="AddPersonAffiliationForm" action="PersonAffiliations.html" modelAttribute="BlankPersonAffiliationForm">
            ...
            <form:input id="orgDeptId" path="deptId" />
            <form autocomplete="off" id="searchOrgForm">
                <div class="autocomplete">
                    <input id="orgSearch" type="text" style="width:500px" name="orgSearch" placeholder="Organization" />
                </div>
            </form>


        </form:form>
    </body>
</html>

但是 getOrgsViaAjax 控制器方法永远不会执行。 Firebug 说 404

在 .jsp 方面我已经尝试过:

source : '${pageContext.request.contextPath}/PersonAffiliations/getOrgsViaAjax'

source : '${pageContext.request.contextPath}/PersonAffiliations//getOrgsViaAjax'

source : '/PersonAffiliations/getOrgsViaAjax'

source : '/getOrgsViaAjax'

source : '${pageContext.request.contextPath}/PersonAffiliations.html/getOrgsViaAjax'

source : '/PersonAffiliations.html/getOrgsViaAjax'

在控制器方面我已经尝试过:

@RequestMapping(value = "/getOrgsViaAjax", method = RequestMethod.GET)
public @ResponseBody String getOrgsViaAjax(@RequestParam("term") String query) {


@RequestMapping(value = "/getOrgsViaAjax")
public @ResponseBody String getOrgsViaAjax(@RequestParam("term") String query) {


@RequestMapping(value = "/getOrgsViaAjax")
public @ResponseBody String getOrgsViaAjax() {

但我似乎什么都做不好。

Firebug 清楚地表明,当我在输入字段中输入任何内容(自动完成)时,它正在发送一个请求,但它总是返回 404:

很明显自动完成功能正在触发一个请求,但它没有映射到 MVC 控制器

如何让 source 与 Spring MVC 中的 RequestMapping 匹配?


编辑:

我不确定这是否相关,但我应该注意到有一个 mvc-dispacher-servlet.xml 看起来像这样:

<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/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">


    <bean name="/SearchPerson.html" 
        class="org.personhub.controller.SearchPersonController" />      

    <bean name="/authenticate.html" 
        class="org.personhub.controller.LogInController" />

    <bean name="/PersonSummary.html"
            class="org.personhub.controller.PersonSummaryController" />

    <bean name="/ManagePerson.html" 
        class="org.personhub.controller.ManagePersonController" />

    <bean name="/PersonNames.html" 
        class="org.personhub.controller.PersonNamesController" />

    <bean name="/PartyAddresses.html" 
        class="org.personhub.controller.PartyAddressesController" />

    <bean name="/PartyIdentifiers.html" 
        class="org.personhub.controller.PartyIdentifiersController" />

    <bean name="/PersonAffiliations.html" 
        class="org.personhub.controller.PersonAffiliationsController" />

    <bean name="/PartyContactMethods.html" 
        class="org.personhub.controller.PartyContactMethodsController" />

    <bean name = "Logout.html"
         class= "org.personhub.controller.LogOutController"> </bean>    

      <!--  <mvc:resources mapping="/resources/**" location="/resources/" /> -->
     <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass">
            <value>
                org.springframework.web.servlet.view.tiles3.TilesView
            </value>
        </property>
    </bean>

    <bean id="tilesConfigurer"  
        class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">  
        <property name="definitions">  
            <list>  
                <value>/WEB-INF/tiles.xml</value>  
            </list>  
        </property>  
    </bean>  


</beans>

编辑:

根据要求,这里是 web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>PersonHubWeb</display-name>
    <welcome-file-list>
        <welcome-file>LogIn.jsp</welcome-file>              
    </welcome-file-list>

    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>


    <servlet>
        <servlet-name>PersonHubStart</servlet-name>
        <servlet-class>org.personhub.utils.StartUpServlet</servlet-class>
        <load-on-startup>3</load-on-startup>
    </servlet>

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

</web-app>

为了以防万一,这里还有 tiles.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
  "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" 
  "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
    <definition name="base.definition"
        template="/WEB-INF/pages/BaseLayout.jsp">
        <put-attribute name="title" value="Person Hub UI" />
        <put-attribute name="header" value="/WEB-INF/pages/Baseheader.jsp" />
        <put-attribute name="menu" value="/WEB-INF/pages/BaseMenu.jsp" />
        <put-attribute name="feedback" value="/WEB-INF/pages/BaseFeedback.jsp" />
        <put-attribute name="body" value="" />
        <put-attribute name="footer" value="/WEB-INF/pages/Basefooter.jsp" />
    </definition>


    <definition name="Search" template="/WEB-INF/pages/SearchLayout.jsp">
        <put-attribute name="title" value="Person Hub UI" />
        <put-attribute name="header" value="/WEB-INF/pages/SearchHeader.jsp" />     
        <put-attribute name="body" value="" />
        <put-attribute name="footer" value="/WEB-INF/pages/Basefooter.jsp" />
    </definition>   

    <definition name="PersonSearch" extends="Search">               
        <put-attribute name="body" value="/WEB-INF/pages/SearchPerson.jsp" />
    </definition>

    <definition name="PersonSummary" extends="base.definition">         
        <put-attribute name="body" value="/WEB-INF/pages/PersonSummary.jsp" />
    </definition>

    <definition name="ManagePerson" extends="base.definition">      
        <put-attribute name="body" value="/WEB-INF/pages/ManagePerson.jsp" />
    </definition>

    <definition name="PersonNames" extends="base.definition">       
        <put-attribute name="body" value="/WEB-INF/pages/PersonNames.jsp" />
    </definition>

    <definition name="PersonAffiliations" extends="base.definition">        
        <put-attribute name="body" value="/WEB-INF/pages/PersonAffiliations.jsp" />
    </definition>

    <definition name="PartyContactMethods" extends="base.definition">       
        <put-attribute name="body" value="/WEB-INF/pages/PartyContactMethods.jsp" />
    </definition>

    <definition name="PartyAddresses" extends="base.definition">

        <put-attribute name="body" value="/WEB-INF/pages/PartyAddresses.jsp" />
    </definition>

    <definition name="PartyIdentifiers" extends="base.definition">

        <put-attribute name="body" value="/WEB-INF/pages/PartyIdentifiers.jsp" />
    </definition>

</tiles-definitions>

将映射更改为 @RequestMapping("/PersonAffiliations")

您当前请求 /PersonAffiliations/getOrgsViaAjax 而不是 /PersonAffiliations.html/getOrgsViaAjax

仔细查看您提供的设置,您的应用似乎是以一种方式设置的 (web mvc),而您正试图以另一种方式使用它(rest web 服务)。

您只需做一些更改即可使您的应用程序 restful。

创建一个用 @RestController

注释的新控制器
@RestController
@RequestMapping("/personAffiliations")
public class PersonAffiliationsRestController {
   @RequestMapping(value = "/getOrgsViaAjax", method = RequestMethod.GET)
   public @ResponseBody String getOrgsViaAjax(@RequestParam("term") String query) {
     return "{\"Test OrgOne\":\"42695847\",\"Test OrgTwo\":\"84920493\",\"Test OrgThree\":\"22222222\",\"Test OrgFour\":\"42226589\"}";
   }
}

mvc-dispatcher-servlet.xml

中注册控制器
<bean name="/personAffiliations" class="org.personhub.controller.PersonAffiliationsRestController" />

web.xml

中的其余 Web 服务注册一个新的 url 映射
<servlet-mapping>
    <servlet-name>mvc-dispatcher</servlet-name>     
    <url-pattern>*.html</url-pattern>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>  

更改来源以使用

'${pageContext.request.contextPath}/rest/personAffiliations/getOrgsViaAjax'

您使用“*.html”注册一个 servlet,这样您的 servlet 调度程序就只有 *.html 后缀请求。这就是为什么您的其他映射方法效果很好的原因。因为你有 class 级别映射 @RequestMapping("/PersonAffiliations.html") 并且它以 .html 后缀结尾。

但是当您使用 @RequestMapping(value = "/getOrgsViaAjax") 时,您的 url 会变成 PersonAffiliations.html/getOrgsViaAjax。这不会以 *.html 模式结束。所以出现404错误。

可能的解决方案

您添加 .html 后缀 spring 和自动完成 url 如下:

source : '${pageContext.request.contextPath}/PersonAffiliations.html/getOrgsViaAjax.html'

@RequestMapping(value = "/getOrgsViaAjax.html")
public @ResponseBody String getOrgsViaAjax(@RequestParam("term") String query) {
    ...
}