Problems sending multiple objects through POST and SPRING-MVC - java

I'm developing REST services which have to receive multiple info. In this case, two objects and an attribute.
This is the javascript where I'm testing the POST request
var user = {
username: "admin",
password: "admin"
};
var userToSubscribe = {
username: "newuser",
password: "newpassword",
email: "user#1and1.es"
};
var openid = "myopenid";
$.ajax({
url: '/myportal/rest/subscribeUser.json',
type: 'POST',
dataType: 'json',
contentType: 'application/json',
mimeType: 'application/json',
data: JSON.stringify({ user: user, userToSubscribe: userToSubscribe, openid: openid})
});
The POST request:
JSON
openid
"myopenid"
user
Object { username="admin", password="admin"}
userToSubscribe
Object { username="newuser", password="newpassword", email="user#1and1.es"}
Source
{"user":{"username":"admin","password":"admin"},"userToSubscribe":{"username":"newuser","password":"newpassword","email":"user#1and1.es"},"openid":"myopenid"}
And the controller which handles the POST:
#RequestMapping(method=RequestMethod.POST, value="/subscribeUser.json")
public #ResponseBody Message subscribeUser(#RequestBody("user") User user, #RequestBody("userToSubscribe") User userToSubscribe, #RequestParam String openid){
...
}
And the error is
POST subscribeUser.json 400 Incorrect request localhost:8080 990 B [::1]:8080
What am i doing wrong?
Thank you

The request body will contain the entire JSON content. So when you want to map the JSON, you use only one RequestBody annotated-parameter. You will have to do something like this:
public #ResponseBody Message subscribeUser(#RequestBody String str)
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(str);
And then use the convertValue method of the mapper to get your different objects from the string.
JsonNode node = mapper.readTree(str);
User theUser = mapper.convertValue(node.get("user"), User.class);
Similarly for the other objects

You cannot use #ModelAttributes in a RESTful method that accepts JSON. I believe the proper method is to use #RequestBody, as done here. You will most likely need to wrap the objects in some wrapper class, but I could be wrong there as I have never personally tried to pass multiple JSON objects in one request before.
That said, I think it would be a good idea if you rethought your REST api, removing the JSON arguments and instead passing them in as part of the URI path, if possible. I would suggest reading through this blog post.

You can create a java bean(POJO) containing all the objects like..
class JavaBean{
private User user;
private UserTOSubscribe userToSubscribe;
private Long openId;
// getter and setter
}
and pass this bean in to the Web service. so web service looks like..
#RequestMapping(method=RequestMethod.POST, value="/subscribeUser.json")
public #ResponseBody Message subscribeUser(#RequestBody JavaBean javaBean) {
...
}

Related

How to pass large number of parameters from Angular js to rest service

I am trying to fetch parameters from angular JS $http service to rest service using **#queryParam** . I need to fetch lot of parameters(below have shown for 3 as an example ,but I need to use around 12-15 of them which I need to pass to the java side) ,so fetching all with #QueryParam makes the code look pretty bad .I am using GET.
How can I optimize this ?
Example what I am doing -
Angular Js code -
$http({
url: someUrl,
method: "GET",
params: {filter1: $scope.filter1,
filter2:$scope.filter2,
filter3:$scope.filter3
});
Java side -
#path("/getAllData")
#GET
#Produces({..}
public response getAllData(#QueryParam("filter1") final String filter1,
#QueryParam("filter2") final String filter2,
#QueryParam("filter3") final String filter3){
}
Also ,wanted to know the optimization in case when I am building URL instead of params object, and picking the same with #PathParam
$http.get('rest/test/getAllData/?filter1='$scope.filter1 +
'&filter2='$scope.filter2 + '&filter3='$scope.filter3 +
'&filter4='$scope.filter4)
I am able to do it by passing individually in #QueryParam . I am looking for optimized code when we a large number of parameters.
Create a POJO with all the required parameters.
In angular, do this
var obj = {};
obj.filter1 = $scope.filter1;
obj.filter2 = $scope.filter2;
obj.filter3 = $scope.filter3;
$http({
url: someUrl,
method: "GET",
params: obj
});
You can accept all the parameters in you rest like this -
#path("/getAllData")
#GET
#Produces({..}
public response getAllData(MyPojo obj){
//String filter1 = obj.filter1;
}
You can do it in 2 ways:
1) org.json.simple.JSONObject.
2) Bean or POJO Class.
AngularJS Controller:
var URL = appURL+'/adm/addCollProcess.do';
var json = {"col_pro_id":$scope.col_pro_id, "col_code": $scope.col_code, "exam_type_ids": $scope.exam_types.toString().replace("[","").replace("]",""),
"created_by" : "admin", "file_path" : $scope.file_path, "website" : $scope.website, "facebook" : $scope.facebook};
// using JSONObject
$http.post(URL, json).then(function(response){
if(response.data){
// Code
}
});
// using Bean Class
$http.post(URL, JSON.stringify(json)).then(function(response){
if(response.data){
// Code
}
});
Java Controller:
// using JSONObject
#RequestMapping(value="/addCollProcess.do", method=RequestMethod.POST)
public boolean addCollProcess(#RequestBody JSONObject json){
// Code
}
// using Bean Class:
#RequestMapping(value="/addCollProcess.do", method=RequestMethod.POST)
public #ResponseBody boolean addCollProcess(#RequestBody AdmissionProcessBean processBean) {
// Code
}

