I have a JSON object like as follows:
[
{
"usernameid": [
"2",
"7"
],
"phaseid": [
"2",
"7"
],
"weekstartdate": "2014-11-02"
}
]
I try to map this JSON in a POJO in my controller:
public ModelAndView approveTimesheet(#RequestBody ApproveTimesheet timesheet,HttpSession session)
{
logger.info("yes");
}
My AJAX Call:
$.ajax({
type : 'post',
url : 'PendingTimesheet',
contentType : "application/json; charset=utf-8",
data : JSON.stringify(jsonObj),
success : function(data) {
},
});
POJO class:
public class ApproveTimesheet
{
private String[] usernameid;
private String[] phaseid;
private String weekstartdate;
//Getters and Setters
}
I am getting the below exception
out of START_ARRAY token
at [Source: org.apache.catalina.connector.CoyoteInputStream#7097326d; line: 1, column: 1]
How to correctly map the above JSON request in Spring controller?
Any Ideas will be greatly appreciated.
You are sending an array of JSON objects and not a singleton one.
Your controller signature should then hold a Collection or Array of ApproveTimesheet on front of the #RequestBody annotation. (I would suggest using arrays to avoid generic types mismatch):
public ModelAndView approveTimesheet(
#RequestBody ApproveTimesheet[] timesheets,
HttpSession session)
{
for(int i = 0; i < timesheets.length; i++)
{
logger.info(timesheets[i]);
}
//...
}
Related
I'm trying to send an array of
this Json data
data using this Ajax in a JSP:
$.ajax({
url: 'agregarSeleccion',
type: 'POST',
dataType:'json',
data: JSON.stringify(lista),
success:function(dataP){
//Successs
error: function (jqXhr) {
swal("Error","","error");
}
});
To this controller in Java (Spring framework):
private List<Seleccion> seleccionados = new ArrayList<Seleccion>();
#RequestMapping("/agregarSeleccion")
#ResponseBody
public List<Seleccion> agregar(Seleccion obj) {
seleccionados.add(obj);
return seleccionados;
}
The "Seleccion" object it's an entity that has some of the attributes of the JSON that I sent from Ajax, the "seleccionados" is a list that saves the array received, but when I send it, the obj param always return a null object and Ajax sends the error function, I think the problem is that I'm sending an array to an Object, but I can't figure how to solve it
Seleccion object model:
public class Seleccion {
private int idProducto;
private String nombre;
private double precio;
private int cantidad;
private double totalParcial;
//Getters and setters
}
Try using ResponseEntity and update you controller like the below snippet;
Test Data
[
{
idProducto : 1,
nombre : 'Test1',
precio : 1.5,
cantidad : 1,
totalParcial : 2.5
}
]
Your Ajax (I changed datatype back to json);
$.ajax({
url: 'agregarSeleccion',
type: 'POST',
contentType: "application/json",
data: JSON.stringify(lista),
success:function(dataP){
console.log(dataP);
},
error: function (jqXhr) {
swal("Error","","error");
}
});
Your Controller (Notice a variable is declared outside method as well , added allAll method to add list , Changed return type at the end)
List<Seleccion> seleccionados;
#RequestMapping("/agregarSeleccion")
public ResponseEntity<?> agregar(#Valid #RequestBody List<Seleccion> obj) {
seleccionados = new ArrayList<Seleccion>();
System.out.println("result"+ obj.toString());
seleccionados.addAll(obj);
return new ResponseEntity<>(seleccionados, HttpStatus.OK);
}
I am trying to pass multi-valued parameters in request param and expecting results as below. I am using #RequestParam List<String> in the controller to return multi-valued parameters but I am trying to figure how can return the list of employee details in the response as shown below.
Http Request: /list/id?employee_ids=E123,E765
I am getting below response:
{
"Employees": [
{
"EmployeeID": "E123,E765",
"EmployeeName": "John"
}
Expected Results:
{
"Employees": [
{
"EmploeeId": "E123",
"EmployeeName": "John"
},
{
"EmploeeId": "E765",
"EmployeeName": "Peter"
}
]
}
Pojo:
private String employeeId;
private String employeeName;
Service:
When a list of employee id's are passed, I should get employee id and name
'Employee table contains: EmployeeId and EmployeeName as columns'
Controller:
#GetMapping(value = "/id")
public ResponseEntity<EmployeeResponse> getEmployee(#RequestParam List<String> employee_ids , #RequestHeader Map<String, Object> headers) {
log.info("Received request with headers: {}", headers);
ResponseEntity<EmployeeResponse> response = ResponseEntity.ok(getEmployee.employees(employee_ids
));
log.info("Responding to request with response: {}", response);
return response;
Here is an example of how I use hashmaps in my routes:
Map<String, Object> pdata = new HashMap();
pdata.put("schedules", schedSVC.getSchedules());
pdata.put("webuser", userSVC.getActiveUser());
if you are using JdbcTemplate
use the NamedParameterJdbcTemplate object
then you have the method NamedParameterJdbcTemplate.queryForList(query, params);
just need to add the query with the relevant list
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": "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"
}
]
}
]
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?
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
}
}
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.
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
I am using spring mvc. I need to pass a json object from my jsp page to controller.
My ajax code:
function createJSON() {
jsonObj = [];
item = {};
$(".values").each(function() {
var code = $(this).attr('id');
item[code] = $('#' + code).val();
});
var content=JSON.stringify(item)
$.ajax({
type: 'POST',
contentType : 'application/json; charset=utf-8',
url: "/pms/season/submit",
data: content,
dataType: "json",
success : function(data) {
alert(response);
},
error : function(e) {
alert('Error: ' + e);
}
});
}
My controller code:
#RequestMapping(value = "/submit", method = RequestMethod.POST)
public void saveNewUsers( #RequestParam ("json") String json) {
System.out.println( "json ::::"+json );
}
But it's not working.
#RequestParam("json") means that you are intending to include a request parameter called json in the URI, i.e. /submit?json=...
I think you intend to get the request body, i.e. #RequestBody.
I would then suggest that, unless you really need the raw JSON string, you would have the #RequestBody translated to a Java object for you:
public void saveNewUsers(#RequestBody MyDto myDto) {
...
}
where MyDto would have getters/setters and fields matching the JSON class.
You can over omit the #RequestBody annotation if you annotate the controller with #RestController, instead of #Controller.
If you definitely want the raw JSON string, then take a look at this previous question: Return literal JSON strings in spring mvc #ResponseBody
I am newbie in Spring. I generate the JSON like below:
[
{
"customer" : "16", "project" : "19",
"phase" : "47", "approver" : "5",
"date1" : "", "date2" : "",
"date3" : "", "date4" : "",
"date5" : "", "date6" : "",
"date7" : "", "activity" : "1"
},
{
"customer" : "17", "project" : "20",
"phase" : "48", "approver" : "3",
"date1" : "", "date2" : "",
"date3" : "", "date4" : "",
"date5" : "", "date6" : "",
"date7" : "", "activity" : "1"
}
]
I am passed this JSON to my Spring controller:
$.ajax({
type: 'post',
url: 'NewTimesheet',
dataType : 'json',
data: JSON.stringify(jsonObj),
success: function(data) {
console.log(data);
}
});
I am mapped the request to controller like below:
#RequestMapping(value="NewTimesheet", headers = { "Content-type=application/json" })
#ResponseBody
public String addNewTimesheet(#RequestBody List<Timesheet> timesheet,
HttpSession session) {
logger.info("timesheet list size is" + timesheet.size());
return "success";
}
Timesheet class:
public class Timesheet {
private String project;
private String phase;
private String approver;
private String customer;
private String date1;
private String date2;
private String date3;
private String date4;
private String date5;
private String date6;
private String date7;
private String activity;
//Getters and setters
}
But my request is not mapped with the conroller. My console displays like below:
WARN
org.springframework.web.servlet.PageNotFound.handleNoSuchRequestHandlingMethod:142
- No matching handler method found for servlet request: path '/NewTimesheet', method 'POST', parameters
map['[{"customer":"16","project":"19","phase":"47","approver":"5","date1":"","date2":"","date3":"","date4":"","date5":"","date6":"","date7":"","activity":"1"},{"customer":"17","project":"20","phase":"48","approver":"3","date1":"","date2":"","date3":"","date4":"","date5":"","date6":"","date7":"","activity":"1"}]'
-> array['']]
How to map my JSON to controller? Any help will be greatly appreciated!!!
You need to annotate the class as Controller, add a RequestMapping in your class and the HTTP method your calling in your method.
#Controller
#RequestMapping("/NewTimesheet")
public class MyClassName {
#RequestMapping(value={ "", "/" }, method = RequestMethod.POST, headers = { "Content-type=application/json" })
#ResponseBody
public String addNewTimesheet(#RequestBody List<Timesheet> timesheet,HttpSession session){
logger.info("timesheet list size is"+timesheet.size());
return "success";
}
}
Change #RequestBody to #ModelAttribute before the list in the controller. And in your json, put 'timesheet.' before every field, that is, timesheet.customer,timesheet.project.... such like that. That would work.
You need to define method=post. also I added produces = "application/json"
#RequestMapping(value="NewTimesheet", method = RequestMethod.POST, produces = "application/json")
#ResponseBody
public String addNewTimesheet(#RequestBody List<Timesheet> timesheet,HttpSession session){
logger.info("timesheet list size is"+timesheet.size());
return "success";
}
A couple things that might be causing problems for you:
Make sure you have all of the necessary dependencies for Jackson. For Maven, this would be:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.2</version>
</dependency>
You don't need to stringify your JavaScript object, this is done implicitly. You should also name your submitted variable, since it must map to the domain object:
$.ajax({
method : 'post',
url : 'NewTimesheet',
dataType : 'json',
data:{ 'timesheet': jsonObj },
success : function(data) {
console.log(data);
}
});
Your controller should be configured to explicitly handle a POST request. Setting the accepted content type in the headers is not necessary. Also, I believe you need to map your domain objects to an array and not a list:
#RequestMapping(value="NewTimesheet", method = RequestMethod.POST)
public #ResponseBody String addNewTimesheet(#RequestParam("timesheet") Timesheet[] timesheet,HttpSession session){
logger.info("timesheet list size is"+timesheet.length);
return "success";
}
If you are using a relatively recent version of Spring MVC, there is no additional configuration required to handle requests for and producing JSON. Your AJAX request specifies a JSON response, which Spring will recognize and delegate to Jackson for serializing the input and output.
In my ajax request i added the contentType:application/json.After adding this controller mapped my ajax request.Thanks for all.