Ajax不向Spring Controller发送数据

时间:2015-12-25 00:55:46

标签: jsp spring-mvc

我是Ajax的新手,所以请耐心等待。我有一个jsp页面,它应该以数组形式将所选日期以及int id和string类型发送到控制器。我正在使用Keith Wood Datepicker。但每当我试图发送数据时,它都会给我错误。控制台日志错误是:

        org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolverlogException
          WARNING: Handler execution resulted in exception: Required int parameter 'id' is not present

以下是我的jsp代码:

$(function() {
    $('#first').datepick({multiSelect: 99, showTrigger: '#calImg'});
           $("#getDates").click(function () {

             var dates = $('#first').datepick('getDate');

            //Create a HTML Table element.
             var table = $("<table />");

            //Add the data rows.
            for (var i = 0; i < dates.length; i++) {
                row = $(table[0].insertRow(-1));
                    var cell = $("<td />");
                    cell.html($.datepick.formatDate('DD, MM d,  yyyy',dates[i]));
                    row.append(cell);

            }

            var dvTable = $("#getSelect");
            dvTable.html("");
            dvTable.append(table);
        });
     $('#clearDates').click(function(){    

          $('#first').datepick('clear');
          $('#getSelect').empty();

          });


        $('#second').datepick({ 
            rangeSelect: true, monthsToShow: [1, 2]}); 
        var dateRange = [];
        $("#getRange").click(function () {

             var dates = $('#second').datepick('getDate');
            for(var i=0; i<dates.length; i++){
                dateRange.push(dates[i]);
            }
            //Create a HTML Table element.
            var table = $("<table />");

            //Add the data rows.
            for (var i = 0; i < dateRange.length-1; i++) {
                row = $(table[0].insertRow(-1));
                    var cell = $("<td />");
                    cell.html($.datepick.formatDate('DD, MM d,     yyyy',dateRange[i])+" <b> To </b>" + $.datepick.formatDate('DD, MM d,     yyyy',dateRange[i+1]) + "<br />");
                    i++;
                row.append(cell);

            }

            var dvTable = $("#getSelectRange");
            dvTable.html("");
            dvTable.append(table);
        });
     $('#clearRangeDates').click(function(){    

          $('#second').datepick('clear');
          $('#getSelectRange').empty();
          dateRange = [];
          });
     $('#start').datepick({showTrigger: '#calImg'});
     $('#end').datepick({showTrigger: '#calImg'});
     $('#submitDates').click(function(){
         var dateRandom = $('#first').datepick('getDate');
         var id = 1;
         var type = "random";
         $.ajax({
               url: "${pageContext.request.contextPath}/calendarData",
                dataType: "json",
                traditional: true,
                data: $.param({ "id": id, "dates": dateRandom, "type":     type}, true),
                type: "POST",
                contentType : 'application/json; charset=utf-8',
                success: function(data)     {$('#first').datepick({multiSelect: 99, showTrigger: '#calImg'});},
                error : function(e) {
                    alert('Error: ' + e);
                 }
            });
     });

});


</script>
</head>
<body>

<div class="container-fluid">
 <div class="page-header">
  <h2>Choose your dates:</h2>
 </div>     
  <div class="row">
   <h4>Choose By Day:</h4>
    <div class="col-sm-6" id="first" style="background-color:lavender;">

      <img id="calImg" src="${pageContext.request.contextPath}/resources    /script/calendar-    blue.gif" alt="Popup" class="trigger"> </p> 
    </div>
    <div class="col-sm-6" id="isoDate" style="background-    color:lavenderblush;">
    <div class="table-responsive">
     <table class="table">
      <tr><td colspan="2" class="c_button"><input type="button"     value="Get Date" id="getDates" /></td></tr>
      <tr><td colspan="2"><div id="getSelect"></div></td></tr>
       <tr><td class="c_button"><input type="button" value="Clear Date"     id="clearDates" /></td>
          <td class="c_button"><input type="button" value="Submit Date"     id="submitDates" /></td></tr>
      </table> 
      </div>
     </div>
  </div>

  <br /><br />
  <div class="row">
    <h4>Choose By Range:</h4>
    <div class="col-sm-6" id="second" style="background-color:lavender;">

    </div>
    <div class="col-sm-6" id="second_iso" style="background-    color:lavenderblush;">
    <div class="table-responsive">
     <table class="table">
      <tr><td colspan="2" class="c_button"><input type="button"     value="Get Date Range" id="getRange" /></td></tr>
      <tr><td colspan="2"><div id="getSelectRange"></div></td></tr>
      <tr><td class="c_button"><input type="button" value="Clear Date"     id="clearRangeDates" /></td>
          <td class="c_button"><input type="button" value="Submit Date     Range" id="submitRangeDates" /></td></tr>
      </table> 
      </div>
    </div>
  </div>
  <br /><br />
  <div class="row">
    <div class="col-sm-12" id="third_iso" style="background-    color:lavender;">
      <h4>Recurring Event:</h4>
      <form action="" method="post">
      <div class="table-responsive">
      <table id="recur" class="table">
        <tr>
          <td><b>Start Date: </b><input id="start" type="text"     name="start" class="form-control" /><span class="pop"><img id="calImg"     src="${pageContext.request.contextPath}/resources/script/calendar-blue.gif"     alt="Popup" class="trigger" /></span></td>
          <td><b>End Date: </b><input id="end" type="text" name="end"     class="form-control" /><span class="pop"><img id="calImg"     src="${pageContext.request.contextPath}/resources/script/calendar-blue.gif"     alt="Popup" class="trigger" /></span></td>
        </tr>
        <tr><td>
           <b>Repeat Event: </b>
           <select name="repeat" class="form-control">
             <option value="Daily">Daily</option>
             <option value="Weekly">Weekly</option>
             <option value="Monthly">Monthly</option>
           </select>
        </td></tr>
        <tr><td><input type="submit" value="Submit" class="btn     btn-primary btn-md"/></td></tr>
      </table>
      </div>
      </form>
    </div>
    <!--  <div class="col-sm-6" style="background-color:lavenderblush;">
      <p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem     accusantium doloremque laudantium, totam rem aperiam, eaque     ipsa quae ab illo inventore veritatis et quasi architecto beatae     vitae dicta sunt explicabo.</p>
    </div>-->
  </div>
