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*
Related
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;
}
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?
I need help I last time create the controller with the single file upload with an object and it's work for me like
My POJO class
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "file", "data" })
public class FileWithObject<T> {
#JsonProperty("file")
private MultipartFile file;
#JsonRawValue
#JsonProperty("data")
private T data;
}
MY REST CONTOLLER
#RequestMapping(value="/filestore/{bucket-uuid}/appsport.com/singleFileUploadWithObject/{folder}",
method = RequestMethod.POST)
#ResponseBody
// api work
public String singleFileUploadWithObject(
#PathVariable(name="bucket-uuid", required = true) String bucketUUId,
#PathVariable(name="folder", required = false) String folder,
FileWithObject rawData) {
return pingResponse;
}
My Postman result
That's all work for me. How to send the list of the objects through the postman or is possible to handle that way request like below rest controller
#RequestMapping(value="/filestore/{bucket-uuid}/appsport.com/listOfObjectsWithSingleFile/{folder}", method = RequestMethod.POST)
#ResponseBody
public String listOfObjectsWithSingleFile(
#PathVariable(name="bucket-uuid", required = true) String bucketUUId,
#PathVariable(name="folder", required = false) String folder,
Set<FileWithObject> rawData) {
return pingResponse;
}
How to handle list of objects
[{
"file": fileobject,
"data": "zyz"
},{
"file": fileobject,
"data": "zyz"
}]
I'm trying to creating the api for this blow task
I have done this by use of Meta-Data concept there are few changes I did in controller and bean
Controller
#RequestMapping(value="/filestore/{bucket-uuid}/appsport.com/listOfObjectsWithSingleFile/{folder}",
method = RequestMethod.POST)
#ResponseBody
public String listOfObjectsWithSingleFile(
#PathVariable(name="bucket-uuid") String bucketUUId, #PathVariable(name="folder") String folder,
FileWithObject objects) { // change this Set<FileWithObject> rawData to FileWithObject objects
return pingResponse;
}
Bean
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "file", "files", "data" })
public class FileWithObject<T> {
#JsonProperty("file")
private MultipartFile file;
#JsonProperty("files")
private List<MultipartFile> files;
#JsonRawValue
#JsonProperty("data")
private T data;
// work like (meta-data)
List<FileWithObject> rawData;
// getter setter
}
Image's For Request
Note:- I'm Still looking for this issue handle this in a blow way
#RequestMapping(value="/filestore/{bucketuuid}/appsport.com/listOfObjectsWithSingleFile/{folder}", method = RequestMethod.POST)
#ResponseBody
public String listOfObjectsWithSingleFile(#PathVariable(name="bucket-uuid", required = true) String bucketUUId,
#PathVariable(name="folder", required = false) String folder,Set<FileWithObject> rawData) {
return pingResponse;
}
hope it helps some one
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.
I'm new in Spring Boot and I want to have the same Request Mapping method for JSON and simple request params, for example:
#RequestMapping(value = "/start")
public String startPostProcess(#RequestParam(value = "url",
required = false,
defaultValue = "https://goo.gl") String url,
#RequestParam(value = "word",
required = false,
defaultValue = "Search") String word,
#RequestBody String hereGoesJSON) {
//Do some stuff
}
So, when request goes with params, only #RequestParam will work, in other cases we will use #RequestBody annotation.
localhost:8080/start?url=htts://google.com&word=Luck
Or may bee I'll be able to write method like this, for accepting any params:
#RequestMapping(value = "/start")
public String startPostProcess(#RequestBody String anyParam) {
//Parse this anyParam
}
?
I've not found this trick in spring documentation, so I will appreciate any links to it.
Okay, I've solved the problem :D
All that I just needed was 2 methods with the same mapping and explicitly specify RequestMethod type:
#RequestMapping(value = "/start")
public String startPostProcess(#RequestParam(value = "url",
required = false,
defaultValue = "https://goo.gl") String url,
#RequestParam(value = "word",
required = false,
defaultValue = "Search") String word) throws InterruptedException {
//Do some stuff
}
#RequestMapping(value = "/start", method = RequestMethod.POST, consumes = "application/json")
public String startJsonProcess(#RequestBody String body) {
//Do another stuff with RequestBody
}
UPD: added "consumes = "application/json". It helps dividing simple POST requests and JSON POST requests.