RESTFUL Web Service - List - web-services

I have a client application requesting a list of channels from a webservice. Is it possible to take the "response" from the web service and store it in an ArrayList?
Meaning if I wanted to store a list of channels for example, it would normally come from the web service as a response, typically from ResponseBuilder.
And I want to store it in an ArrayList from the client, like List.
How would I go about doing that?

You can use TypeReference to instantiate your Channel object list, here is an example:
import com.fasterxml.jackson.core.type.TypeReference;
public class ChannelClient {
public void getChannels() {
Response serviceResponse = client.target("http://your_service_url/channels/").
request(MediaType.APPLICATION_JSON).get(Response.class);
String responseString = serviceResponse.readEntity(String.class);
List<Channel> list = new ObjectMapper().readerFor(new TypeReference<List<Channel>>() {
}).readValue(responseString);
}
}
Make sure to have Jersey JSON Jackson jar in your dependencies, you can get it from here
https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson/2.26-b07
EDIT: In case you want to consume MediaType.TEXT_PLAIN response, you will just change the request method argument to your specified type like this:
Response serviceResponse = client.target("http://your_service_url/channels/").
request(MediaType.TEXT_PLAIN).get(Response.class);

Related

How do I map path parameters from an API Gateway API to the Request Object of a Java Lambda

I have a lambda, written in Java, that accepts a Request Object of the structure
{
"id": "be1c320a-144f-464d-b32c-38ec7fb4445b",
"userId": "foobar"
}
When I call this Lambda through the test interface with such an object, it works fine.
I want to create an API where a GET request to
/users/foobar/items/be1c320a-144f-464d-b32c-38ec7fb4445b
i.e. of the form
/users/{userId}/items/{id}
calls this Lambda.
I have created the API resources /users, {userId}, items, and {id} appropriately.
And I have created the GET method (on /users/{userId}/items/{id})and associated it to the lambda.
When I test the API, it invokes the lambda, but with null values in the request. I can see it package the path as {"id":"be1c320a-144f-464d-b32c-38ec7fb4445b","userId": "foobar"} in the logs, but that's not being sent in the body.
I have tried creating a template map (and have tried RTFM), but cannot see how to map path parameters to a body.
How do I achieve this mapping?
I think your Request Object structure may not be properly configured. There may be a few ways to configure this. Here is some information that has helped me.
How to pass a querystring or route parameter to AWS Lambda from Amazon API Gateway - Demonstrates this mapping (albeit with python). However, taking the top response, if you enable "Use Lambda Proxy integration", you can similarily do this with Java as so:
#Override
public Object handleRequest(APIGatewayProxyRequestEvent input, Context context) {
Map<String, String> pathParameters = input.getPathParameters();
String id = pathParameters.get("id");
String userId = pathParameters.get("userId");
// Handle rest of request..
}
This is a tuturial using the serverless framework to create an Api with Java. This tutorial similarily accesses the pathParameters by parsing the input rather than using the APIGatewayProxyRequestEvent java class.
#Override
public Object handleRequest(Map<String, Object> input, Context context) {
try {
// get the 'pathParameters' from input
Map<String,String> pathParameters = (Map<String,String>)input.get("pathParameters");
String id = pathParameters.get("id");
String userId = pathParameters.get("userId");
} catch (Exception ex) {
logger.error("Error in retrieving product: " + ex);
}
}
Use a mapping template.
First, in the Method Request section, you should see userId and id as Request Paths
Then, in the Integration Request, do not choose Proxy Integration.
Then in the Mapping Templates section, add a new mapping template for application/json of the form
{
"id" : "$method.request.path.id",
"userId" : "$method.request.path.user_id"
}

Get Json of a Restful service

