0

My used stack

  • spring boot 1.5.6 realease
  • ajax jquery 3.3.1

My objective

I m trying to print some data into jasper report so I created a rest controller, I got the idea to send json data from front end and got it parsed thanks to jackson api into List of pojo then using the JRDataBean to process my report

My code

When pushing the print button I m sending this json array using ajax that I got from the chrome console by making it a global variable then using a copy ( atrick that I googled to get variable content as string )

  • here is my json

.

   [ {
    "codeInterne": 45,
    "clientName": "TalcorpDZ",
    "clientPhone": "+213778217469",
    "codeExterne": "CLI201801",
    "email": "[email protected]",
    "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": "[email protected]",
    "clientType": 1,
    "clientEtat": 1,
    "identifiant": "lkjhgf",
    "contacts": [
      {
        "nom": "Taleb",
        "prenom": "Mohammed",
        "telephonePortable": "02354649",
        "email": "[email protected]"
      }
    ],
    "adresses": [
      {
        "adress": "Batiments des enseignants Mohammed Khemist",
        "ville": "Maghnia"
      }
    ]
  }
]
  • and here is the part where I do the post request

.

$(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);

            });
    });

the post is well received by my controller which is coded as the following :

@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

    }
}

finally here is my ClientJsonDto.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 
}

adress.java

@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
}

contact.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
}

the exception that I m facing is:

2018-11-18 15:12:40.255 WARN 1768 --- [nio-8082-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'object': was expecting ('true', 'false' or 'null'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'object': was expecting ('true', 'false' or 'null') at [Source: java.io.PushbackInputStream@1df244f9; line: 1, column: 9]

what can I do to see what my rest controller is receiving as request body before that jackson tries to marshal?

what can I do to fix this exception?

1
  • thank you for the suggestion it was instructive, I fixed the bug here is the answer Commented Nov 20, 2018 at 12:29

3 Answers 3

1

Your json value and mapping is all correct but i can't see producer and consumer with post mapping request as you have to explicitly define the producer and consumer.

The error could be due to the format of data you are giving to your controller. Your controller method is expecting JSON string. For example in case of jQuery, JSON.stringify() gives you JSON string. So I would suggest you confirm this at the client side from where you're sending the data to this controller.

Code which you need to change and check.

@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

        }
    }
Sign up to request clarification or add additional context in comments.

3 Comments

After a day of searching I believe that I m doing things wrong in my js I will try to refactor all my js code and keep you in touch
can you try to use private List<Contact> contacts; instead of assigning null value also for private List<Adress> adresses; as well.
thanks to you talking about json string I figured it out so I accept also your answer thanks
1

I believe you want to see what is being received so that you can find why it is not getting mapped to your DTO.

Try changing

@RequestBody List<ClientJsonDto> datas

to

@RequestBody List<Map> datas

or

@RequestBody List datas

And see if you can print and debug it.

Comments

0

Finally got fixed

I based my fix upon this tutorial,what I mentioned is I m handling my array in a shady way so I tried the same principle, and I added the JSON.stringify and changed the datatype to text

here is all the changes that I made

$(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);

        });
});

the print data that I m printing is handled as below

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);

}

before the fix it was like this, may be this idea is to avoid because I was using a jquery array of objects whithout knowing

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);

}

wish this helps entry level like me in the futur

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.