I am writing a feign client to consume an endpoint of a PHP API.
I need to call an endpoint which is like :
www.myapp.com/number.php?number[]=1
My Feign Client looks like this:
#FeignClient(name = "testProxy", url = "${service.url}")
public interface NumberProxy {
#RequestMapping(value = INumber.URL, method = RequestMethod.GET)
public String getEvents(#RequestParam("numbers[]") Integer number);
}
The problems is number[].
If I see the feign log to check the GET URL, this is what I see.
GET [https://www.myapp.com/number.php?number[]={number[]}][1] HTTP/1.1
The number[] is not replaced by the actual value and that is what the API call is failing.
Is there a way to deal with this?
P.S.
I know that the PHP API should not have a query parameter like this, but it is what it is and I can not change that.
And I have also tried with List<Integer> for the number variable, but output is same.
Are we talking about a org.springframework.web.bind.annotation.RequestParam if so it shouldn't be the problem of square brackets. For me it works fine:
#RequestMapping(value = "/api/somepath", method = RequestMethod.POST)
public void uploadData(
#RequestPart("file") MultipartFile fileUpload, HttpServletRequest request,
HttpServletResponse response, #RequestParam(name = "param[]") Integer number) {
LOGGER.trace("paramValue=[{}]", number)
}
logs a value passed through a client
What if the problem is in parameter naming? In the first occurence you write numberS[] but further it named as number[]
You should name your parameter just as numbers without the brackets and change the type to a List:
#RequestMapping(value = INumber.URL, method = RequestMethod.GET)
public String getEvents(#RequestParam("numbers") List<Integer> number);
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 am trying to implement datatable editor with spring boot ,but the client to server data varies for create ,update and delete even not constant for create as well and depends on fields
I have implemented this till now
#RequestMapping(value="/datatabledata" , method=RequestMethod.POST)
#ResponseBody
public String datatabledata(HttpServletRequest request)
{
Enumeration<String> params = request.getParameterNames();
while(params.hasMoreElements()){
String paramName = params.nextElement();
System.out.println("Parameter Name - "+paramName+", Value - "+request.getParameter(paramName));
}
//System.out.println(data);
//System.out.println(request.);
//Map<String,String>ak=new HashMap<>();
//ak.put("data", "hello ");
return "done";
}
Above code prints following output on console for create
Parameter Name - action, Value - create
Parameter Name - data[0][username], Value - dddddd
Parameter Name - data[0][date], Value - 2018-11-28
Parameter Name - data[0][balance], Value - dddddddddd
and this for edit
Parameter Name - action, Value - edit
Parameter Name - data[5bfab595507af613f409c0c4][username], Value - four
Parameter Name - data[5bfab595507af613f409c0c4][date], Value - 2018-11-25
Parameter Name - data[5bfab595507af613f409c0c4][balance], Value - 9000.0
The only constant parameter here is action and so I can use
#RequestParam("action")
but how to get rest data ?? something like #RequestParam() String data
You can create a DTO class which can be mapped from the request and can be used further.
#RequestMapping(value="/datatabledata" , method=RequestMethod.POST)
#ResponseBody
public String datatabledata(HttpServletRequest request)
{
UserDTO object = new ObjectMapper().setDateFormat(simpleDateFormat).readValue(request.getReader(), UserDTO.class);
performYourOperation(object);
}
I see we should utilize REST in more richer way here.
So create three different controller method handlling create, update and delete and maps them to difference HTTP methods like below :
//For Create. Take the parameter as (#RequestBody List<User>)
#RequestMapping(value="/datatabledata" , method=RequestMethod.POST)
//For Update/Edit, Take the parameter as (#RequestBody List<User>)
#RequestMapping(value="/datatabledata" , method=RequestMethod.PUT)
//For Delete, Just take either list of ids or id to be delete. Nothiing else required
#RequestMapping(value="/datatabledata" , method=RequestMethod.DELETE)
Now you don't need action as parameter. Client just need to specify the correct http method.
You should use #RequestParam Map<String,String> allRequestParams in your endpoint:
#RequestMapping(value="/datatabledata" , method=RequestMethod.POST)
#ResponseBody
public String datatabledata(#RequestParam Map<String,String> allRequestParams) {
/ ... rest of your code
}
I have to similar controllers ONe get by Id and the other get By name
both using PathVariables I read an article where it explained and how to resolve by using regex but it seems not to work properly
#GetMapping(value = "/trucks/{truckId:[0-9]+}")
#ResponseStatus(HttpStatus.FOUND)
#ResponseBody
public final TruckDto getTruckId(#PathVariable(value = "truckId")
final String truckId) {
LOGGER.debug("test: truckId({})", truckId);
Truck truck = truckService.getTruckById(Integer.parseInt(truckId));
return mappingService.map(truck, TruckDto.class);
}
/**
* #return Truck with an average.
*/
#ResponseStatus(HttpStatus.FOUND)
#ResponseBody
#GetMapping(value = "/trucks/{truckCode:[a-zA-Z0-9]+}")
public final TruckWithAvgPetrolDto getTruckByTruckCode(#PathVariable(value = "truckCode")
final String truckCode) {
LOGGER.debug("test: getTruckByTruckCode({})", truckCode);
TruckWithAvgDto truck = truckService.getTruckByTruckCode(truckCode);
return mappingService.map(truck, TruckWithAvgPetrolDto.class);
}
WIthout putting regex both of fail my test but after putting regex the method getTruckByTruckCode that accepts numbers and letters pass but get by truckId still gives the error ambigous handler method , Am i missing something or why isnt it working
I have a REST API like this:
#RequestMapping(value = "/services/produce/{_id}", method = RequestMethod.PATCH,
consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public String patchObject(#RequestBody PatchObjectRequest obj,
#PathVariable("_id") String id) {
// some code
}
My problem is that the id that might be given is in the form:
US%2FCA%2FSF%2FPlastic
Which is a URL encoding of "US/CA/SF/Plastic".
My problem is that when a % character is put into the URL the #RequestMapping does not map it to this method and it will return a 404. Is there a way to accept ids that have % character in them as part of the URL?
You are receiving this error because using it as path variable it is decoded and then server tries to match it to a path that doesn't exits. Similar questions where posted a few years ago: How to match a Spring #RequestMapping having a #pathVariable containing "/"?, urlencoded Forward slash is breaking URL.
A good option for you would be to change _id from #PathVariable to #RequestParam and problem solved, and remove it from path.
Hope you can add regex in the path variable like:
#RequestMapping(value = "/services/produce/{_id:.+}",
method = RequestMethod.PATCH,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
In my test application I have a controller with the following method:
#RequestMapping(value = "/{city}", method = RequestMethod.GET)
public #ResponseBody
MyAnwser getAnwser(#PathVariable String city) {
return new MyAnwser(city);
}
which returns the following
{"result":{"valueA":"valueB"}}
I'm looking for a way to remove the first object sign from the response - "{" to get:
"result":{"valueA":"valueB"}
but I can't figure out a way to do it while using #ResponseBody
If you do that, you wouldn't end up with a valid JSON! In other words, you can't mustn't do that.
As you want to Remove First And Last Character of your Received String Then use
String str="your Received String goes here";
str=str.substring(1, str.length()-1)