How to pass javascript array to spring data rest - java

How to send array to spring rest? I tried the following but didn't work
javascript:
function postTopic(){
self.data.blogTopicsArr.push({
options: {
"title": self.title.value,
"details": self.topicDetails.value,
"username": "Guest user",
"userImage": "assets/img/spiritual-icon4.png",
"day_posted": new Date().toLocaleString()
}
});
$.ajax({
url: "/new_topic",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(self.data.blogTopicsArr),
success: function (res) {
},
error: function (err) {
}
});
}
Topic Bean class:
#Entity
#Table(name = "topics")
public class TopicBean implements Serializable {
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "title")
private String title;
#Column(name = "details")
private String details;
#Column(name = "username")
private String username;
#Column(name = "userImage")
private String userImage;
#Column(name = "day_posted")
private Date day_posted;
//Getters and Setters
}
Spring rest:
#RequestMapping(path = "/new_topic", method = RequestMethod.POST)
public ResponseEntity new_topic(#RequestBody List[] topics) throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.add("success", "topic added");
return new ResponseEntity(headers, HttpStatus.OK);
}
I get error: {"statusCode":400,"body":{"timestamp":1484506636823,"status":400,"error":"Bad Request","exception":"org.springframework.http.converter.HttpMessageNotReadableException","message":"Required request body is missing: public org.springframework.http.ResponseEntity seconds47.restAPI.Topics.new_topic(java.util.List[]) throws java.lang.Exception","path":"/new_topic"}}}
How do I solve this?
Update: added topic bean class above with fields I am using in that class

Try using
#RequestMapping(path = "/new_topic", method = RequestMethod.POST)
public ResponseEntity new_topic(#RequestBody List<HashMap<String, Object>> topics) throws Exception
And print out any input from topics. If you do get any values, you need to replace it with
#RequestMapping(path = "/new_topic", method = RequestMethod.POST)
public ResponseEntity new_topic(#RequestBody List<Topic> topics) throws Exception
with the relevant structure of the Topic class.
public class Topic{
OptionsBean options;
...
//getters and setters
...
}
public class OptionsBean{
String title;
String details;
String username;
String userImage;
String day_posted;
...
//getters and setters
...
}

function postTopic(){
var topic = {
"title": self.title.value,
"details": self.topicDetails.value,
"username": "Guest user",
"userImage": "assets/img/spiritual-icon4.png",
"day_posted": new Date().toLocaleString()
};
$.ajax({
url: "/new_topic",
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: topic,
success: function (res) {
},
error: function (err) {
}
});
}
#RequestMapping(path = "/new_topic", method = RequestMethod.POST)
public ResponseEntity new_topic(#RequestBody TopicBean topic) throws Exception {
//... do whatever with the new topic
HttpHeaders headers = new HttpHeaders();
headers.add("success", "topic added");
return new ResponseEntity(headers, HttpStatus.OK);
}
topic and TopicBean must have the same members and must be of same type.

Related

Post json to struts 2 action

I need to post a simple json object to a Struts 2 action, could you tell me what I miss with this:
the Java object to save:
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
private Integer id;
#Column(name = "code")
private String code;
#Column(name = "libelle_fr")
private String libelleFr;
#Column(name = "libelle_nl")
private String libelleNl;
I use alpine.js but it's a detail, the script called to send the request is this one:
<script>
function postForm() {
return {
indicateurDictionnaireForm: {
libelleFr: '',
libelleNl: '',
code: ''
},
message: '',
submitData() {
this.message = ''
fetch('<%= request.getContextPath() %>/mesures.ce.save.action', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
dataType:"json",
body: JSON.stringify(this.indicateurDictionnaireForm)
})
.then(() => {
this.message = 'Form sucessfully submitted!'
})
.catch(() => {
this.message = 'Ooops! Something went wrong!'
})
}
}
}
</script>
the json sent to the action is:
{
"libelleFr":"fr",
"libelleNl":"nl",
"code":"sample"
}
from my action file there is my method called from the front:
private IndicateurDictionnaire indicateurDictionnaireForm;
// Action to save an indicateurDictionnaireto database
#Action(value = "mesures.indicateurs.ce.save", results = {
#Result(name = "success", type = "json", params = {"root", "indicateurDictionnaireForm"}),
#Result(name = "input", type = "tiles", params = {"root", "indicateurDictionnaireForm"}, location = "viewMesureCoutUnitaire")})
public String save(IndicateurDictionnaire indicateurDictionnaire, String libelleFr, String libelleNl, String code) {
dictionnaireIndicateurBo.saveIndicateurDictionnaire(indicateurDictionnaire);
return SUCCESS;
}
According the struts2 json pluggin, the json should be mapped to my object if it's properly formatted but the fields are empty if I look in debug.
Do you know how I can proceed to at least see the json request in my action method?
The methods that are mapped to the actions not use any parameters in the method signature. So you need to remove those parameters and add json interceptor to the action config.
This field is used as root object by the json interceptor and should not be null.
IndicateurDictionnaire indicateurDictionnaire;
// getter and setter should be added
#Action(value = "mesures.indicateurs.ce.save", results = {
#Result(name = "success", type = "json", params = {"root", "indicateurDictionnaire"})
}, interceptorRefs = #InterceptorRef(value = "json", params = {"root", "indicateurDictionnaire"}))
public String save() {
dictionnaireIndicateurBo.saveIndicateurDictionnaire(indicateurDictionnaire);
return SUCCESS;
}