</div>


</body>
</html>   

我的控制器类是:

@Controller
public class ScheduleController {

    private DatesService datesService;

    public void setDatesService(DatesService datesService){
         this.datesService = datesService;
    }

    @RequestMapping("/")
    public String showHome(){
        return "home";
    }

    @RequestMapping("/calendar")
    public String showCalendar(){
        return "calendar";
    }

    @RequestMapping(value = "/calendarData", method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE, consumes =     MediaType.APPLICATION_JSON_VALUE)
    @ResponseStatus(value=HttpStatus.OK)
    @ResponseBody
    public String showCalendarData(@RequestParam("id") int id,         @RequestParam("dates[]") LocalDate[] dates, 
    @RequestParam("type") String type){

        for(int i=0; i < dates.length; i++){
            datesService.create_random(dates[i], type, id);
        }
        return "calendar";
    }

}

这是pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.neiu.scheduler</groupId>
  <artifactId>scheduler</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.4</version>
        <configuration>
          <warSourceDirectory>WebContent</warSourceDirectory>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.2.2.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.38</version>
    </dependency>
    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
        <version>2.9.1</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.13</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>1.9.13</version>
    </dependency>
  </dependencies>
</project>

2 个答案:

答案 0 :(得分:0)

ajax调用中的id参数正在HTTP POST的正文中传递。但是您的控制器希望id参数作为URL中的请求参数出现,例如http://localhost:8080/myApp?id=123

因此错误消息准确无误,没有名为id的请求参数。相反,您已经在请求正文中传递id

您可以使用GET请求将您的值作为URL的一部分传递(更新您的AJAX调用)。或者使用@RequestBody获取请求正文并以另一种方式验证其内容(更新Java)。

修改 @ user5715620,你的类路径上有杰克逊吗?如果使用Maven:

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>
如果它包含在类路径中并使用它来序列化/反序列化请求/响应,那么Spring应该把它拿起来。

编辑2: @ user5715620,您是否整理了控制器方法?在OP中,您有@ResponseBody注释,这意味着该方法的返回值将作为响应主体发送,您还可以使用方法设置来生成JSON。但是,您将返回JSP的名称,即“calendar”。字符串'calendar'不是有效的JSON。

您更新了showCalendarData的参数是什么?也许更新OP以反映您当前的状态。我希望它像showCalendarData(@ResponseBody String jsonString)。首先只记录该字符串。一旦你知道你正在接收数据,你就可以使用Jackson来解析jsonString并提取你需要的值。 (您可以将jsonString的类型设置为自定义类型,并让杰克逊序列化它,但在您的情况下,我稍后会添加该改进。)

您是如何部署应用程序的?确保将所有依赖项部署到容器中。如果使用Eclipse,则可以在项目属性中检查部署程序集。

尝试了解您期望发生的事情并自己做一些调查。不要盲目地应用我的建议,并回到下一期。

答案 1 :(得分:0)

我将ajax代码更改为:

$(document).ready(function(){
     $('#submitDates').click(function(){
         var dateRandom = $('#first').datepick('getDate');
         var dates = JSON.stringify(dateRandom);
         // var id = 1;
        //var type = "random";
         alert("hi");
         $.ajax({
               url: "${pageContext.request.contextPath}/calendarData?id=1&type='random'",
               dataType: "json",                
                data : dates,
                type: "POST",
                contentType : 'application/json; charset=utf-8',
                success: function(response) {
                    alert("Success: " + response);
                    //$('#first').datepick({multiSelect: 99, showTrigger: '#calImg'});

                    },
                error : function(e) {
                    alert('Error: ' + 'Not working');
                 }
            });
         event.preventDefault();
     });

我的控制器是:

@RequestMapping(value = "/calendarData", method = RequestMethod.POST)

    @ResponseStatus(value=HttpStatus.OK)

    public @ResponseBody String showCalendarData(@RequestParam(value = "id") String id,
                                     @RequestBody(required = false) String[] dates, 
                                     @RequestParam(value = "type") String type){
......
}