I have the following which works well in receiving a non-empty Array,
$.ajax({
url: "ajaxController",
dataType: "json",
type: "get",
data: {
'term': request.term,
'exclude': ["45","66"]
},
Controller (note the [] in RequestParam Value -- the result goes in a String[]):
public List<KeyValueBean> getChoices(String term,
#RequestParam(value = "exclude[]")
String[] exclude) {
}
But if I pass an empty array in the same code, which sometimes happens, it breaks:
'exclude': []
or alternatively
'exclude': JSON.stringify([])
Error:
org.springframework.web.bind.MissingServletRequestParameterException: Required
String[] parameter 'exclude[]' is not present
If you pay attention to the error, it says your request parameter exclude can not be null. If you need to can send empty array sometimes, you can mark your parameter as optional(not required) in this way:
#RequestParam(required = false, value = "exclude[]")
The problem is probably because you passed your #RequestParam with value="exclude[]" while you are passing the object named as "exclude".
So, it actually should be:
public List<KeyValueBean> getChoices(String term,
#RequestParam(value = "exclude")
String[] exclude) {
}
Related
I have the below code as my restful service operation.
#GET
#UnitOfWork
#Timed(name = "get-requests")
#Path("/{referenceId}")
public Response get(#Auth #ApiParam(access = "internal") UserPrincipal user,
#ApiParam(name = "id", value = "reference ID", required = true)
#PathParam("referenceId") String id) {
return Response.ok(id).build();
}
However, I noticed if I pass in m1234;5678, I get only m1234 returned. I tried #Path("/{referenceId:.*}"), but it doesn't work.
I also tried use #Encode at the top of the method to make sure the url is not decoded and then try to replace %3B with ";" in the code. But it seems not working also.
Please note that I cannot use Spring framework. Thanks.
The ; denotes a matrix parameter. Use #MatrixParam to get its value.
See also the answers to this question: URL matrix parameters vs. request parameters
Edit: The key of the matrix parameter would be 5678, the value would be null.
There is a way to get achieve what you want by using PathSegment as the type of the parameter instead of String:
#PathParam("referenceId) PathSegment id
In the body of the method, you can use
String idValue = id.getPath();
to get m1234;5678.
I have an endpoint I created using spring.io. My GetMapping declaration can be seen below
#ApiOperation(
value = "Returns a pageable list of CustomerInvoiceProducts for an array of CustomerInvoices.",
notes = "Must be authenticated.")
#EmptyNotFound
#GetMapping({
"customers/{customerId}/getProductsForInvoices/{invoiceIds}"
})
public Page<CustomerInvoiceProduct> getProductsForInvoices(
#PathVariable(required = false) Long customerId,
#PathVariable String[] invoiceIds,
Pageable pageInfo) {
//Do something fun here
for (string i: invoiceIds){
//invoiceIds is always empty
}
}
Here is how I am calling the url from postman and passing the data.
http://localhost:8030/api/v1/customers/4499/getProductsForInvoices/invoiceIds/
{
"invoiceIds": [
"123456",
"234566",
"343939"
]
}
My string array for invoiceIds is always empty in the for loop Nothing gets passed to the array. What am I doing wrong?
The mapping you are using is this:
customers/{customerId}/getProductsForInvoices/{invoiceIds}
Both customerId and invoiceIds are Path variables here.
http://localhost:8030/api/v1/customers/4499/getProductsForInvoices/invoiceIds/
The call you are making contains customerId but no invoiceIds. Either you can pass the list in place of invoiceIds as String and read it as a String and then create a List by breaking up the List - which will be a bad practice.
Other way is to change your path variable - invoiceId to RequestBody.
Generally, Path Variables are used for single id or say navigating through some structured data. When you want to deal in a group of ids, the recommended practice would be to pass them as RequestBody in a Post method call rather than a Get method call.
Sample code snippet for REST API (post calls):
Here, say you are trying to pass Employee object to the POST call, the REST API will look like something below
#PostMapping("/employees")
Employee newEmployee(#RequestBody Employee newEmployee) {
//.. perform some operation on newEmployee
}
This link will give you a better understanding of using RequestBody and PathVariables -
https://javarevisited.blogspot.com/2017/10/differences-between-requestparam-and-pathvariable-annotations-spring-mvc.html
https://spring.io/guides/tutorials/rest/
I have the following Java REST method I implemented using Jersey:
#POST
#Path("copy")
public List<Integer> copyCompanionTextRule(#QueryParam("ruleid") List<Integer> ruleIdList,
#QueryParam("workgroupid") List<WorkgroupId> workgroupIds,
#Context HttpHeaders hh)
throws ETMSException
{
List<Integer> insertedItems = new ArrayList<Integer>();
if ( null != ruleIdList ){
for(Integer ruleId : ruleIdList) {
insertedItems.addAll(copyCompanionTextRule(ruleId, workgroupIds));
}
}
return insertedItems;
}
It receives a list of integer and a list of objects of type WorkgroupId as well as the context for some extra processing I'll do later.
I'm working the client with Sencha EXTJS 4.2 and my request is being performed this way:
Ext.Ajax.request({
url: '/sysadmin/companiontextrules/copy',
method: 'POST',
showException: true,
scope: this,
params: {
ruleid: Ext.encode(ruleIdsArray),
workgroupid: toWorkgroups
},
callback: function(options, success, response) {
me.setLoading(false);
if (!success) {
return;
}
this.destroy();
}
});
The ruleIdsArray is just an array of integers: [1274,1292,1745].
The toWorkgroups is an array of objects which has a model that is related to the WorkgroupId entity.
As you can see, both lists are being processed as query parameters and I'm using the "params" config in the Ajax request; however, this is not working.
Seems like the ruleId array is empty, when it tries to iterate the rulesIdList is empty so the method POST works but it is returning always an empty list.
I know I cannot use them in the form "url?ruleid=a&workgroupid=b". When I tried it just by curiosity, I got a QueryParamException and NumberFormatException saying that the rule array is being considered as string.
When I use the "Ext.encode" for both params I receive a message in browser console that the Maximum callstack size exceeded.
This is what I got from Chrome Console:
I've tried almost everything, but maybe some more eyes can help me in this, I'd really appreciate comments or any kind of help.
Thanks in advance.
Looks like your parameters are going in the POST body instead of as query parameters.
url?ruleid=a&workgroupid=b is getting a NumberFormatException because ruleId is supposed to be Integer.
url?ruleid=1&workgroupid=b or url?ruleid=1&ruleid=2&workgroupid=b should work
I am passing two variables in ajax call, one as normal string variable and other one js array object which i m sending to my java class..but when i m sending with array object,the ajax call is getting failed and throwing 500 response code with illegal argument exception
var array1 = new Array();
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
array1.push($(inputs[i]).attr('name').toString());
}
var path = "javaclassurl";
$.ajax({
type: "POST",
url: path,
data: {
var1: var1,
array1: array1
},
});
$(this).dialog("close");
//}
},
This is the way i m receiving in my java class
String values[]=request.getParameterValues("array1");
This ajax call is inside dialog box as its a dialog box plugin being used.Please help me in getting the error corrected
Could you please try doing it this way:
String values[]=request.getParameterValues("array1[]");
jQuery API documentation for .ajax() call states:
processData (default: true)
Type: Boolean
By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded". If you want to send a DOMDocument, or other non-processed data, set this option to false.
So you might try setting this to false.
I am wondering how spring split each parameters of a http request.
By example i have this method definition :
#RequestMapping(value = "/search.do", method = RequestMethod.GET)
public String searchGet(ModelMap model,
#RequestParam(value = "memberId", required = false) Integer memberId,
#RequestParam(value = "member", required = false) String member) {...}
and i use this url :
/search.do?member=T&O=
i get member = T and not member =T&O=
The request params are limited to only memberId and member.
Can i configure spring for solving this problem ?
Some characters in URLs have a special meaning. If they are supposed to be part of a value they need to be escaped.
If your value is T&O= then it needs to be changed to T%26O%3D
Looking at your controller code, your URL should have been
/search.do?memberId=T&member=
Then request parameter names will get mapped correctly.
If you wish to use same URL as mentioned in your question, change controller code to :
public String searchGet(ModelMap model,
#RequestParam(value = "O", required = false) Integer memberId,
#RequestParam(value = "member", required = false) String member) {...}
& is used to seperate request parameters.
URL contain request param name and value in following format
http://host_port_and_url?name1=value1&name2=value2&so_on
In your case
/search.do?member=T&O=
Name -> Value
member -> T
O -> (No value- Blank)
So you are getting correct values