How to accept 2D arrays in Spring MVC controller? - java

I'm making a POST request via jQuery Ajax:
$.ajax({
type: "POST",
url: opts.save_url,
data: $(ul_obj).serializeFormList() + "&form_id=" + form_db_id,
});
The $(ul_obj).serializeFormList() creates a 2D array of request params.
Here's the screengrab of the params passed to the Spring MVC controller:
Now when I handle this in the Controller I get 404 Bad Request for frmb[][]
Here's the code:
public #ResponseBody String saveData(#RequestParam(value= "form_id", required = true) String formId,
#RequestParam(value= "frmb", required = true) String[][] formArray) {
//Content removed for brevity
}
What is the exact way to handle this request data? Please guide me. I'm stuck real bad.

As I see you are concatenating the parameters
"&form_id=" + form_db_id
you can do the same for "frmb"
frmb=1,2&frmb=2,3
so when you try get the String [][] using
#RequestParam(value= "frmb", required = true) String[][] formArray)
you will get
formArray = [[1,2],[2,3]]

Java has only index (integer) based Arrays:
So either you make your request using only integer based arrays:
form_Id
frmb[0][0] input_text
frmb[0][1] required
frmb[0][values] sdfsfds
or you use an other structure to fetch the data: For example an Array containing a Map
#RequestParam(value= "frmb", required = true) Map<String,String>[] formArray
If you are able to modify the sended json, then I would recommend to use a JavaBean instead of the Map

Related

Unable to pass Array from Angular 2 typescript to Spring Java