SpringBoot Exception: org.springframework.http.converter.HttpMessageNotReadableException on an Ajax post request

I am using Spring Boot 2.5.1, Lombock 1.18.20 and jQuery 3.5.1. I need to validate a DTO (with a list as param) via Ajax request. I'm trying to make this request, but I'm getting this error
m.m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character ('-' (code 45)) in numeric value: expected digit (0-9) to follow minus sign, for valid numeric value; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('-' (code 45)) in numeric value: expected digit (0-9) to follow minus sign, for valid numeric value at [Source: (PushbackInputStream); line: 1, column: 3]]
JavaScript file:
const validate = async () => {
const l1 = {
field1: 'l1',
field2: 'l2'
}
const l2 = {
field1: 'l3',
field2: 'l4'
}
const list = [l1, l2];
const dataJSON = JSON.stringify({
field1: 'valu1',
field2: 'valu2',
field3: 'valu3',
list: list
});
const formData = new FormData(jQuery('form')[0]);
formData.append('request', dataJSON);
$.ajax({
contentType: 'application/json',
url: '/mypath/validate',
type: 'POST',
data: formData,
async: true,
cache: false,
dataType: 'json',
processData: false,
traditional: true,
success: function(data, textStatus, xhr) {
//Do something
}
});
}
Ajax (jQuery) request:
-----------------------------996071269515593120684095564
Content-Disposition: form-data; name="request"
{"field1":"valu1","field2":"value2","field3":"value3","list":[{"field1":"l1","field2":"l2"},{"field1":"l3","field2":"l4"}]}
-----------------------------996071269515593120684095564--
DTO class:
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
#GroupSequence({RequestDTO.class, L1.class, l2.class, L3.class})
public class RequestDTO {
#NotEmpty(groups = L1.class, message = "This field is required")
private String field1;
#NotEmpty(groups = L1.class, message = "This field is required")
private String field2;
#NotEmpty(groups = L2.class, message = "This field is required")
private String field3;
#Valid
private List<RequestListDTO> list;
#Data
#Builder
#NoArgsConstructor
#AllArgsConstructor
public static class RequestListDTO{
#NotEmpty(groups = L3.class, message = "This field is required")
private String field1;
#NotEmpty(groups = L3.class, message = "This field is required")
private String field2;
}
}
Controller:
#Controller
#SessionScope
#RequestMapping(value = "/mypath")
*#Validated I have tried adding this but it doesn't work either*
public class ValidateController {
#PostMapping(value = "/validate", consumes = "application/json")
#ResponseBody
public ResponseEntity<?> validate(#Valid #RequestBody RequestDTO request) {
if (request != null) {
return ResponseEntity.ok().body(request);
}
return null;
}
}
If I change my controller method to public ResponseEntity<?> validate(HttpServletRequest request), I get the data correctly and can parse it, but I need the first approach
Any idea what's wrong here?

How to insert JSON object into database using spring boot and angularjs?

