I have a JSP page that makes an ajax post to a Java spring controller. However, whenever I make the post, I am getting a 415 Unsupported Media Type error. Since I'm fairly new to Spring MVC, I'm not sure if the error is due to my response type or request type. My ajax looks like:
$.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
type: "POST",
url: "validateRedirect",
context:document.body,
contentType:"application/json",
data:JSON.stringify(validateObject),
dataType:"json"
});
With my request mapping looking like:
#RequestMapping(value = "/validateRedirect", method = {RequestMethod.POST}, headers="Content-Type=application/json")
public ResponseEntity<String> callToValidate(HttpServletRequest servletRequest, HttpServletResponse servletResponse, #RequestBody ValidateObj validateObject)
Even when I try to make a post from Postman, I get the same error, so I'm thinking it's something to do with my response
Try modifying your controller to
#PostMapping(value = "/validateRedirect")
public ResponseEntity<ValidateObj> callToValidate(#RequestBody ValidateObj validateObject)
try it out:
#RestController
public TestController{
#PostMapping("/validateRedirect")
public ResponseEntity<ValidateObj> callToValidate(#RequestBody ValidateObj validateObject){
//...your logic
return new ResponseEntity<ValidateObj>();
}
}
If you are using default settings of spring, it should application/json as default accept and content type. So you don't have to specify in annotation.
Related
I'm developping a REST API in JavaEE and a client using this API in ReactJS.
The API works perfectly when I'm using postman, but as soon as I use fetch method in JS to POST JSON information through my client, I'm getting a 415 error: Unsupported Mediatype in my browser's console.
For the API, I'm using Jersey to process requests and Hibernate as ORM. I have genson dependency and as I said, everythig works perfectly fine with Postman.
I also checked the result of JSON.stringify() before sending it and it looks fine to me.
Plus, in my server's console, I'm getting this error everytime I try to POST anything :
GRAVE: A message body reader for Java class model.User, and Java type class model.User, and MIME media type application/octet-stream was not found.
I checked and double-checked everything, I'm sending the right headers, the browser identifies the request as 'application/json' content type but it's like my API still doesn't accept it, or receives it as application/octet-stream mediatype.
Here is the method where fetch is done :
signIn(){
console.log(JSON.stringify(this.state));
fetch('http://localhost:8080/P52/users', {
method: 'POST',
body: JSON.stringify(this.state),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}).then(res => {
return res.json();
}).catch(err=>err)
}
The method that receives data in the API :
#POST
#Consumes(MediaType.APPLICATION_JSON)
public User createUser(User u){
return UserController.createUser(u);
}
The controller just create a new instance of User class to run this code in the User model class :
public User(User u){
this.id = u.getId();
this.pseudo = u.getPseudo();
this.firstname = u.getFirstname();
this.lastname = u.getLastname();
Session session = (Session)HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.save(this);
session.getTransaction().commit();
session.close();
}
If anyone has the answer to my problem or has already faced it, please let me know so I can finally move forward with this project.
Thank you in advance,
Arthur
415 is Unsupported Media Type (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/415)
try changing
#Consumes(MediaType.APPLICATION_JSON)
to
#Consumes(MediaType.APPLICATION_JSON_VALUE)
This is the jquery function which returns 415 media type not found error
$('#save').on('click',function(){
alert("test");
var data = JSON.stringify(jQuery('#form').serializeArray());
console.log("data"+data);
$.ajax({
type: "POST",
url: "saveExpenses",
data: JSON.stringify(jQuery('#form').serializeArray()),
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: true,
success: function(data){alert("Success");}
})
})
and the controller:
#RequestMapping(value="/saveExpenses",method=RequestMethod.POST)
public String saveExpense(#RequestBody ExpensesSummary expenses, HttpServletRequest request,HttpSession session){
System.out.println("first name"+expenses.getFirstName());
String message = homeBankingDao.expenseSummary(expenses);
request.getSession().setAttribute("message",message);
return "login";
}
Perhaps you should have a look to produce and consume annotations and attributes.
Those posts may certainly help:
Multiple scenarios #RequestMapping produces JSON/XML together with Accept or ResponseEntity
Spring 3.1 or Later #RequestMapping Consumes/Produces
Spring Mvc and MediaType for consumes in #RequestMapping for a get rest request
Spring RequestMapping for controllers that produce and consume JSON
Or I don't get it...
EDIT:
if the error (415) is thrown from your jquery function then you should certainly also define the "accept: application/json" thing in your original query. Cf. this post.
If server-side, you should also check that Jackson is present in your libraries. Cf. this post.
I send POST request
$.ajax({
type: "POST",
url: "/common/ajax/advert/",
data: data,
dataType: "json",
contentType: "application/json",
success: function(r){}
});
to controller
#Controller
#RequestMapping(value = "/common/ajax/advert")
public class Controller {
#RequestMapping(value="/", method=RequestMethod.POST)
#ResponseBody
public Map<String,Object> adsSearch(#RequestBody Map<String,Object> data){
Map<String,Object> result = new HashMap<String,Object>();
List<Advert> ads = advSrv.getAds(data);
result.put("obj", ads);
return result;
}
and return 404 error, but in spring 3.2 this work fine.
Controllers with RequestMethod.GET work correct in old and new version.
Please help me to fix it.
UPD.1 I tried to create a #RestController class (Spring 4.1) with RequestMethod.POST - and it did not work too.
UPD.2 In log Spring mapped this methods properly, but post request not handled (unlike get requests, they works fine).
Finaly I found a problem - it was a Spring Security after upgrading to 4.0, where csrf protection enabled by default:
DEBUG: org.springframework.security.web.csrf.CsrfFilter - Invalid CSRF token found for post-request
I add support csrf protection and all work properly.
Hi am using spring mvc + ajax. I made a ajax call by passing a userid. And everything goes fine successfully returned to ajax but when i alert the response its simple showing the html page code. Please help me to sort out this prob.
I think i didnt coded my ajax well.Help me to in correct way
Controller code:
public #ResponseBody ModelAndView abc(HttpServletRequest httpServletRequest,
HttpSession session, ModelMap map){
ModelAndView modelAndView = new ModelAndView("abcd.page",
"commandName", object);
return modelAndView;
Ajax code :
$(".userDetails").click(function() {
alert("clicked");
var userId=$(this).parent().parent(). parent().find(".userId").
text().trim();
alert("userId :"+userId);
$.ajax({
url : 'ABC.htm',
type : 'GET',
data: {userId:userId},
beforeSend: function(xhr) {
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
},
success : function(response) {
alert("success");
alert(response);
},
error : function(res) {
alert("error");
},
});
return false;
});
The output for the alert(response); is
EDIT: Can any one please tell why ajax giving html content on success... After many changes i made getting the same alert.
Edited Again : I think i dont have any problem in controller. Please suggest me solution to code my ajax correctly. It seems error here. How to get a ModelAndView object in ajax
You don't get a ModelAndView object in AJAX. Spring uses HandlerMethodReturnValueHandler instances to handle your handler method's return value. For ModelAndView, it uses ModelAndViewResolverMethodReturnValueHandler. For #ResponseBody, it uses RequestResponseBodyMethodProcessor. These are checked in a specific order and the one for ModelAndView has higher priority. Therefore, when you return a ModelAndView, Spring will add the model attributes to the full Model and then resolve your view name to, probably, a jsp and write the response from that jsp, giving you some HTML. Since AJAX just sees the response from the request, it will see HTML.
If you want to return JSON, don't return a ModelAndView, return the model object directly or write JSON directly to the response yourself.
I'm familiar with how to return json from my #Controller methods using the #ResponseBody annotation.
Now I'm trying to read some json arguments into my controller, but haven't had luck so far.
Here's my controller's signature:
#RequestMapping(value = "/ajax/search/sync")
public ModelAndView sync(#RequestParam("json") #RequestBody SearchRequest json) {
But when I try to invoke this method, spring complains that:
Failed to convert value of type 'java.lang.String' to required type 'com.foo.SearchRequest'
Removing the #RequestBody annotation doesn't seem to make a difference.
Manually parsing the json works, so Jackson must be in the classpath:
// This works
#RequestMapping(value = "/ajax/search/sync")
public ModelAndView sync(#RequestParam("json") String json) {
SearchRequest request;
try {
request = objectMapper.readValue(json, SearchRequest.class);
} catch (IOException e) {
throw new IllegalArgumentException("Couldn't parse json into a search request", e);
}
Any ideas? Am I trying to do something that's not supported?
Your parameter should either be a #RequestParam, or a #RequestBody, not both.
#RequestBody is for use with POST and PUT requests, where the body of the request is what you want to parse. #RequestParam is for named parameters, either on the URL or as a multipart form submission.
So you need to decide which one you need. Do you really want to have your JSON as a request parameter? This isn't normally how AJAX works, it's normally sent as the request body.
Try removing the #RequestParam and see if that works. If not, and you really are posting the JSON as a request parameter, then Spring won't help you process that without additional plumbing (see Customizing WebDataBinder initialization).
if you are using jquery on the client side, this worked for me:
Java:
#RequestMapping(value = "/ajax/search/sync")
public ModelAndView sync(#RequestBody SearchRequest json) {
Jquery (you need to include Douglas Crockford's json2.js to have the JSON.stringify function):
$.ajax({
type: "post",
url: "sync", //your valid url
contentType: "application/json", //this is required for spring 3 - ajax to work (at least for me)
data: JSON.stringify(jsonobject), //json object or array of json objects
success: function(result) {
//do nothing
},
error: function(){
alert('failure');
}
});