I am trying to pass a String array from my typescript
tmp : Array<string> = [];
So I have a function which takes in this array as a parameter input
passValues(test : Array<string>) {
........
// some method to call post method from service
}
So in service
public passingOfValues( test : Array<string> ) : Observable<Array<string>> {
let headers = new Headers({ 'Content-Type': 'application/json'} );
let options = new RequestOptions({ headers: headers);
let response = this.http.post(this.basePath + this.modulePath + '/getArrayValue', {'test' : test }, options)
.map(this.extractData)
.catch(this.handleError);
return response;
}
But I am getting errors such as System property [org.owasp.esapi.devteam] is not set
And I read on other posts that I have to stringify the array before passing to backend.
Is there a reason why I need to stringify / also can I just pass the raw array?
EDIT 1 :
including backend controller codes
public ResponseEntity<?> getArrayValues( ArrayList<String> test ) {
logger.debug("### Test if array has a size ###" + test.size());
}
Apparently size already shows 0 from here.
EDIT 2 :
While debugging, i realised that the SQL at the back is receiving
say
HOME CHARACTER(20 OCTETS)
does this make any difference?
Like passing of string into octets or do I have to do some conversion?
Sorry if I have alot of questions am also working hard on debugging and learning more about it!
Most of the developers like JSON data as request and it's good practice in RESTful apis. why?
JSON format is {key1: value1, key2: value 2,....}
You are passing
this.http.post(this.basePath + this.modulePath + '/getArrayValue',{'test' : YOUR_ACTUAL_ARRAY})
form the front-end. The httpClient.post(url,body,options?) has url and body as mandatory. How can you get it in back-end? Since you have body only,
public ResponseEntity<?> getArrayValues(#RequestBody List<String> test) {
// codes
}
Key of passed parameter from front-end test and variable which
listens in back-end should be in same name. Otherwise
#RequestBody("KEY_NAME") List<String> any_variable
As you asked from comment, you may have two key value pairs. Eg : { "test" : value1, "tmp": value2}. Assume value1 and value2 both are String array.
this.http.post(this.basePath + this.modulePath + '/getArrayValue',{'myJson' : YOUR_JSON})
There are lot of way(Eg : Gson,ObjectMapper etc). I use another way.
Create a class called TestTmpConverter
class TestTmpConverter{
List<String> test;
List<String> tmp;
//No-argument constructors & Argument constructors
//Getters
}
In controller
public ResponseEntity<?> getArrayValues(#RequestBody List<TestTmpConverter> myJson ) {
List<TestTmpConverter> test=myJson.getTest();
List<TestTmpConverter> tmp=myJson.getTmp();
// Do your work
}
I only showed one way.There are a lot of way to pass data to back-end like #RequestParam, #PathVariable etc. I feel now you get something how you can pass the data.
For your client put your data directly on POST's body:
public passingOfValues( test : Array<string> ) : Observable<Array<string>> {
let headers = new Headers({ 'Content-Type': 'application/json'} );
let options = new RequestOptions({ headers: headers);
let response = this.http.post(this.basePath + this.modulePath + '/getArrayValue',
test, options)
.map(this.extractData)
.catch(this.handleError);
return response;
}
On your REST service use the #RequestBody annotation:
public ResponseEntity<?> getArrayValues(#RequestBody String[] test ) {
logger.debug("### Test if array has a size ###" + test.size());
}

How to convert JSON response to Java List- Using Rest Assured for API Testing

I have a nested JSON response. JsonResponse Screenshot
I want to get the the dictionary at 0th location from the list and then get a particular element from it.
For e.g. In response, {0} and {1}, I want to get complete {0} as a result. Then from {0}, I want to extract "Id" value only.
I don't want to use the JsonPath.read(JsonResponse String, JSON Path) everytime. So looking for some simple and better alternative.
How to convert JSON response to Java List. Below is the response.
Response resp = given().header("Authorization", "Bearer "+"dwded").
accept(ContentType.JSON).
when().
get("https://example.com");
return resp;
For testing a web-API or REST endpoint, I would recommend Karate.
So it becomes simple:
* def id = response[0].Id
In the swagger editor pet example.
responses:
200:
description: "successful operation"
schema:
type: "array"
items:
$ref: "#/definitions/Pet"
A model is generated from the
Pet:
type: "object"
properties:
name:
type: "string"
example: "doggie"
This generated a java class
public class Pet {
#JsonProperty("name")
private String name = null;
The api shows a REST that returns an entity that can be shown as an array of json objects
ResponseEntity<List<Pet>> findPetsByStatus( #NotNull#ApiParam(value = "Status values that need to be considered for filter", required = true, allowableValues = "available, pending, sold") #RequestParam(value = "status", required = true) List<String> status);

How to extract parameters from an object to show in parameters in documentation

I have the following API endpoint:
#ApiResponses(
value = {
#ApiResponse(code = 200, message = "OK",
responseHeaders = {
#ResponseHeader(name = "X-RateLimit-Limit", description = "The defined maximum number of requests available to the consumer for this API.", response = Integer.class),
#ResponseHeader(name = "X-RateLimit-Remaining", description = "The number of calls remaining before the limit is enforced and requests are bounced.", response = Integer.class),
#ResponseHeader(name = "X-RateLimit-Reset", description = "The time, in seconds, until the limit expires and another request will be allowed in. This header will only be present if the limit is being enforced.", response = Integer.class)
}
)
}
)
#ApiOperation(httpMethod = "GET", hidden = false, nickname = "Get Network Availability in JSON", value = "Get network availability for a product", response = AvailableToPromise.class, position = 1)
#RequestMapping(value = "/{product_id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> networkAvailabilityJsonResponse(
#RequestHeader HttpHeaders headers,
#PathVariable("product_id") String productId,
#Valid NetworkAvailabilityCmd cmd, //query params
BindingResult result)
throws Exception {}
}
Certain parameters, such as key are taken from the query and mapped into this object through Spring MVC.
However, in the parameters section of my endpoint in the swagger-ui, it's showing me a few odd things:
None of the variables that are in NetworkAvailabilityCmd show in this parameters list, and cmd itself shows as being located in the request body (it's actually located in the query). Is there a way to hide cmd and extract the params inside this object to show on the params list? I'd like the params list to look like this (with more params):
I'm able to do this if I use #ApiImplicitParams on the method endpoint, and write out each of the params. However, this NetworkAvailabilityCmd is used for many endpoints, and having the list of params on each endpoint is very messy. Being able to extract the variables from in the object would be far cleaner, and would prevent people from forgetting to add the entire list to new endpoints.
I imagine that it requires an annotation on NetworkAvailabilityCmd cmd, and potentially something on the variables in that class, but I can't seem to find what I'm looking for in the docs.
Thanks!
I found out that adding #ModelAttribute worked magically. This annotation is from Spring.

How to share information between Spring controller methods from GET and POST requests?

I'm new to Spring and I want to:
1) when an user visits localhost/admin/users I want the predefined options to apply
2) On localhost/admin/users I have some buttons that perform a POST with four parameters because my boss don't want me to use get (and I think is better to use POST, too)
3) I have a controller method adminUsersPost that manages the POST request, and I want that method to be able to make my browser to reload using the adminUsersGet method, but with the information sent in the POST request.
What I'm getting now in my browser is an alert with a webpage content in some weird encoding, I hope it is correct but I don't know.
#RequestMapping(value = "/admin/users", method = RequestMethod.GET)
public ModelAndView adminUsersGet(
Integer page,
Integer items,
String sorting,
String sortingDirection)
{
// predefined options
Integer pagina = 1;
Integer itemsPorPagina = 10;
String ordenacion = "idUsuario";
String dirOrdenacion = "asc";
// end of predefined options
// Code that I want for it to use POST params from the other method
ModelAndView mv = new ModelAndView("adminUsers");
return mv;
}
#RequestMapping(value = "/admin/users", method = RequestMethod.POST)
public ModelAndView adminUsersPost(
#RequestParam(value = "pagina") Integer pagina,
#RequestParam(value = "itemsPorPagina") Integer itemsPorPagina,
#RequestParam(value = "ordenacion") String ordenacion,
#RequestParam(value = "dirOrdenacion") String dirOrdenacion)
{
// Here I try to pass the POST parameters to the GET method for reloading
// the webpage with the new content
return adminUsersGet(pagina, itemsPorPagina, ordenacion, dirOrdenacion);
}
The pattern POST params-->GET same parameters is a common one. What you need is RedirectAttributes which will store your parameters into the session and redirect to your GET method. Once the GET is hit spring will automatically remove all attributes from the session, thus none of the POST parameters will be displayed in the browser url in the GET method. Have a look here for a complete example and adjust it for your needs.

Retrieve path parameters with Jersey from the request object

I have a REST API call using Jersey, like this:
#GET
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.APPLICATION_JSON)
#Path("/get/{version}")
public String getData(#PathParam("version") String version, FormDataMultiPart request) {
// My code here
}
The fact is that I want both:
1) The version set into the URL (like it is now)
2) The version retrieved from the request object.
I don't want to have two separate inputs.
Is there a way I can achieve this?
Assuming you are firing a request using jQuery and AJAX, this is how you can do it:
var vesrion = <retrieve vesrion>
var requestURL = "http://required.url/" + version
$.ajax({
type : 'POST',
url : rquestURL,
cache:false,
processData:false,
contentType:false,
data : new FormData($("#"+formId)[0]) // 'formId' will be the ID of your form
}) ..
This is how you can pass both path param and form data together.

Categories

Resources