I am new to Spring boot so the question may sound silly. I want to insert a json object into database. But it is giving me an error like:
"Failed to evaluate Jackson deserialization for type".
On console, I am getting an error like:
Http 415 Unsupported Media type error with JSON
Here is my POJO class:
#Entity
#Table(name = "academics")
public class Academics {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private int id;
#Column(name = "adhaarcard")
private String adhaarCard;
#Column(name = "grade")
private List grades;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAdhaarCard() {
return adhaarCard;
}
public void setAdhaarCard(String adhaarCard) {
this.adhaarCard = adhaarCard;
}
public List getGrades() {
return grades;
}
public void setGrades(List grades) {
this.grades = grades;
}
}
My controller function:
#RequestMapping(value="saveacademics",method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> saveAvademics(#RequestBody Academics academics) {
academicsService.save(academics);
URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
.buildAndExpand(academics.getId()).toUri();
return ResponseEntity.created(location).build();
}
Angularjs Code:
$scope.saveAcademics = function() {
var adhaar = sessionStorage.getItem("emp-key");
var _data = {
"adhaarCard":adhaar,
"grades": {
"graduation":
{ "ssc": "SSC", "hsc": "HSC", "quOne": $scope.qone
},
"specialization":
{ 'ssc': "N.A", 'hsc': $scope.hscSpl, 'qoneSpl': $scope.qoneSpl},
"grade":
{ 'ssc': $scope.sscGrade, 'hsc': $scope.hscGrade, 'qoneGrade': $scope.qoneGrade},
"university":
{ 'ssc': $scope.sscUni, 'hsc': $scope.hscUni, 'qoneUni': $scope.qoneUni},
"year":
{ 'ssc': $scope.sscYear, 'hsc': $scope.hscYear, 'qoneYear': $scope.qoneYear}
}
};
console.log(_data);
$http({
url: 'saveacademics',
method: "POST",
data: JSON.stringify(_data)
})
.then(function(response) {
alert("Success");
},
function(response) { // optional
alert("Error Occoured.");
});
}
Try MediaType.APPLICATION_JSON instead on MediaType.APPLICATION_JSON_VALUE
#RequestMapping(value="saveacademics",method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON)
MediaType.APPLICATION_JSON is a "public constant media type for application/json", whereas MediaType.APPLICATION_JSON_VALUE is a "String equivalent of MediaType.APPLICATION_JSON".
Json that you generate from angular js and your Java pojo are not matching.
Better you can reformat json as below
{ adhaarCard: "12", grades : [
{ university: "univ name", specialization: "sadd", grade: 83, graduation:"SSC", year: 2007 },
{ university: "univ name", specialization: "sadd", grade: 67, graduation:"HSC", year: 2009 }
]
}
And mapping PoJo class as
#Column(name = "adhaarcard")
private String adhaarCard;
#Column(name = "grade")
private List<Grades> grades ;
Grades.java
private String university;
private String specialization;
private int grade;
private Sting graduation;
private int year;
Add Column mapping and getter, setters.
Tip:
Instead of #RequestMapping you can use #PostMapping which is a shorthand. So you wont get confused with media type, it take application/json as default type.
#RequestMapping(value="saveacademics",method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
replace with
#PostMapping("saveacademics")

How to read json with mulitple array in spring mvc controller?

