REST API invocation in Java - java

Suppose I need to write a Java client, which calls a REST API (with HTTP GET). I know it returns the data in JSON by default and I do not need to supply any headers.
Now I can use either Apache HttpClient to invoke the API or read the URL directly (get a stream from the URL with url.openStream and read the data). The second approach seems to me much simpler. Which one would you suggest and why ?

All the REST clients provide a wrapper over basic java URL based APIs. These clients are easy to use and provide all the necessary functionality. Your code will be much cleaner in case you use Apache HttpClient. And Apache's API are quite reliable.

I would use special libraries for that, like Jersey client or Apache CXF client.
https://jersey.java.net/documentation/latest/client.html
http://cxf.apache.org/docs/jax-rs.html
These ones are part of Java EE standard, a well defined specification which is widely used.
For JSON, consider https://github.com/FasterXML/jackson. Depending on what client you use, you will find information about how to make it work.

If you are not a big fan of JavaEE, and you look for neat and elegant API, and you are interested in working with a language on top of Java, Groovy HTTPBuilder is such a library that works like a charm!
twitter = new RESTClient( 'https://twitter.com/statuses/' )
resp = twitter.post( path : 'update.xml',
body : [ status:msg, source:'httpbuilder' ],
requestContentType : URLENC )
assert resp.status == 200
assert resp.data.user.screen_name == userName

You can use spring-data-rest and Spring's RestTemplate. No need to write a webapp as you can bootstrap Spring easily into a standalone java application putting AnnotationConfigApplicationContext in the Main(). It's quite simple.
For example, suppose you have a Restful URL, http://localhost:8080/croot/books/ that returns a list of books (deserialized into objects of type Book).
Using Spring's RestTemplate you can do the following:
public Resource<List<Resource<Book>>> findAll() {
return restTemplate
.exchange(
"http://localhost:8080/croot/books/",
HttpMethod.GET,
null,
new ParameterizedTypeReference<Resource<List<Resource<Book>>>>() {
}).getBody();
}
You can also process this using spring-data-hateoas allowing you to further decouple the client from the server and helps process what to do next, say in pagination.
This is a very simplified/contrived example but the REST support in Spring 3 combined with the spring-data framework is quite elegant.
Using Spring you also get the advantage of Jackson for JSON processing as the RestTemplate will have one of the flavors of Jackson's message converters (provided through MappingJackson2HttpMessageConverter for example) in it's list of default converters used for processing.

Related

Spring Webflux: Controller return Mono<ResponseEntity<MyPojo>> vs Mono<MyPojo>

Question regarding return types I have seen with Spring Webflux.
In many examples, like online tutorials, the rest web controller of a Spring Webflux project will return a Mono<MyPojo>:
public Mono<MyPojo> monoPojo(String parameter) {
return WebClient.create("http://...").get().retrieve().bodyToMono(MyPojo.class)
.map(oneMyPojo -> unregisterRepository.insert(oneMyPojo));
}
But I am also bumping into projects where it returns Mono<ResponseEntity<MyPojo>>:
public Mono<ResponseEntity<MyPojo>> monoResponseEntityPojo(String parameter) {
return WebClient.create("http://...").get().retrieve().bodyToMono(MyPojo.class)
.map(oneMyPojo -> unregisterRepository.insert(oneMyPojo))
.map(ResponseEntity::ok);
}
What are the benefits of Mono<ResponseEntity<MyPojo>> over Mono<MyPojo>?
Lets clear some things up
A ResponseEntity<T> is from the org.springframework.httppackage while a ServerResponse is from the org.springframework.web.reactive.function.server package.
This should as a start should give you a hint of when to use what, and where.
But in short, you can use webflux in 2 ways, either by using old fashioned #RestController annotations, with annotated functions for each path. This a sort of "backwards compatibility mode" between regular servlet spring web, and webflux async event driven programming.
ResponseEntities are returned from old spring-web while if you instead opt in to use functional enpoints that exist in webflux, you need to return ServerResponses.
If you look in the code for the classes you will se that they work some parts the same, but other parts differently, especially how they store the body and serialize the bodies.
Handler functions and Filter functions in webflux only work with ServerResponses.
Now to your question, returning Mono<ResponseEntity<T> or Mono<T>.
Well it all comes down to how lazy you are.
If you return a Mono<T> the framework will try to figure out what type of content you have in the Mono, and then create a ResponseEntity accordingly. So if you are serializing it into json, it will set the content-type for you, and set the status usually to 200 OK
While if you wish, you can build your ResponseEntity completely custom, and return any status code, with any body, and any headers etc. etc.
So what it all comes down to is how lazy are you, how much do you want the framework to do for you, and how much to do you want to be explicit, and and type out everything by yourself, or customize.
Me, im lazy, i just return something that works.

