代码之家  ›  专栏  ›  技术社区  ›  Mohammed Housseyn Taleb

将JSON数组发送到REST端点会导致Jackson解析异常

  •  0
  • Mohammed Housseyn Taleb  · 技术社区  · 6 年前

    我常用的堆栈

    • 弹簧靴1.5.6 RealEase
    • Ajax jquery 3.3.1

    我的目标

    我正试图将一些数据打印到Jasper报表中,因此创建了一个REST控制器,我有了从前端发送JSON数据的想法,并通过Jackson API将其解析为pojo列表,然后使用jrdatabean处理我的报表。

    我的密码

    当按下打印按钮时,我使用从chrome控制台获得的Ajax发送这个json数组,方法是将其设置为全局变量,然后使用副本(我在Google上搜索的atrick将变量内容设置为字符串)

    • 这是我的JSON

    .

       [ {
        "codeInterne": 45,
        "clientName": "TalcorpDZ",
        "clientPhone": "+213778217469",
        "codeExterne": "CLI201801",
        "email": "talcorpdz@gmail.com",
        "clientType": 0,
        "clientEtat": 1,
        "identifiant": "TalcorpDZ",
        "contacts": [
          {
            "nom": "Taleb",
            "prenom": "Mohammed Housseyn",
            "telephonePortable": "04330256699",
            "email": null
          }
        ],
        "adresses": [
          {
            "adress": "Batiments des enseignants Mohammed Khemisti",
            "ville": "Maghnia"
          }
        ]
      },
      {
        "codeInterne": 64,
        "clientName": "lkjhgf",
        "clientPhone": "+213778217469",
        "codeExterne": "dfghjk",
        "email": "talcorpdz@gmail.com",
        "clientType": 1,
        "clientEtat": 1,
        "identifiant": "lkjhgf",
        "contacts": [
          {
            "nom": "Taleb",
            "prenom": "Mohammed",
            "telephonePortable": "02354649",
            "email": "talcorpdz@gmail.com"
          }
        ],
        "adresses": [
          {
            "adress": "Batiments des enseignants Mohammed Khemist",
            "ville": "Maghnia"
          }
        ]
      }
    ]
    
    • 下面是我处理邮件请求的部分

    .

    $(document).on('click', '#menu0-func1-menu0-func1', function(){
            console.log(printData);
                var settings = {
                    "async" : true,
                    "crossDomain" : true,
                    "url" : "http://"+document.location.host+"/facturation/print/client",
                    "method" : "POST",
                    "headers" : {
                        "cache-control" : "no-cache",
                        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                    },
                    "processData" : false,
                    "contentType" : "application/json",
                    "dataType" : "json",
                    "data" : printData
                }
    
                $.ajax(settings).done(function(response) {
                    console.log(response);
    
                });
        });
    

    这篇文章很受我的控制器欢迎,编码如下:

    @RestController
    @RequestMapping(PrintController.API)
    public class PrintController {
        public static final String API="print";
    
    
        @PostMapping("client")
        public void export(@RequestBody List<ClientJsonDto> datas,HttpServletResponse response){
    
            System.out.println(datas);
    
            // processing the print mechanisme
    
        }
    }
    

    最后是我的客户jsondto.java

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonPropertyOrder({
        "codeInterne",
        "clientName",
        "clientPhone",
        "codeExterne",
        "email",
        "clientType",
        "clientEtat",
        "identifiant",
        "contacts",
        "adresses"
    })
    public class ClientJsonDto {
    
        @JsonProperty("codeInterne")
        private Integer codeInterne;
        @JsonProperty("clientName")
        private String clientName;
        @JsonProperty("clientPhone")
        private String clientPhone;
        @JsonProperty("codeExterne")
        private String codeExterne;
        @JsonProperty("email")
        private String email;
        @JsonProperty("clientType")
        private Integer clientType;
        @JsonProperty("clientEtat")
        private Integer clientEtat;
        @JsonProperty("identifiant")
        private String identifiant;
        @JsonProperty("contacts")
        private List<Contact> contacts = null;
        @JsonProperty("adresses")
        private List<Adress> adresses = null;
        @JsonIgnore
        private Map<String, Object> additionalProperties = new HashMap<String, Object>();
    
    // getters, setters 
    }
    

    爪哇

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonPropertyOrder({
        "adress",
        "ville"
    })
    public class Adress {
    
        @JsonProperty("adress")
        private String adress;
        @JsonProperty("ville")
        private String ville;
        @JsonIgnore
        private Map<String, Object> additionalProperties = new HashMap<String, Object>();
    
    //getters, setters
    }
    

    Java语言

    @JsonInclude(JsonInclude.Include.NON_NULL)
    @JsonPropertyOrder({
        "nom",
        "prenom",
        "telephonePortable",
        "email"
    })
    public class Contact {
    
        @JsonProperty("nom")
        private String nom;
        @JsonProperty("prenom")
        private String prenom;
        @JsonProperty("telephonePortable")
        private String telephonePortable;
        @JsonProperty("email")
        private String email;
        @JsonIgnore
        private Map<String, Object> additionalProperties = new HashMap<String, Object>();
     //getters setters
    }
    

    我面临的例外是:

    2018-11-18 15:12:40.255警告1768--[NIO-8082-EXEC-9] .W.S.M.S.DefaultHandlerExceptionResolver:未能读取HTTP 信息: org.springframework.http.converter.httpmessagenotreadable异常: JSON分析错误:无法识别的标记“object”:应为(“true”, “false”或“null”);嵌套异常为 com.fasterxml.jackson.core.jsonParseException:无法识别的令牌 “object”:在[source: Java.Io.PubBaskPixStudio1DF244F9;线:1,列:9

    我该怎么做才能看到我的休息控制器在杰克逊试图进行编组之前接收到的请求主体?

    我可以做什么来修复这个异常?

    3 回复  |  直到 6 年前
        1
  •  1
  •   GauravRai1512    6 年前

    您的JSON值和映射都是正确的,但是我看不到带有后映射请求的生产者和消费者,因为您必须明确定义生产者和消费者。

    错误可能是由于您提供给控制器的数据的格式造成的。您的控制器方法需要JSON字符串。例如,对于jquery,json.stringify()为您提供json字符串。所以我建议您在客户端确认这一点,从那里您将数据发送给这个控制器。

    需要更改和检查的代码。

    @RestController
    @RequestMapping(PrintController.API)
    public class PrintController {
        public static final String API="print";
    
    @PostMapping("client",produces=MediaType.APPLICATION_JSON_VALUE,consumes=MediaType.APPLICATION_JSON_VALUE)
            public void export(@RequestBody List<ClientJsonDto> datas,HttpServletResponse response){
    
                System.out.println(datas);
    
                // processing the print mechanisme
    
            }
        }
    
        2
  •  1
  •   Teddy    6 年前

    我相信你想看看收到了什么,这样你就可以找到为什么它没有映射到你的DTO。

    尝试改变

    @RequestBody List<ClientJsonDto> datas
    

    @RequestBody List<Map> datas
    

    @RequestBody List datas
    

    看看是否可以打印和调试它。

        3
  •  0
  •   Mohammed Housseyn Taleb    6 年前

    终于修好了

    我的解决方法基于此 tutorial ,我提到的是我正在以一种不明确的方式处理我的数组,所以我尝试了相同的原则,并添加了json.stringify并将数据类型更改为文本。

    这是我做的所有更改

    $(document).on('click', '#menu0-func1-menu0-func1', function(){
        console.log(printData);
        var jsonData =JSON.parse(JSON.stringify(printData));
            var settings = {
                "async" : true,
                "crossDomain" : true,
                "url" : "http://"+document.location.host+"/facturation/print/client",
                "method" : "POST",
                "headers" : {
                    "cache-control" : "no-cache",
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                },
                "processData" : false,
                "contentType" : "application/json",
                "dataType" : "text",
                "data" : JSON.stringify(printData)
            }
    
            $.ajax(settings).done(function(response) {
                console.log(response);
    
            });
    });
    

    我正在打印的打印数据处理如下

    var printData =[];
    
    function displayList(){
        console.log("click");
        if(console.log($('#search-client').val())){
            console.log($('#search-client').val().toLowerCase());
        }
        var as=clientsData.filter((n,i,a) =>{return (
                n.email.toLowerCase().indexOf($('#search-client').val().toLowerCase()) >= 0 || 
                n.contacts[0].nom.toLowerCase().indexOf($('#search-client').val().toLowerCase()) >= 0 ||
                n.contacts[0].prenom.toLowerCase().indexOf($('#search-client').val().toLowerCase()) >= 0 || 
                n.adresses[0].ville.toLowerCase().indexOf($('#search-client').val().toLowerCase()) >= 0 || 
                n.contacts[0].telephonePortable.toLowerCase().indexOf($('#search-client').val().toLowerCase()) >= 0)});
        var html=' ';
        console.log(as.length);
        printData = [];
        for(var i=0; i<as.length ; i++){
            var ClientJsonDto = as[i];
            html+=[{client : as[i] , index : i}].map(RefCliElement).join('');   
            printData.push(ClientJsonDto);
        }
    
        console.log(JSON.stringify(printData));
        $('#clientList').html(html);
        console.log(html);
    
    }
    

    在修复之前,可能这个想法是为了避免,因为我使用的对象是jquery数组,而不知道

    var printData;
    
    function displayList(){
        console.log("click");
        if(console.log($('#search-client').val())){
            console.log($('#search-client').val().toLowerCase());
        }
        var as=clientsData.filter((n,i,a) =>{return (
                n.email.toLowerCase().indexOf($('#search-client').val().toLowerCase()) >= 0 || 
                n.contacts[0].nom.toLowerCase().indexOf($('#search-client').val().toLowerCase()) >= 0 ||
                n.contacts[0].prenom.toLowerCase().indexOf($('#search-client').val().toLowerCase()) >= 0 || 
                n.adresses[0].ville.toLowerCase().indexOf($('#search-client').val().toLowerCase()) >= 0 || 
                n.contacts[0].telephonePortable.toLowerCase().indexOf($('#search-client').val().toLowerCase()) >= 0)});
        var html=' ';
        console.log(as.length);
        for(var i=0; i<as.length ; i++){
            html+=[{client : as[i] , index : i}].map(RefCliElement).join('');   
        }
        printData = as;
        $('#clientList').html(html);
        console.log(html);
    
    }
    

    希望这有助于入门级的未来像我一样