Pass multiple JSON objects from client to server using jQuery and JAVA - java

I would like to ask about how to pass the multiple JSON object from Client to Server side. At first, I got the JSON object from 3rd Party API. After that, I want to pass them to Java method on the Server side. This is what I have tried but it is not success
on Client side (JSP)
function getInfo(InkBlob){
var myInkBlob = JSON.stringify(InkBlob);
jQuery.ajax({
type: 'POST',
url: '/webapp/filepicker/importAssets',
dataType: 'json',
data: {"inkBlob": myInkBlob}
});}
jQuery POST the data as
If I don't use JSON.stringify, the result will be like,
This is the method that Response for the incoming data
#RequestMapping(value = "/importAssets", method = RequestMethod.POST)
#ResponseBody
public void importAssets2(String[] inkBlob) throws Exception {
System.out.println(inkBlob); // print as [Ljava.lang.String;#56bdbbec (and another 2 similar)
System.out.println(inkBlob.length); // print as 15}
I want to use the data inside the object. For example, if I want to get the URL of the first object. I want to just inkBlob[0].URL. And the expected length of the inkBlob in this example should be 3 because only 3 object pass to the method. How can I achieve that???

Spring provides way to pass on a complete bean submitted from the form
Try using this :
Here InkBlob is a bean containing variable names and types exactly same as getting passed in post request.
#RequestMapping(value = "/importAssets", method = RequestMethod.POST)
#ResponseBody
public void importAssets2(#ModelAttribute(inkBlob) InkBlob inkBlob) throws Exception {
............Other code
}

Sample code for client
<form:hidden path="fileName" value="xxxx"/>
<input type = "hidden" name = "isWritable" value = "yyyyy"/>
<input type = "hidden" name="mimeType" value="zzzzz"/>
............
</form:form>
And on Server Side Handle it like this :
#RequestMapping(value = "/importAssets", method = RequestMethod.POST) #ResponseBody
public void importAssets2(#ModelAttribute("inkBlob") InkBlob inkBlob) throws Exception {
............Other code }
Where InkBlob should be like this :
public class InkBlob implements Serializable {
private static final long serialVersionUID = 15463435L;
String fileName;
String isWritable;
String mimeType;
......
public void setFileName(String fileName){
this.fileName = fileName;
}
.... Other Getters and settters.
}

Related

How to take LIST input in #RequestParam in Spring MVC?

Heyy,
I want to take a list of data in my request param,here "personIdCollection" is a set of list but when i am hitting through postman i am getting a bad request.
Here is my code.
controller
#PostMapping("/face-tag-data")
public String getFaceTaggedData(#RequestParam String projectId,#RequestParam List<String> personIdCollection) {
return null;
}
and here is my ajax
var data = {};
data.personIdCollection = personIdCollection;
data.projectId = $("#projectId").val();
$.ajax({
type:'POST',
url:contextPath+'/face-tag-data',
data:data,
success:function(resp){
console.log(resp);
},
failure:function(resp){
console.log(resp);
}
});
This is working for me. I do not use an ajax-request but instead submit my form directly but it should work either way.
My controller looks like:
#RequestMapping(value="addSingleArticles", method=RequestMethod.POST)
public #ResponseBody String addSingleArticles(
ArticleSubmitData pupilPackageData,
HttpServletRequest request) {
... // do something with the data
}
As you can see I have defined my own composite type which consists of three lists. So you obviously can use it with only one list directly.
public class ArticleSubmitData {
private List<Article> singleArticles;
private List<Article> packageArticle;
private List<Article> popupArticles;
... // getter & setter, inner classes etc.
}
In my server page oder faclet I use the following html-code to make this work
...
<input id="" class="" type="text" name="singleArticles[${line.index}].engraving" />
...
So the trick is to define the variables on your webpage as an array and use this in your controller as a list. As you can see in my example I also use an inner class in my composite class which has extra attributes.