Starting point for converting jersey project to standard servlet app

I am trying to implement the example shown here.
The example seems to be for a jersey setup, which I am not using or familiar. How hard would it be to convert this to a standard java servlet project(idk how to name this)
What steps should I take. It seems most of the # annotations need to be changed to servlets.
This also seems very differnt from the standard appengine upload setup which all takes place in one servlet.
This would be a lot of work to rework the code to standard servlet and remove jersey. Jersey takes away so much boilerplate code. For example the JSON conversion is done by jersey, which otherwise would have to be custom implemented.
And you can for sure deploy more than one servlet to gae, in which way should this be standard?
Just look at the first method:
#GET
#Path("/url")
public Response getCallbackUrl() {
String url = blobstoreService.createUploadUrl("/rest/file");
return Response.ok(new FileUrl(url)).build();
}
When using only standard servlet you would need to do:
Servlet Definition and Mapping in web.xml to /url
Implement a HttpServlet, override doGet() method
Send Response Code 200 OK
Set appropriate HTTP Response Headers
Convert Response to JSON and write it to response

AJAX with Spring MVC

What AJAX libraries work well with Spring MVC?
I'm new to developing with Spring and Spring MVC. From the documentation at http://www.springsource.org I'm not yet understanding what AJAX framework Spring MVC has built-in or what third party APIs and tooling might be suggested as working well with developing a Spring MVC application.
All recommendations are appreciated.
I did search through previous SO discussions on this subject, but I didn't get any clear direction.
Spring is super easy to use with Ajax. If Jackson is on the classpath Spring can use it for returning JSON to the caller. Something like this:
#RequestMapping( "/my/path" )
public #ResponseBody MyObject doSomething( #RequestParam Long myVal ) {
MyObject result = new MyObject( myVal );
// do something interesting
return result;
}
Then you can use jQuery (or your other favorite javascript library) to make a request to http://myserver/my/path and handle the resulting JSON object.
Google's GSON is also easy to use. As in:
#RequestMapping( "/my/path" )
public ResponseEntity<String> MyObject doSomething( #RequestParam Long myVal ) {
MyObject result = new MyObject( myVal );
// do something interesting
HttpHeaders headers = new HttpHeaders();
headers.set( "Content-Type", "application/json" );
String json = gson.toJson( result );
return new ResponseEntity<String>( json, headers, HttpStatus.CREATED );
}
Please go through the following link. It clearly explains how it needs to be done.
http://blog.springsource.org/2010/01/25/ajax-simplifications-in-spring-3-0/
Here is another approach to let Spring MVC to work with ZK UI components - Rich Web Application with Spring MVC CRUD Demo
In that article, it used Spring MVC controller to communicate with ZK UI components. (all in Java code)
Spring JS has support of Dojo JavaScript framework.
Spring Js
Spring doesn't deal with Javascript frameworks, per se. I don't know if Springsource does any advocacy for any particular Javascript framework or whether they are agnostic. Ajax is really just a technique enabled by browser technology in combination with the Javascript language and what matters is the ability to pass some kind of serialized data between client and server. It isn't that difficult to cook up your own basic AJAX framework and you could even design your own data encoding and not use JSON or XML. It is wise to adopt an existing framework and standards because you don't want to maintain a lot of ancillary code or worry about it, and instead focus on the problem you are trying to solve. So that is why there are many Javascript frameworks out there that can do asynchronous requests and some have some really nice features and capabilities that make your life easier, for example jQuery provides excellent DOM manipulation and browser-neutral functionality. I think that using Spring MVC in conjunction with the Jackson JSON library on the server side, and jQuery on the client side, is the basis for a very decent end-to-end solution. I have had a lot of success with jQuery and jQuery-UI, but other Javascript frameworks can work just as well. For complex applications, you basically end up needing what amounts to a second MVC on the client side because you need that breakdown between UI widgets and the data that has to move between client and server.