I have a Restful service with Jersey where I return Json data, the problem is when I try to get the data with $.ajax I'm not able get it.
My Restful service is:
#Path("/RegistroJson")
public class RegistroJson {
#GET
#Path("/get/{param}/{param2}/{param3}")
#Produces(MediaType.APPLICATION_JSON)
public Usuario htmlHello(#PathParam("param") String nick,#PathParam("param2") String pass,#PathParam("param3") String email) {
Usuario u=new Usuario();
u.setPass(pass);
u.setUser(nick);
u.setEmail(email);
return u;
}
I need the json in the web but I'm not able to get it with this:
$.ajax({url: "http://localhost:8080/RestWebService/rest/RegistroJson/get/emilio/adf/asdf"})
I use that command with this service(http://rest-service.guides.spring.io/greeting) and it works correctly so I think the problem is in my rest service
Could you help me with this?
Thank you
If you go to this rest url with browser, do you receive json data? In $.json() you need to add an success action when your received data will be accessible. You can do this by adding to {} option success:function(f){ console.log(f) }

Implement CXF client to read LIST from a REST server

I am trying to implement a rest web service using Apache CXF and I want to return list of object as a response from server. So i have used generic entity to wrap my list on a server and everything is fine when I enter path from browser. It prints XML representation of object because I have used Jackson JAX-B but when i try to use JAX-RS client. I am getting an exception.
Exception in thread "main" javax.ws.rs.client.ResponseProcessingException: Problem with reading the data, class XYZ, ContentType: /.
at org.apache.cxf.jaxrs.impl.ResponseImpl.reportMessageHandlerProblem(ResponseImpl.java:433)
at org.apache.cxf.jaxrs.impl.ResponseImpl.doReadEntity(ResponseImpl.java:378)
at org.apache.cxf.jaxrs.impl.ResponseImpl.readEntity(ResponseImpl.java:325)
at org.apache.cxf.jaxrs.impl.ResponseImpl.readEntity(ResponseImpl.java:313)
at XYZ.ABC()
at XYZ.ABC()
Caused by: javax.ws.rs.core.NoContentException: Message body is empty
at org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.reportEmptyContentLength(AbstractJAXBProvider.java:276)
at org.apache.cxf.jaxrs.provider.JAXBElementProvider.readFrom(JAXBElementProvider.java:166)
at org.apache.cxf.jaxrs.utils.JAXRSUtils.readFromMessageBodyReader(JAXRSUtils.java:1325)
at org.apache.cxf.jaxrs.impl.ResponseImpl.doReadEntity(ResponseImpl.java:369)
... 4 more
I have written a following client code to get data from server
final Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target(URI.create(PATH));
Response response = webTarget.request(MediaType.APPLICATION_XML).get();
List<ABC> obj = response.readEntity(new GenericType<List<ABC>> (ABC.class){});
But Apart from it I have tried many code to implement CXF client and get data from server but I am getting a same exception almost all the time. I have tried JAXRSCLIENTFactory also to implement client but the same exception.
I ran into the same problem in unmarshalling using the CXF client. Here is how I did it:
Read the response into a String.
Used Gson to convert from string to list of objects.
Note: You will need a wrapper class for your list of objects.
Example:
If the server returns a list of products, Here is how to unmarshall the list:
Create a wrapper class
public class ProductList {
private List<Product> products;
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
}
Code to unmarshall
String responseBody = response.readEntity(String.class);
ProductList productList = new Gson().fromJson(responseBody, ProductList.class);
if(productList.getProducts() != null)
return productList.getProducts();

communication between 2 rest web services

I have many rest controllers in my project (developed with spring MVC) and i would like to make them communicate between each other.
what's the best way to make two spring REST controllers exchange messages ?
Supposed you have 2 controllers:
#RestController
#RequestMapping("/first")
public class FirstController(){
// your code here
}
and
#RestController
#RequestMapping("/second")
public class SecondController(){
// supposed this is your FirstController url.
String url = "http://localhost:8080/yourapp/first";
// create request.
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
// execute your request.
HttpResponse response = client.execute(request);
// do whatever with the response.
}
For reference, have a look at this: http://www.mkyong.com/java/apache-httpclient-examples/
Used library: https://hc.apache.org/httpcomponents-client-ga/

How can I get this working with a GET or should it be a POST with REST Service in Spring

I am working on some web servers and I have to sent some data to the web service and get back a status code.. I am thinking maybe this should be a POST and not a GET but I would like to hear from all the pros out on the internet.
Here is my client code using Spring RESTTemplate
vars.put("lastName", "JOHN");
vars.put("firstName", "SMITH");
vars.put("middleInitial", "");
vars.put("socialSecurityNumber", "111-11-1111");
vars.put("Type","A");
vars.put("FileNumber","");
vars.put("EISNumber","");
String jsonreturn = restTemplate.getForObject("http://" + mRESTServer.getHost() + ":8080/services/api/checkstatus", String.class, vars);
Now here is my service side code (Spring MVC RESTful service). I would think all the fields I entered in the client would be in the ModelMap object but its not
#RequestMapping(value = "/checkstatus", method = RequestMethod.get)
#ResponseBody
public ResponseEntity<String> getCheckEnrollStatus(ModelMap model) throws ResourceNotFoundException
{
logger.debug("Looking for Status: " + model.toString());
}
So I have two questions:
1) Should I change the GET to a POST due to senting alot of data to the server?
2) If I leave it as a get why is my ModelMap emply?
Please help me out
For your ModelMap to be populated you probably need to annotate it with #RequestBody.
As the comment has pointed out you can't have a request body with a GET as per the specification. So you would either need to make the parameters part of the URL and use get or convert to POST.
Though POST seems to not fit with the purpose of your call.
Normally I'd say this should be a GET, but I noticed you have socialSecurityNumber as one of your parameters. You definitely do NOT want that to be part of your URL. Check out RFC 2616 section 15.1.3
Authors of services which use the HTTP protocol SHOULD NOT use GET based forms for the submission of sensitive data, because this will cause this data to be encoded in the Request-URI. Many existing servers, proxies, and user agents will log the request URI in some place where it might be visible to third parties. Servers can use POST-based form submission instead
Do a POST.
get as it is not changing anything onserver just returning data here is the spec.
Use request parameters like this
#RequestMapping(value = "/checkstatus", method = RequestMethod.get)
#ResponseBody
public ResponseEntity<String> getCheckEnrollStatus(#RequestParam final Long id)
or uri parameters, like
#RequestMapping(value = "/checkstatus/{id}", method = RequestMethod.get)
#ResponseBody
public ResponseEntity<String> getCheckEnrollStatus(#PathVariable final Long id) throws ResourceNotFoundException
{