Spring Boot Rest call according to parameter - java

I have a question about the following. We want to create some Rest calls. One of the parameters of the rest calls is the return format. So the parameter return_format can have the values json or xml. Is there a smart way to use the parameter and use the service that will produce the right output format?
If the call parameter return_format == json then
#Produces({"application/json"})
if the call parameter return_format == xml then
#Produces({"application/xml"})

You don't need a parameter like return_format. This can be controlled with the Accept header.
In the controller you can add both formats:
#RequestMapping(value = "/employee", method = RequestMethod.GET,
produces = { "application/json", "application/xml" })
public <yourResponse> get(#RequestHeader("Accept") String accept) {
// Check if Accept is XML or JSON
}

Related

semicolon in the restful service URL truncate the characters after it

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.

Passing json object to an endpoint developed with spring

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/

#RequestParam name includes square brackets []

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);

Mapping to two different method in Spring controller based on header content

I have to implement the same endpoint that return different data type. I can't use versioning in the URL so just wondering how I can use header content to map request to based on header value.
For example I will be sending val1 or val2 in header say decider. And I want to have controller methods like
#RequestMapping(value = "\someUrl")
public firstReturnType someMethod() {
}
#RequestMapping(value = "\someUrl")
public secondReturnType someOtherMethod() {
}
Any suggestion?
This is the HTTP Headers list: https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
you can see that you don't have in HTTP headers that you can use to your needs or any other custom needs.
I would recommend differentiating between the 2 methods by adding HTTP verb, GET, POST, DELETE, PUT.
Or just change your URL to:
#RequestMapping(value = "/someUrl/{id}")
Or just use one method and use if statement to decide which answer to return:
#RequestMapping(value = "/someUrl")
public firstReturnType someMethod(#RequestParam("param") int param ) {
if(param == 1){
...
}
else if(param == 2){
...
}
}

Spring Controller: Passing Url As Parameter 404 Error

My controller attaches a question mark at the end of a string. It works great for every types of string.
https://www.mywebsite.com/attachQuestionmark/33 returns 33?
https://www.mywebsite.com/attachQuestionmark/hello returns hello?
However it returns not found error for urls such as https:://www.test.com.
https://www.mywebsite.com/attachQuestionmark/https:://www.test.com returns 404 error.
Is there any way to pass a full url to spring mvc controller?
#RequestMapping(
value = MyUrlBuilder.API_CREATIVE_CREATE + "/attachQuestionmark/{string}",
method = RequestMethod.GET,
produces = MediaType.ALL_VALUE)
#ResponseBody
#PMET
public static String attachQustionmark(#PathVariable("url") String value)
{
return value + "?";
}
Try URL-encoding the path variable, eg:
https://www.mywebsite.com/attachQuestionmark/https%3A%3A%2F%2Fwww.test.com
Because otherwise the / inside the variable will be interpreted as another path

Categories