dynamic proxy soap web service client in java?

Is there any way to use soap-rpc web services such that the client is generated via a shared interface? Restful web services do it this way, but what about soap based? Do you always have to use a tool like Axis or CXF to generate your stubs and proxies, or is there something out there that will set it up dynamically?
Thanks.
EDIT #1:
To clarify, I'm looking to do something like this:
Common interface:
#WebService
public interface MyWebService {
#WebMethod
String helloWorld();
}
This common interface can already be used to create the server side component. My question is: can this type of common interface be used on the client side to generate dynamic proxies? Restful web services do it this way (Restlets & CXF) and it seems the .Net world has this type of functionality too.
I would see this tutorial of JAX-WS useful for your purposes:
In the example code the Web Services Client is configured by adding an annotation #WebServiceRef with a property pointing to the WSDL location to the client implementation class and no tools are needed to access the stuff from the Web Service that is referenced.
Was this the way you would like to have it, or did this even answer to right question?
Not exactly sure what you're looking for, but if you don't want to rely on JAX-WS/JAXB-generated artifacts (service interfaces and binding objects), you can make use of the Service and Dispatch APIs. For example:
QName serviceName = new QName(...);
Service service = Service.create(serviceName);
QName portName = new QName(...);
String endpointAddress = "...";
service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);
Dispatch<SOAPMessage> dispatch = service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);
SOAPMessage request = ...;
SOAPMessage response = dispatch.invoke(request);
Check Apache CXF. Configuring a Spring Client (Option 1).
When you want to call a webservice, you must have knowledge of methods implemented on it. For that, We need to make stubs OR we can read it from WSDL.
I have created a WS client, using AXIS2 libraries, which is without stubs. The thing is, for each diff. WS we need to create response handles.
You can call any WS method using SOAP envelops and handle the response.
//common interface for response handlers...
//implement this for diff. web service/methods
public interface WSRespHandler{
public Object getMeResp(Object respData);
}
//pass particular handler to client when you call some WS
public class WebServiceClient {
public Object getResp(WSRespHandler respHandler) {
...
return repHandler.getMeResp(xmlData);
}
}
Please check the link below, which shows the example interface for WS client.
http://javalibs.blogspot.com/2010/05/axis2-web-service-client-without.html
For every diff. WS method we can have diff. implementation for WSRespHandler interface, which will help parsing the response.
Not knowing java so well, but being forced to learn some to accomplish a task that I was given, I needed to consume a .Net service that I have already written, I had to do a little research.
I found that 99% of the examples/samples/problems with invoking a method call against a .Net service, or any service for that matter involved using J2EE (ServiceManager) or build classes and a proxy that reflect the service being invoked. Unfortunately for me, none of this would work. I was working "in a box". I could not add new classes, could not WSDL references, did not have J2EE, but DID have access to the standard java libs.
I am used to doing this sort of thing in pretty much every other language but java, but now there was no choice, and java it was.
A lot of digging and figuring out all new terminology, methods, classes, etc, I knew I was getting close, but was having issues with some small items to complete the task.
Then I came across this post: http://www.ibm.com/developerworks/xml/library/x-jaxmsoap/
As long as you have some sort of idea of what you need to send the soap service in term of the soap envelope, the above link will give you the information you need to be able to invoke a service without the classes, wsdl class generators and J2EE, apache or other dependencies.
In an hour from the time I read the mentioned article, I had a class working and about 10 minutes later, converted the code to the "in the box" solution.
Hope this helps
Apache Tuscany might help you, although it may be heavier than you want
http://tuscany.apache.org/

Java REST client without schema