Convert json object to java object

I have a request like that:
let jsonData= {};
jsonData["className"]= className;
jsonData["models"]= arr;
let endPoint= "/classses?classAndModel=" + encodeURIComponent(JSON.stringfy(jsonData));
return $.ajax({
url: host + endPoint,
data: data,
cache: false,
contentType: false,
processData: false,
method: "POST"
});
I want to convert that json to java object.I tried this one
My rest service is:
#PostMapping(value=/classes",consumes=MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Void> addClassAndModelMapping(ClassAndModels classAndModels){
}
public class ClassAndModels {
ClassAndModelResult classAndModel;
...getter and setter...
}
public ClassAndModelResult {
String className;
List<String> models;
...getter and setters...
}
I get 400 error.If I change that line ClassAndModelResult classAndModel to String classAndResult.I get response but I want Object type.Do you have any idea?
The first part of code shows that you are sending data as a query string.
Take a look at https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html
But considering the #PostMapping, you should send that data in the request body and do something like this on the server side.
#PostMapping("/classes")
public ResponseEntity<Void> addClassAndModelMapping(#RequestBody ClassAndModels classAndModels){
//
}
As Phils says, you can add a GetMapping on your controller to see how your ClassAndModels its being serialized
Source: https://spring.io/guides/tutorials/bookmarks/
P.S. Sorry about my english, I'm not a native speaker.
Please try to add #RequestParam annotation or better use classAndModel value as RequestBody similar to the below.And also correct the spelling mistake in the javascript url.
#PostMapping(value = "/classes")
public ResponseEntity<Void> addClassAndModelMapping(#RequestBody ClassAndModels modal) {
}

How to send Integer value in the form of JSON format and recieve in REST Controller?