I am sending json from ajax to controller that contain multiple array.
Json Data:
{
"node": [
{
"id": "dev_1",
"blockId": "11"
},
{
"id": "dev_2",
"blockId": "15"
}
],
"connect": [
{
"id": "con_5",
"typeId": "2"
}
],
"name": "test"
}
Controller:
#RequestMapping(value = "/saveBoard", method = RequestMethod.POST)
public JsonResponse saveBoard(#RequestBody String jsonData) throws IOException {
JsonResponse response = new JsonResponse();
ObjectMapper mapper = new ObjectMapper();
final JsonNode jsonNode = mapper.readTree(jsonData).get("node");
if(jsonNode.isArray()) {
for (final JsonNode nodes : jsonNode) {
System.out.println("jsonNode : "+ nodes);
}
}
return response;
}
I have tried with object mapper but not succeed.
Here i want to read different array for different classes like node for node class with some specified fields, connect for connect class and string for another use.
UPDATE
Contorller:
#RequestMapping(value = "/saveBoard", method = RequestMethod.POST)
public JsonResponse saveMissionBoard(#RequestBody MissionJsonPojo chartJson) {
boolean status = false;
String messsage = "";
JsonResponse response = new JsonResponse();
System.out.println("data : " + flowChartJson.getNodes());
return response;
}
Ajax:
$.ajax({
url: '<c:url value="/board/saveBoard"/>',
type: 'POST',
data: JSON.stringify(chartJson),
dataType: "json",
contentType: "application/json",
success: function(response) {
console.log("In success");
},
error: function (a, b, c) { }
});
JSON:
{
"nodes": [
{
"missionDeviceId": "device_1",
"device": "1",
"deviceXCoordinate": 79,
"deviceYCoordinate": 73,
"blockId": "1##1"
},
{
"missionDeviceId": "device_2",
"device": "3",
"deviceXCoordinate": 340,
"deviceYCoordinate": 146,
"blockId": "2##5"
}
],
"connections": [
{
"missionConnectionId": "con_5",
"sourceId": "device_1",
"targetId": "device_2",
"device": "2"
}
],
"name": "test"
}
Node Pojo:
public class Nodes{
private String missionDeviceId;
private Integer device;
private String deviceXCoordinate;
private String deviceYCoordinate;
private String blockId; //getters setters
}
Connection Pojo:
public class Connections{
private String missionConnectionId;
private String sourceId;
private String targetId;
private Integer device; //getters and setters
}
MissionJsonPojo:
public class MissionJsonPojo{
private List<Nodes> nodes;
private List<Connections> connections;
private String name; //getters and setters
}
As suggested by #dambros, create a POJO structure like this:
public class Node {
private String id;
private String blockId;
//setter-getters.
}
public class Connect {
private String id;
private String typeId;
//setter-getters.
}
import java.util.List;
public class Payload {
private List<Node> nodes;
private List<Connect> connects;
private String name;
//setter-getters
}
And change your method signature to:
public JsonResponse saveBoard(#RequestBody Payload payload) throws IOException {
}
This should solve your problem.

Required String parameter is not present error in Spring MVC

I try to make an AJAX query to my controller in Spring MVC.
My action code is:
#RequestMapping(value = "events/add", method = RequestMethod.POST)
public void addEvent(#RequestParam(value = "start_date") String start_date, #RequestParam(value = "end_date") String end_date, #RequestParam(value = "text") String text, #RequestParam(value = "userId") String userId){
//some code
}
My Ajax query is:
$.ajax({
type: "POST",
url:url,
contentType: "application/json",
data: {
start_date: scheduler.getEvent(id).start_date,
end_date: scheduler.getEvent(id).end_date,
text: scheduler.getEvent(id).text,
userId: userId
},
success:function(result){
//here some code
}
});
But I got an error:
Required String parameter ''start_date is not present
Why?
As I know I presented it like (#RequestParam(value = "start_date") String start_date
UDP
Now I give 404
My class to take data
public class EventData {
public String end_date;
public String start_date;
public String text;
public String userId;
//Getters and setters
}
My js AJAX call is:
$.ajax({
type: "POST",
url:url,
contentType: "application/json",
// data: eventData,
processData: false,
data: JSON.stringify({
"start_date": scheduler.getEventStartDate(id),
"end_date": scheduler.getEventEndDate(id),
"text": scheduler.getEventText(id),
"userId": "1"
}),
And controller action:
#RequestMapping(value = "events/add", method = RequestMethod.POST)
public void addEvent(#RequestBody EventData eventData){
}
And JSON data is:
end_date: "2013-10-03T20:05:00.000Z"
start_date: "2013-10-03T20:00:00.000Z"
text: "gfsgsdgs"
userId: "1"
On the server side you expect your request parameters as query strings but on client side you send a json object. To bind a json you will need to create a single class holding all your parameters and use the #RequestBody annotation instead of #RequestParam.
#RequestMapping(value = "events/add", method = RequestMethod.POST)
public void addEvent(#RequestBody CommandBean commandBean){
//some code
}
Here is a more detailed explanation.
I had the same issue.. I solved it by specifying the config params in the post request:
var config = {
transformRequest : angular.identity,
headers: { "Content-Type": undefined }
}
$http.post('/getAllData', inputData, *config*).success(function(data,status) {
$scope.loader.loading = false;
})
config was the parameter I included and it started working..
Hope it helps :)
Spring Boot Code
#RequestMapping(value = "events/add", method = RequestMethod.POST)
public void addEvent(#RequestParam(value = "start_date") String start_date, #RequestParam(value = "end_date") String end_date, #RequestParam(value = "text") String text, #RequestParam(value = "userId") String userId){
//some code
}
Postman Request Link to be send: Add the parameters and value using Parmas in postman and see the below request link.
http://localhost:8080/events/add?start_date=*someValue*&end_date=*someValue*&text=*someValue*&userId=*someValue*

Categories

Resources