Goal
Java client for Yahoo's HotJobs Resumé Search REST API.
Background
I'm used to writing web-service clients for SOAP APIs, where wsimport generates proxy stubs and you're off and running. But this is a REST API, which is new to me.
Details
REST API
No WADL
No formal XML schema (XSD or DTD files). There are example XML request/response pairs.
No example code provided
Progress
I looked at question Rest clients for Java?, but the automated solutions there assume you are providing both the server and the client, with JAXB invoked on POJOs to generate a schema and a REST API.
Using Jersey (a JAX-RS implementation), I have been able to make a manual HTTP request:
import com.sun.jersey.api.client.*;
...
ClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);
WebResource webResource = client.resource("https://hj.yahooapis.com/v1/HJAuthTokens");
webResource.accept("application/xml");
// body is a hard-coded string, with replacements for the variable bits
String response = webResource.post(String.class, body);
// parse response into a org.w3c.dom.Document
// interface with Document via XPATH, or write my own POJO mappings
The response can look like:
<?xml version="1.0" encoding="utf-8"?>
<Response>
<ResponseCode>0</ResponseCode>
<ResponseMessage>Login successful</ResponseMessage>
<Token>NTlEMTdFNjk3Qjg4NUJBNDA3MkJFOTI3NzJEMTdDNDU7bG9jYWxob3N0LmVnbGJwLmNvcnAueWFob28uY29tO0pVNWpzRGRhN3VhSS4yQVRqRi4wWE5jTWl0RHVVYzQyX3luYWd1TjIxaGx6U0lhTXN3LS07NjY2MzM1OzIzNDY3NTsxMjA5MDE2OTE5OzZCM1RBMVNudHdLbl9VdFFKMFEydWctLQ==</Token>
</Response>
Or, it can look like:
<?xml version="1.0" encoding="utf-8"?>
<yahoo:error xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" xml:lang="en-US">
<yahoo:description>description</yahoo:description>
<yahoo:detail>
<ErrorCode>errorCode</ErrorCode>
</yahoo:detail>
</yahoo:error>
Questions
Is there a way to auto-generate POJOs which can be marshalled/unmarshalled without a formal schema?
Should I attempt to generate those POJOs by hand, with JAXB annotations?
Is there some tool I should be leveraging so I don't have to do all this manually?
It's interesting that they provide an HTTP URL as the namespace URI for the schema, but don't actually save their schema there. That could be an oversight on their part, which an email or discussion-list posting could correct.
One approach is to create your own schema, but this seems like a lot of work for little return. Given how simple the messages are, I wonder if you even need a POJO to wrap them? Why not just have a handler that extracts the data you need using XPath?
Edit: blast from the past, but I saw the comment, reread the question, and realized that the first sentence was hard to understand. So, clarification:
One very good habit, if you're going to write a publicly accessible web service, is to make your schema document available at the same URL that you use for the schema's namespace URI -- or better, have that URL be a link to complete documentation (the W3C XSD namespace is itself a good example: http://www.w3.org/2001/XMLSchema).
I would suggest writing beans by hand, and only annotating with JAXB annotations if you have to. For most accessors/mutators (getters/setters) you do not have to; by default all public bean accessors and fields are considered, name is derived using bean convention, and default is to use elements instead of attributes (so attributes need to be annotated).
Alternatively you can of course write schema by hand, generate beans using JAXB, if you like W3C Schema a lot. And just use resulting code, not schema, for data binding.
As to POJO: that can be very simple. Something like:
#XmlRootElement("Response")
class Response {
public int responseCode;
public String responseMessage;
public String token; // or perhaps byte[] works for automated base64?
}
and similarly for other ones. Or, use getters/setters if you like them and don't mind bit more verbosity. These are just data containers, no need to get too fancy.
And if you must auto-detect type from content, consider using Stax parser to see what the root element, and then bind using JAXB Unmarshaller, handing XMLStreamReader that points to that root element. That way you can pass different object type to bind to.
And finally: sending/receiving requests: plain old HttpURLConnection works ok for GET and POST requests (construct using, say, URL.openConnection()). Jakarta HttpClient has more features if need be. So oftentimes you don't really need a separate REST client -- they may come in handy, but generally build on simple http client pieces.
I find HTTP4E very useful for making REST calls. It is an awesome Eclipse plugin, it has tabs, syntax coloring, auto suggest, code generation, REST HTTP call replay, etc.. It does a great job of HTTP debugging, HTTP tampering, hacking. I am having so much fun with it.
http://www.ywebb.com/
Try JdkRequest from jcabi-http (I'm a developer). This is how it works:
String body = new JdkRequest("http://www.google.com")
.header("User-Agent", "it's me")
.fetch()
.body()
Check this blog post for more details: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

Categories

Resources