【问题标题】:Send complex json object to Spring MVC controller将复杂的 json 对象发送到 Spring MVC 控制器
【发布时间】:2014-10-20 17:18:26
【问题描述】:

我正在尝试向 spring mvc 搜索引擎的 ajax 控制器发送一个复杂对象,其中包含 3 个变量:当前页面、每页项目和搜索参数。问题是控制器方法的声明并没有将 params 变量作为 Map。

因为我可以发送结构来分别收集控制器上的 3 个变量?

错误:

必需的地图参数“params”不存在

  var dataToSend = {
        'page': 1,
        'itemsPerPage': 10,
        'params': {
          'codItem': "10",
          'nameItem': "foo"
        }
      };  

      $.ajax({
        url: form.attr("action"),
        type: 'POST',
        data: JSON.stringify(dataToSend),
        dataType: 'json',
        cache: false
      }).success(function(data) {
        callback(data);
      });        




 public @ResponseBody HashMap<String, Object> search(@RequestParam(value="params") Map<String, String> params, @RequestParam(value = "page") int page, @RequestParam(value = "itemsPerPage") int itemsPerPage){
};

【问题讨论】:

    标签: java ajax json spring spring-mvc


    【解决方案1】:

    我的环境: AngularJs、SpringMVC、Gson jsonobject

    通常,如果我将复杂的 json 对象从字体端发送到后端,我将采用如下通用方式来处理它。

    第一:

    $http({
        method: 'POST',
        url: contextPath+"/voice/submitWrapupForm",
        dataType: 'json',
        data: $.param({
                  content : angular.toJson( { array:$(form).serializeArray() })
              }),
        headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }
    ).success(function (data, status) {
        console.log(data);
    });
    

    我使用angularJs提交一个格式化的json字符串,我相信使用jquery ajax也是一样的,只需要确保你发送的数据是json格式化的字符串。 https://docs.angularjs.org/api/ng/function/angular.toJson

    秒:

    @RequestMapping(value = "/submitForm", method = RequestMethod.POST,headers = "Accept=application/json")
    public @ResponseBody String submitForm(String content) {
        JsonObject j = new Gson().fromJson(content ,JsonElement.class).getAsJsonObject();
        return j.toString();
    }
    

    你可以看到json内容传递给mvc控制器,在控制器中你可以使用Gson转换成json对象。

    【讨论】:

      【解决方案2】:

      我已经解决了如下问题:

      public class SearchRequestDto {
      
        private String page;
      
        private String itemsPerPage;
      
        private MultiValueMap<String, List<String>> params;
      
        }
      
      @ResponseBody
      public HashMap<String, Object> buscador(SearchRequestDto searchRequest)
      {
      }
      

      问题在于它适用于示例的结构,如果我尝试获取表单参数,则发送给我的不是 json:

        $.ajax({
          url: form.attr("action"),
          type: 'POST',
          data: {  
            'params': form.serialize(),
            'page': start,
            'itemsPerPage': end  
          },
          dataType: 'json',
          cache: false
        }).success(function(data) {
          callback(data);
        });
      

      结果:

      itemsPerPage 5
      page 1
      params codItem=asdfasdf&namItem=asdfasdfasdf&tipItem=1000600&tipItem=1000492&public=on&private=on&provinceItem=15&munItem=262&munItem=270&munItem=276&capItem=123123
      

      还有serializeArray():

      itemsPerPage 5 第 1 页

      params [10] [name] munItem
      params [10] [value] 270
      params [11] [name] munItem
      params [11] [value] 276
      params [13] [name] capItem
      params [13] [value] 123123
      params [2] [name] codItem
      params [2] [value] asdfasdf
      params [3] [name] nameItem
      params [3] [value] asdfasdfasdf
      params [4] [name] tipItem
      params [4] [value] 1000600
      params [5] [name] tipItem
      params [5] [value] 1000492
      params [6] [name] public
      params [6] [value] on
      params [7] [name] private
      params [7] [value] on
      params [8] [name] provinceItem
      params [8] [value] 15
      params [9] [name] munItem
      params [9] [value] 262
      

      我可以像dataToSend的结构一样发送它吗?唯一的方法是通过参数?

      【讨论】:

        【解决方案3】:

        您可以简单地将HttpServletRequest 注入您的Controller 方法并自己读取主体,如下所示:

        public @ResponseBody HashMap<String, Object> search(HttpServletRequest request)
        {
        
            String params;
            try 
            {
                params = IOUtils.toString( request.getInputStream());
                System.out.println(params);
            } 
            catch (IOException e) 
            {
                e.printStackTrace();
            }
        
           //Your return statement.
        }  
        

        输出:{"page":1,"itemsPerPage":10,"params":{"codItem":"10","nameItem":"foo"}}

        您可以通过使用 JSON API sunch as GSON 将此字符串转换为 JSON 对象来读取此属性。或者创建包含您在 JSON 中定义的所有属性的 POJO,并将您的 Json 字符串直接转换为 POJO 对象。

        示例代码:

        MyClass obj = new Gson().fromJson(params, MyClass.class);  
        

        希望对您有所帮助。

        【讨论】:

          【解决方案4】:

          要正确执行此操作,您需要使用 JSON 库。 Spring 与 Jackson 捆绑在一起。

          首先,您需要创建类来表示您的 JSON。

          public class MyJson {
            int page;
            int itemsPerPage;
            Map<String, String> params;
          
            public MyJson() {}
          
            ... getters/setters
          
          }
          

          你需要改变 $.ajax,像这样发送数据 { data : JSON.stringify(dataToSend)},因为参数需要,一个名字。

          在你的控制器方法中写下:

          ObjectMapper mapper = new ObjectMapper();
          
          // readValue(youStringJson, destinactionClass)
          MyJson json = mapper.readValue(data, MyJson.class);
          

          如果您有 MyJson 参数字段的 getter,您可以遍历 json.getParams() 映射。

          【讨论】:

          • 你不需要包装器。你可以简单地说 Map json= mapper.readValue(YOURMAP , Map.class);
          【解决方案5】:
          /* An Alternative Solution: See if this helps::::Sample Code of java,javascript,jsp for search parameters. Search Parameter POJO will have search parameters + Pagenumber + RecordCounton the page + sortColumn in it */
          
              public class SearchParameters implements Serializable{
                  /**
                   * 
                   */
                  private static final long serialVersionUID = 4847934022647742263L;
                  private Integer pageNumber;
                  private String sortColumn;
                  private Integer recordCount;
                  private String sortOrder;
                  private Long gdsProductId; // some search parameter
                  private Integer ruleId; // some search parameter
          
              //getter and setters
          
              }
          /* your java controller method, which accepts the SearchParameter Object */
          
          @RequestMapping(value = "/search", method = RequestMethod.POST)
          @ResponseBody
          public Map<String, GDS> search(SearchParameters parameters)
                  throws Exception {
               // Print Parameter 
               logger.info("read :=" + parameters);
               // your logic to be written here
          }
          
          /* Your Javascript will have the below function.
             $("#searchPaginationform").serialize() will send the data for all the hidden elements of searchPaginationform in the below jsp.
            form  searchPaginationform will have hidden fields for the pagenumer,rows and other       elements */
          
              $.post('search.form', $("#searchPaginationform").serialize(), function (response) {
          
              }
          /* Your Jsp -- see the hiddenfield name is matching the SearchParameter instance variable -*/
          
              <form:form id="searchPaginationform">
                  <input type="hidden" name="gdsProductId" id="gdsProductId" >
                  <input type="hidden" name="pageNumber" id="pageNumber" value=1>
                  <input type="hidden" name="sortColumn" id="sortColumn" value="metamap_id">
                  <input type="hidden" name="recordCount" id="recordCount" value=10>
                  <input type="hidden" name="sortOrder" id="sortOrder" value="desc">
                  <input type="hidden" name="ruleId" id="ruleId"> 
              </form:form>
          

          【讨论】:

          • 我的问题是我想为以后的搜索过程发送变量 itemsPerPage 页面和单独的参数,这已经把我和他们放在了如下: $.ajax({ url: form.attr("action" ), 类型: 'POST', 数据: form.serialize () + "&page=" + 1 + "&itemsPerPage =" + 10, dataType: 'json', 缓存: false }).success(function(data) { 回调(数据); });但是因为我有页面和参数 itemsPerPage 变量
          • 您可以使用 IE9 、开发工具 (F12) 并捕获请求(通过单击“网络”选项卡并单击“开始捕获”按钮。看起来 HTTP 请求中没有名为“参数”的参数你的情况。
          • 可能是您的 ajax 调用可能会在请求正文中传递参数。在你的控制器中尝试@RequestBody。
          猜你喜欢
          • 1970-01-01
          • 2014-10-31
          • 2016-08-05
          • 1970-01-01
          • 2012-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-29
          相关资源
          最近更新 更多