spring mvc transport json to object

I am trying to post a json using ajax to my spring mvc controller I am using code like this in my js file:
$('#regist').click(function () {
$.ajax({
url: 'user/regist',
contentType: "application/json; charset=utf-8",
type: 'post',
dataType: 'json',
success: function (data) {
var json = JSON.stringify(data);
alert(json);
},
fail: function (errMsg) {
alert(errMsg);
},
data: JSON.stringify({
'IDCard': '1234567890'
})
})
});
the signature of my controller function is like this:
#RequestMapping(value = "/regist", method = RequestMethod.POST)
#ResponseBody
public ResultJson regist(HttpSession session, #RequestBody RegistFormJson json)
the RegistFormJson goes like this:
public class RegistFormJson {
private String IDCard;
public String getIDCard() {
return IDCard;
}
public void setiDCard(String IDCard) {
this.IDCard = IDCard;
}
}
now when I send my request, and what I get from my controller using
logger.info(json.getIDCard);
is null.When I change my bean propertity to idCard and change my other code as well ,I can get the result successfully. Who can tell me why ? And If I want to use IDCard in my code, how can I get the result .Thanks
Spring comes with Jackson API which uses Standard Java Code Convention to map JSON properties to Java models.
Since IDCard is not in lower camel case, Jackson API is not able to map the JSON property.
To overcome this you need to specify a #JsonProperty("IDCard") annotation on a Java attribute in order to use IDCard for your JSON property.
Likewise, you can set the PropertyNamingStrategy on the ObjectMapper to overcome this issue.

AngularJS consumes JAX-RS rest web service

This is the first time that I am using a Java back-end for my web application. I have a Jax-rs webservice that I am trying to consumes with my AngularJS app
AngularJS call
$http({
url : REST_END_POINT + '/checkuser',
method : "GET",
data : {
'userId' : credentials.username,
'pwd' : credentials.password
},
dataType : "json",
headers : {
"Content-Type" : "application/json"
}
});
Webservice
#GET
#Produces("application/json")
#Consumes("application/json")
#Path("checkuser/")
public string getCheckUser(#QueryParam("userId") String userId, #QueryParam("pwd") String pwd){
try{
if(port != null){
boolean result = port.checkUser(userId, pwd);
return new java.lang.Boolean(result).toString();
}
}catch(Exception ex){
//TODO
}
return null;
}
Both userId and pwd are always null
With Firebug I can see that data contains
Object{
userId="aaa",
pwd="aa"
}
I also tried with JSON.stringify which send those data :
"{"userId":"aaa","pwd":"aa"}"
I believe that the way you are trying to access your userID and pwd is incorrect, you are using the #QueryParam which would look for the userID and pwd as query parameters of the GET request like so:
http://myservice:port/checkuser?userId=myuserid&pwd=pass
if you change your GET request to
$http({
url : REST_END_POINT + '/checkuser',
method : "GET",
params : {
'userId' : credentials.username,
'pwd' : credentials.password
},
dataType : "json",
headers : {
"Content-Type" : "application/json"
}
});
Then you should have more luck.
However I wouldn't advise this method as it could be insecure. I'd instead look at trying to utilize an existing authentication system rather than rolling your own as these existing authentication systems will be far more secure.
You can use Jackson api for converting json to/ from Java objects.
Jackson contains simple mapper methods to implicitly map your json properties to Java class member variables.
Instead of #querypram use a Java class having fields as userId and pwd

Spring REST webservice with JSON param to be consumed using Jquery AJAX

I am trying to learn Spring Framework for creating RESTful web service for my future projects. So far I have tried using GET and consume it with no problem using a simple Ajax request. I have also tried using query strings to input parameters.
As of now I am trying to create an endpoint that receives a POST request. I've been researching for some days now but to no avail (some tuts are too complicated for a beginner like me).
Here is my simple code:
Java Spring
#RequestMapping(value = "/test", method = RequestMethod.POST)
#ResponseBody
public String testString(String jsonString)
{
System.out.println(jsonString);
return jsonString;
}
Ajax
var data = {"name":"John Doe"}
$.ajax({
url: "http://localhost:8080/springrestexample/test",
method:"POST",
data:data,
dataType:'text',
success: function( data ) {
alert(data);
},
error: function( xhr, status, errorThrown ) {
alert("Error:" + errorThrown + status);
}
});
I have tried debugging tomcat and it seems like I am not passing any value on the testString. Do I need to add something on my java code?
#RequestMapping only maps your method to some url.
To access data you need #RequestParam annotation to get data, eg:
#RequestMapping(value = "/test", method = RequestMethod.POST)
#ResponseBody
public String testString(#RequestParam("name") String jsonString)
{
System.out.println(jsonString);
return jsonString;
}
Look at this manual for more examples.
Since you are passing data into body from your ajax request, so you need to retrieve from the
#RequestBody
Add this annotation before the arguments like this way;
public String testString(#RequestBody String jsonString) {
System.out.println(jsonString);
return jsonString;
}
And you are done :)

How to correctly handle this AJAX request that send an array to a Spring MVC controller method? Why it can't work?

I am pretty new in Spring MVC and I have the following problem trying to handle an AJAX request that send an array of int to a controller method.
So I have the following situation. I have this JQuery function:
// It is global and it is initiazilized by another function:
var checkedRowList = new Array();
// SOME OTHER CODE THAT INIZIALIZED THE checkedRowList array here
...............................................
...............................................
...............................................
$('#validaButton').click(function() {
alert("validazione");
alert("CHECKED ROWS: " + checkedRowList.length);
alert(checkedRowList[0]);
$.ajax({
type: "POST",
data: {'checkedRowList' : checkedRowList},
url: "validaProgetti"
}).done(function(response) {
alert("SUCCESS");
}).error(function(xhr) {
alert("ERROR");
manageError(xhr);
});
});
So the checkedRowList is correctly initizialized (I checked it) and I use the ajax() function to send it toward the validaProgetti resource using a POST request.
Then into a controller class I have this method that have to handle the previous request:
#RequestMapping(value = "validaProgetti", method=RequestMethod.POST)
public String validaProgetti(#RequestParam List<Integer> checkedRowList, Model model, HttpServletRequest request) {
System.out.println("Numero progetti da validare: " + checkedRowList);
return "blablabla";
}
As you can see it handle HTTP Post request toward the validaProgetti resource. And Inside it I have specify the RequestParam List checkedRowList to retry the array passed by the AJAX request.
But it don't work because when the AJAX request is performed it don't enter into the validaProgetti() method and it shown the alert("SUCCESS"); popup.
Why? What am I missing? How can I fix this situation?
as I see you missed two things.
The first one is that in the Spring Web MVC controller. You don't pass a RequestParam but RequestBody.
#RequestMapping(value = "validaProgetti", method=RequestMethod.POST)
public #ResponseBody String validaProgetti(#RequestBody List<Integer> checkedRowList) {
System.out.println("Numero progetti da validare: " + checkedRowList);
return "blablabla";
}
The second one is related with your Ajax request. You should send javascript array formatted as JSON. This is done via the function JSON.stringify(), which converts js value into json.
$('#validaButton').click(function() {
alert("validazione");
alert("CHECKED ROWS: " + checkedRowList.length);
alert(checkedRowList[0]);
$.ajax({
type: "POST",
data: JSON.stringify(checkedRowList),
url: "validaProgetti",
contentType:"application/json"
}).done(function(response) {
alert("SUCCESS");
}).error(function(xhr) {
alert("ERROR");
manageError(xhr);
});
});
Also you may change the request mapping when defining in java code. Since it is a relative path, it would be confusing in some cases.
#RequestMapping(value = "/validaProgetti", method=RequestMethod.POST)
public #ResponseBody String validaProgetti(#RequestBody List<Integer> checkedRowList) {
System.out.println("Numero progetti da validare: " + checkedRowList);
return "blablabla";
}

Categories