I have one REST Controller where I have written this code
#PostMapping(value = "/otp")
public void otp(#RequestBody Integer mobile) {
System.out.println(" Mobile = "+mobile);
}
And I am calling this method from Postman with the following inputs
URL : localhost:8080/otp
Body :
{
"mobile":123456
}
But I am getting the following exception
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Can not deserialize instance of java.lang.Integer out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.Integer out of START_OBJECT token
If I am taking String as a parameter like this
#PostMapping(value = "/otp")
public void otp(#RequestBody String mobile) {
System.out.println(" Mobile = "+mobile);
}
And passing the inputs as
{
"mobile":123456
}
Now it is printing in the console as follows
Mobile = {
"mobile":"123456"
}
But I want only this value 123456. How to achieve my requirement?
NOTE: I don't want to create any additional POJO class or even I don't want to send the data using query/path parameter.
If you want to send your body like:
{
"mobile":123456
}
You will create another object to receive the value.
But if you only want to accept the integer value without any other object, you will not put json object in request body, but only the integer itself.
Body:
12345
You can use a class as request body:
class Request {
public Integer mobile;
}
and specify the parameter like this:
public void otp(#RequestBody Request mobile) {
...
Create a pojo class like below.
public class Mobile{
private Integer mobile;
//getter and setter
}
And then
public void otp(#RequestBody Mobile mobile)
to print value use
mobile.getMobile();
Converting process with json and #RequestBody is automatically and need you provide a class which contains proper field.If you insist to send data by request body,you could use String to receive json data as String.For example:
public void test(#RequestBody String request){
log.info(request);
}
In this way the request body you received is a String.You need some other tool to help you convert it.Like org.json,you could get more info from here HttpServletRequest get JSON POST data
But the easiest way is creating a new class to receive the data or changing #RequestBody to #RequestParam or #Pathvariable.
If you still want to use json as the request body,maybe you could create a common class A which contain lots of fields like name,phone number,email...Then after you send a request which only contains mobile,you just need to A.getMobile().In this way, even you get 100 request,you still need one POJO(but not recommend)
Just send the number in JSON.
12345
use #RequestBody to receive the int number.
it will work.
I use postman to send it in RAW JSON.
BTW, I am a beginner learning Spring Boot.
if you have org.json.JSONObject
#PostMapping(value = "/otp")
public void otp(#RequestBody String mobile) {
JSONObject obj = new JSONObejct(mobile);
System.out.print(obj.getInt("mobile"));
}

Correct way to put parameters in a function

I have a huge form with around 30 parameters and I don't think it's a good idea to do what I usually do.
The form will be serialized and pass all the parameters via ajax post to spring controller.
I usually do like this:
#RequestMapping(value = "/save-state", method = RequestMethod.POST)
public #ResponseBody
void deleteEnvironment(#RequestParam("environmentName") String environmentName, #RequestParam("imageTag") String imageTag) {
//code
}
but if I have 30 parameters I will have a huge parameter list in the function.
What is the usual and correct way to avoid this?
EDIT: What if I pass the HttpServlet request only?? The request will have all the parameters and I can simple call request.getParameters("").
There are two options I would suggest:
Take an HttpServletRequest object and fetch needed properties separately.
The problem is Spring's controllers are designed to eliminate such low-level API (Servlets API) calls. It's could be the right fit if a controller was too abstract (operates on abstract datasets), which means you wouldn't be able to define a DTO with a fixed-length number of parameters.
Construct a DTO class with the properties needed and take it as a parameter.
The advantage is you completely delegate low-level work to Spring and care only about your application logic.
You can do something like this:
#RequestMapping(value = "/save-state", method = RequestMethod.POST)
public void deleteEnvironment(#RequestBody MyData data) {
//code
}
Create a class containing all your form parameters and receive that on your method.
but if I have 30 parameters I will have a huge parameter list in the
function.
In your request, pass a JSON object that contains these information and create its counterpart in Java.
RequestMethod.POST is not design to perform deletion.
Usr rather RequestMethod.DELETE.
#RequestMapping(value = "/save-state", method = RequestMethod.DELETE)
public #ResponseBody
void deleteEnvironment(MyObject myObject) {
//code
}
Correct way is to serialize all parameters as Json and call back end api with one parameter.
On back-end side get that json and parse as objects.
Example:
` #RequestMapping(method = POST, path = "/task")
public Task postTasks(#RequestBody String json,
#RequestParam(value = "sessionId", defaultValue = "-1") Long sessionId)
throws IOException, AuthorizationException {
Task task = objectMapper.readValue(json, Task.class);
`

How to re-write request URI along with path variable in Spring?

I'm using Spring 4 right now and I have a controller defined a such:
#RequestMapping(value = "/{id}/definitions", method = RequestMethod.PUT)
#ResponseBody
public List<ResponseDTO> update(#PathVariable(value = "id") String id,
HttpServletRequest iRequest) throws Exception
{ ... }
I am expecting to receive an encrypted 'id' String coming as part of a path variable in the request itself. But what I need to do is re-write this request URI and decrypt it to another value (an integer, for example) and form another HTTP request with the original URI only with the transformed/decrypted value.
How can I get a hold of the entire URI and substitute the {id} with an integer?
For example, if the original request coming in looks like:
http://mycompany.com/my-service/kjAISOhalkjZjakmbbb/definitions
I want to transform everything after the context path:
/kjAISOhalkjZjakmbbb/definitions
to:
/123456/definitions
So finally, I can form a request to another service that might look like this:
http://mycompany.com/my-service-2/123456/definitions
Thank you!
Decrypt the value (however you do that).
Then just use a redirect or forward (probably a forward in your case):
#RequestMapping(value = "/{id}/definitions", method = RequestMethod.PUT)
public void update(#PathVariable(value = "id") String id,
HttpServletRequest iRequest) throws Exception {
String decryptedId = //decrypt here
//Do whatever else
//either forward: or redirect:
return "forward:my-service-2/" + decryptedId + "/definitions";
}

Categories