Passing parameters to GET in REST - rest

I am trying to pass parameters with a GET request to a REST web service:
My class has the path defined as follows:
#Path("/ws")
public class RegistrationWS {
The method that I am calling has the path defined as:
#GET
#Produces("text/plain")
#Path("/{key}/{deviceId}")
public String getText(#QueryParam("key") String key, #QueryParam("deviceId") String deviceId) {
When I run the client, I get back the word 'failure', which is what my getText() method returns if the key was null:
// Get plain text
String registrationResponse = service.path("rest").path("ws/"+DEF+"/"+"ABC")
.accept(MediaType.TEXT_PLAIN)
.get(String.class);
Am I building the URL correctly in the client?

Related

call two different rest methods with same URI

I have two Rest URIs :
// URI n1 : GET /users/{userName}
public ResponseEntity<userDto> findUserByName(
#PathVariable( value = "userName", required = true)
String userName
);
// URI n2 : GET /users/{userID}
public ResponseEntity<userDto> findUserByID(
#PathVariable( value = "userID", required = true)
Long userID
);
When I call GET /users/SuperUser123 I want the first function to respond and when I call GET /users/1854 I want the second one respond. What really happens is that the first function is always called for both cases (as the param is always of type String).
So how can I achieve what I want while respecting REST API URI recommendations ?
It will give ambiguous mapping runtime exception as the url pattern is same for both the methods.
If your url has some pattern like starting for superuser or something then you can use regex patterns to make it work.
In below example first method method will get called if the path variable is a digit otherwise second method for alphabets.you can change regex pattern accordingly.
#RequestMapping("{id:[0-9]+}")
public String handleRequest(#PathVariable("id") String userId, Model model){
model.addAttribute("msg", "profile id: "+userId);
return "my-page";
}
#RequestMapping("{name:[a-zA-Z]+}")
public String handleRequest2 (#PathVariable("name") String deptName, Model model) {
model.addAttribute("msg", "dept name : " + deptName);
return "my-page";
}

JAX-RS Request Body Validation

We are using JAX-RS to implement a REST API for one of our projects. Requirement is that the users would pass in the request object in JSON format.
Let us assume that we have a method that is invoked on hitting an API endpoint
#POST
#PATH("/api/user")
#Produces("application/json")
#Consumes("application/json")
public CustomResponse methodA(#RequestBody UserInfo userDTO)
Sample Request Object:
{
"firstName":"Test",
"lastName":"Name",
"sno":"A123"
}
UserInfo DTO
private String firstName;
private String lastName;
private String sno;
getters and setters
Now if the user tries to add other parameters to the request object given above (for ex: "age") and invokes api endpoint, we have not been able to intercept and report the same back to the user saying "Invalid parameter age" as it seems that the request is being filtered out for invalid/unknown parameters and not reporting any error as such.
Any thoughts on how this can be addressed?
I was able to identify unrecognized properties by adding following piece of code:
Change the method signature to
public CustomResponse methodA(#RequestBody String reqObj)
and then
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
UserInfo userDTO = mapper.readValue(reqObj, UserInfo.class);
We now see a
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "<>" for any unsupported parameter

ReSTful service getting contradict due to path parameter value has forward slash

I have API like this-
/objectname/name
/objectname/collection/id
Both API's are indirectly related.
Problem occurs when calling first API with name value as "A/B Type". So rest controller actually calling second API rather first (/objectname/A/B Type) because forward slash. How to deal with this situation.
As a side note I am encoding the parameters values.
I developed the restful services using SpringBoot and RestTemplate.
The conflict comes by specifying the name directly in the resource path and passed to the function as a #PathVariable.
Your code looks something like this:
#RequestMapping(value = "objectname/{name}", method = RequestMethod.GET)
public String yourMethodName(#PathVariable String name){
return name;
}
What I would recommend in order to avoid this kind of conflict is (if you're allowed to modify the #RestController or #RepositoryRestResource layers) to pass the value of the object in a #RequestParam
For instance:
#RequestMapping(value = "/objectname", method = RequestMethod.GET)
public String yourMethodName(#RequestParam(name = "name", required = true) String name){
return name;
}
That said, When you are constructing your the request using RestTemplate then you should url encode your name (A%2FB%20Testing) and construct the following url:
http://localhost:8080/objectname?name=A%2FB%20Testing
I tested this locally and worked alright for me.

How can I specify the default MimeType returned by a REST resource with Jersey

I am creating a REST interface and have a resource 'data'. Now I want that an user can specify whether he wants the data as XML or as JSON. Therefore I have created two methods for the same path, one produces application/xml, the other produces application/json. Everything works fine, but how can I specify what should be returned, if an user doesn't set the 'Accept' header field?
My tests have shown that it is not always the same. Yesterday the default was application/xml, today my tests have failed, because as default application/json was returned.
How can I specify a default?
Code Snippet:
#GET
#Path("/rest/data")
#Produces(MediaType.APPLICATION.XML)
public Object getDataAsXML() {
// return data in XML format
}
#GET
#Path("/rest/data")
#Produces(MediaType.APPLICATION_JSON)
public Object getDataAsJSON() {
// return data in JSON format
}
Cheers,
metalhamster
#Path("/myResource")
#Produces("text/plain")// doGetAsPlainText method defaults to the MIME type of the #Produces annotation at the class level.
public class SomeResource {
#GET
public String doGetAsPlainText() {
...
}
#GET
#Produces("text/html")
public String doGetAsHtml() {
...
}
}
The doGetAsPlainText method defaults to the MIME type of the #Produces annotation at the class level. The doGetAsHtml method's #Produces annotation overrides the class-level #Produces setting, and specifies that the method can produce HTML rather than plain text.
#GET
#Produces({"application/xml", "application/json"})
public String doGetAsXmlOrJson() {
...
}
The doGetAsXmlOrJson method will get invoked if either of the media types "application/xml" and "application/json" are acceptable. If both are equally acceptable then the former will be chosen because it occurs first.
#Produce

Return raw string from REST service method

I have a REST service method written in C#, defined as below:
[WebGet(UriTemplate = "/{par1}/{par2}/{par3}")]
public string ProcessGet(string par1, string par2, string par3)
{
return Execute(...);
}
It should return result as XML or JSON, based on one parameter (I generate the json and XML serialization)
How can I make this method to return the RAW string, just as I created it, without HTMLEncoding it?
Thank you
Return it as a Stream - that causes the "raw" mode to be used and WCF will not touch your response. You can find more information at http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-web.aspx.