I am using Vue.js, axios and Spring.
On the page I have the following axios code
axios({
method: 'post',
url: '/user/info',
params: {
'_csrf' : document.getElementById('csrf_id').value,
'name' : 'job',
'age' : '25',
},
headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json'}
});
And on the server I have a receiving method like this
#Controller
#RequestMapping("/user")
public class UserInfo {
#ResponseBody
#PostMapping(value = "/info", consumes = "application/x-www-form-urlencoded", produces = "application/json" + ";charset=utf8")
public String info(#RequestParam(value = "name") String name, #RequestParam(value = "age") String age) {
System.out.println(name);
System.out.println(age);
return "ok";
}
}
Axios makes a request to the server, but the server returns a 415 response.
The request headers are missing the application/x-www-form-urlencoded content type. I suspect the problem lies precisely in this.
Tell me, what am I doing wrong?
HttpMethod Post is a method of writing and transmitting data in the request body.
In your case, you put data through params. If you execute code as you write, data will be sent such as /user/info?_csrf=value&name=job&age=25 and there will be no data in the request body.
To get the response you want, you can modify it as below.
axios({
method: 'post',
url: '/user/info',
data: '_csrf=csrf&name=job&age=25',
headers: {'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json'}
});
change params keyword to data and write data like querystring.
Related
I have a Java Jersey class on the backend of my project which has the goal to consume a MULTIPART_FORM_DATA sent from an ajax frontend. When I send the data, I receive a 415 (Unsupported Media Type), even though the content type is formatted as:
content-type: multipart/form-data;
My backend method is configured as follow:
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Path("/fileupload")enter code here
public Response uploadFile(
#FormDataParam("file") FormDataContentDisposition cdh,#FormDataParam("file") InputStream fileStream) {
System.out.println("hello there");
Payment newPayment = new Payment();
return Response.ok().entity(newPayment).build();
}
Ajax code is configured as follow:
$.ajax({
url: '/path/api/fileupload',
type: "POST",
data: formData,
processData: false,
contentType: false,
success: function(response) {
alert("hello there")
},
error: function(jqXHR, textStatus, errorMessage) {
alert(errorMessage); // Optional
}
});
What am I doing wrong?
You have contentType set to false, it may be that the REST service is expecting MULTIPART_FORM_DATA and you're not sending that explicit contentType.
#Consumes(MediaType.MULTIPART_FORM_DATA) means you need to pass an explicit contentType of "multipart/form-data", which you are not doing, you are passing "false".
After spending more than half a day still not able to get down to whats wrong with the following:
Trying to send form data from NodeJSto Spring Rest API.
Node JS:
var inputData = { base : req.body.base, test : req.body.test }
var queryParams = {
host: '127.0.0.1',
port: 8080,
path: '/start',
method: 'POST',
headers: {'Content-type': 'application/json'},
body: inputData //Used JSON.stringify(inputData) - didn't work
};
Using http module to send request:
var req = http.request(queryParams, function(res) {
//do something with response
});
req.end();
Spring Rest:
#RequestMapping(value = "/start", method = RequestMethod.POST, consumes = "application/json")
#ResponseBody
public String startApp(#RequestBody String body) {
System.out.println(body);
return "{\"msg\":\"Success\"}";
}
Using postman I am able to see the same inputData going through the Rest. But when sent from NodeJS, all I see is
{
timestamp: 1506987022646,
status: 400,
error: 'Bad Request',
exception: 'org.springframework.http.converter.HttpMessageNotReadableException',
message: 'Required request body is missing: public java.lang.String ApplicationController.startApp(java.lang.String)',
path: '/start'
}
Using spring-boot-starter parent in the maven.
Am I missing anything here? Any suggestions would be greatly appreciated!
I don't think that you put request body in queryParams will work.
You can try using req.write() to write data to request body as follows:
...
req.write(inputData);
req.end();
...
#CrossOrigin(origins = "http://localhost:3000")
#GetMapping("")
public ResponseEntity<List<ToDoItemViewModel>> loadCategoriesByName(#RequestParam(required = false) String name)
{
List<ToDoItemViewModel> allItemsByCategoryName = toDoItemService.getAllItemsByCategoryName(name);
return new ResponseEntity<>(allItemsByCategoryName, HttpStatus.OK);
}
How can i pass just a primitive type to the controller, here is how my $.ajax looks like
$.ajax({
method: 'GET',
url: "http://localhost:8080/todItems",
contentType: 'application/json',
crossDomain: true,
data: 'Work',
success: (resp) => {
console.log(resp)
},
error: (resp) => {
console.log(resp);
}
})
Now when i debug it, it indeed sends the request to this controller, but the String name is always null for some reason, can you just show me what i have to adjust in my ajax request, it's probably something in the data field.
You are using GET Request with request params(#RequestParam annotation).
#RequestParam means that param in request pass across url, like this;
http://localhost:8080/todItems?name=Work
So, you just need to move data to url params.
If you prefer send data across request body, please do not use GET method, use POST instead. Many web servers are not supporting request body in GET Requests
I need to send data to Spring MVC controller by ajax. But controller doesn't work if I send more than one parameter.
Controller method:
#Timed
#RequestMapping(value = "saveee", method = RequestMethod.POST)
#ResponseBody
public JsonResultBean saveTicketTemplate(#RequestBody TicketTemplateFieldBean fieldBean, Long id) throws IOException {
//TODO smth
return JsonResultBean.success();
}
With this ajax code all works perfectly:
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: '/organizer/api/saveee',
data: JSON.stringify(fieldBean.data),
success: function(result) {
//TODO
}
})
But if I change data parameters, then controller doesn't get request even.
data: ({'fieldBean': JSON.stringify(fieldBean.data), 'id': id})
What I'm doing wrong?
That won't work. First lets clarify the difference between #RequestBody and #RequestParam.
The #RequestBody method parameter annotation should bind the json value in the HTTP request body to the java object by using a HttpMessageConverter. HttpMessageConverter is responsible for converting the HTTP request message to an assoicated java object. Source
And Use the #RequestParam annotation to bind request parameters to a method parameter in your controller. Source
Coming to you question...
With first ajax request you are sending JSON to your controller not request parameters, so #RequestBody is OK.
In the second ajax request also you are sending JSON but with two fields (fieldBean and id). Since #RequestBody annotated parameter is expected to hold the entire body of the request and bind to one object. You should modify the Java Object(ie TicketTemplateFieldBean) to hold id field also. This will work if you have only one argument in the controller.
Then, how to have second argument?
You cannot use two #RequestBody like :
public JsonResultBean saveTicketTemplate(#RequestBody TicketTemplateFieldBean fieldBean, #RequestBody Long id).
as it can bind to a single object only (the body can be consumed only once), You cannot pass multiple separate JSON objects to a Spring controller. Instead you must Wrap it in a Single Object.
So your solution is to pass it as Request parameter- #RequestParam, or as a path variable - #PathVariable. Since #RequestParam and #ModelAttribute only work when data is submitted as request parameters. You should change your code like this:
#Timed
#RequestMapping(value = "saveee", method = RequestMethod.POST)
#ResponseBody
public JsonResultBean saveTicketTemplate(#RequestBody TicketTemplateFieldBean fieldBean, #RequestParam("id") Long id) throws IOException {
//TODO smth
return JsonResultBean.success();
}
And change you request URL as follows:
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: '/organizer/api/saveee?id=10',
data: JSON.stringify(fieldBean.data),
success: function(result) {
//TODO
}
})
You can use #PathVariable like this:
#Timed
#RequestMapping(value = "saveee/{id}", method = RequestMethod.POST)
#ResponseBody
public JsonResultBean saveTicketTemplate(#RequestBody TicketTemplateFieldBean fieldBean, #PathVariable("id") Long id) throws IOException {
//TODO smth
return JsonResultBean.success();
}
And change you request URL as follows:
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: '/organizer/api/saveee/10',
data: JSON.stringify(fieldBean.data),
success: function(result) {
//TODO
}
})
To convert parameter to the method arguments you have to use #RequestParam, so the code should be modified like this:
Controller :
#Timed
#RequestMapping(value = "saveee", method = RequestMethod.POST)
#ResponseBody
public JsonResultBean saveTicketTemplate(#RequestParam TicketTemplateFieldBean fieldBean, #RequestParam Long id) throws IOException {
//TODO smth
return JsonResultBean.success();
}
You're not passing valid data to the controller. Try something like this.
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: '/organizer/api/saveee',
data: JSON.stringify({
fieldBean: JSON.stringify(fieldBean.data),
id: id
}),
success: function(result) {
//TODO
}
})
I have an AJAX call that should return JSON document
function getData() {
$.ajax({
url: '/x',
type: 'GET',
data: "json",
success: function (data) {
// code omitted
}
});
}
My server side is very simple.
#RequestMapping(value = "/x", method = GET, produces = "application/json")
public #ResponseBody List<Employee> get() {
return employeeService.getEmployees();
}
But my request can't even get to the controller. The error is:
HTTP Status 415 - The server refused this request because the request entity is in a format not supported by the requested resource for the requested method.
How can I fix it?
add #Consumes("text/html") before your code in server side,
#Consumes("text/html")
#RequestMapping(value = "/x", method = GET, produces = "application/json")
public #ResponseBody List<Employee> get() {
return employeeService.getEmployees();
}