What is the Java equivalent to Script service (like web service but with JSON instead of XML) in the .net world?
I am looking for a way of creating and invoiking web services using java. I prefer to find a way that will allow me define a method that will act as web service. I don't like the solutions of "dedicated jsp or servlet" for the specific request.
Is there any wat of doing so?
There are a lot of frameworks that help you to do this. I personally prefer Spring.
But you can just search for "Java based RESTful web services frameworks". Here is a list of such framework from Wikipedia: http://en.wikipedia.org/wiki/List_of_web_service_frameworks
Enjoy.
You can use libraries like Jersey or RESTeasy for the implementation of web services. For the consumers, you can use the built in classes of the same libraries or, if you prefer, can use Apache HttpClient
I personally prefer using Jersey + HttpClient combination :)
I would prefer RESTful services which fits for your need of "I prefer to find a way that will allow me define a method that will act as web service." Just with REST annotations You can set a method as a Service.
Code Snippet simple REST
#Path("/rest")
public Class MyFirstService
{
//Method without Path parameters
#GET
#Path("/name")
#Produces("application/json")
public String getMyName()
{
return "My Name:";
}
//Method with Path parameters
#GET
#Path("/name/{id}")
#Produces("application/json")
public String getMyName(#Pathparam("id")String Id)
{
if(Id.equals("1")
return "My Name:";
else
return "None";
}
}
RESTful Services give four major Services as -
GET
PUT
POST
DELETE
I would recommend JEE6, especially if your focus is going to be on REST based services. Glassfish 3 and JBoss 7 are neck and neck now with their implementation, either would be a good choice (though JBoss is my personal preference). With the JAX-RS and JAS-WS specifications you simply annotate your classes and they become web service capable:
Make your bean a SOAP based web service:
#WebService
public class AccountImpl {
// You can explicitly mark the methods you want to make available in your WSDL
#WebMethod
public BigDecimal getBalance() {}
}
Make your bean a REST based web service:
#Path("/rs/account")
public class AccountImpl {
#GET
#Path("/balance")
#Produces("application/json")
public BigDecimal getBalance() {}
}
The code snippet is just an example. You can find more resources online for learning JAX-RS and JAX-WS. Here are a few links:
RESTEasy
Jersey
JAX-WS Tutorial
Note: I included information about JAX-WS for reference only. You indicated you wanted to build JSON services, which implies REST
Related
I know there are a lot of answers on this questions , but i am still confused about difference between JAX-RS API(the specification), and Jersey framework( reference implementation).
I read that:
Jersey framework basically uses com.sun.jersey.spi.container.servlet.ServletContainer servlet to intercept all the incoming requests. As we configure in our projects web.xml, that all the incoming rest request should be handled by that servlet. There is an init-param that is configured with the jersey servlet to find your REST service classes. REST service classes are not Servlet and they need NOT to extend the HttpServlet as you did in your code. These REST service classes are simple POJOs annotated to tell the jersey framework about different properties such as path, consumes, produces etc. When you return from your service method, jersey takes care of marshalling those objects in the defined 'PRODUCES' responseType and write it on the client stream
My question is when you say :" jersey takes care of marshalling those objects in the defined 'PRODUCES' responseType and write it on the client stream", what you mean by jersey , what is actual class or library that handles objects .
I am confused when i read that jersey is the engine that handles JAX-RS API specification. Can someone please explain what exactly is behind word jersey in this sentence? What actual class from Jersey do do the job of processing requests and responses in Jersey?
The concept of specification and implementation is really pretty basic software engineering concepts. Your specification is the high level design. To help understand, I just came up with a really simple example.
Say I want to have a parsing library. I know how I want to be able to use it. The only problem is that I am not very good at writing parsing code. So I create a high level specification, and I outsource the implementation. Here are the three classes that are part of the spec. They are all contained in one "API jar", say myparsers-api.jar
public interface Parser {
String[] parse(String s);
}
public interface ParserFactory {
Parser getBySpaceParser();
Parser getByCommaParser();
}
public class ParserDepot {
private static ServiceLoader<ParserFactory> loader
= ServiceLoader.load(ParserFactory.class);
public static ParserFactory getDefaultParserFactory() {
final List<ParserFactory> factories = new ArrayList<>();
loader.forEach(factories::add);
if (factories.isEmpty()) {
throw new IllegalStateException("No ParserFactory found");
}
return factories.get(0);
}
}
So at this point, I can actually code against this jar. If I were to uses it as is right now in another project, the project would compile just fine.
ParserFactory factory = ParserDepot.getDefaultParserFactory();
Parser parser = factory.getBySpaceParser();
String[] tokens = parser.parse("Hello World");
System.out.println(Arrays.toString(tokens));
So even though there is no implementation of this specification, I can still code against it, and compile against it. But when I try to actually run the program, it won't work, as there is no implementation. You can try to run this code, and you will get an IllegalStateException (see the docs for ServiceLoader if you're unfamiliar with this pattern).
So I outsource the implementation to say a company called Stack Overflow. They get my myparsers-api.jar and they need to give me back an implementation. They would need to implement a ParserFactory, and a couple of Parsers. They might look something like this
public class SoByCommaParser implements Parser {
#Override
public String[] parse(String s) {
return s.split("\\s+,\\s+");
}
}
public class SoBySpaceParser implements Parser {
#Override
public String[] parse(String s) {
return s.split("\\s+");
}
}
public class SoParserFactory implements ParserFactory {
#Override
public Parser getBySpaceParser() {
return new SoBySpaceParser();
}
#Override
public Parser getByCommaParser() {
return new SoByCommaParser();
}
}
Now Stack Overflow gives me back a jar (say so-myparsers-impl.jar) with these three classes and the required META-INF/services file (per the ServiceLoader pattern), and now when I add the so-myparsers-impl.jar to my project and try to run it again, the program now works, because now it has an implementation.
This is exactly how the JAX-RS spec works. It only defines the high level design of how it should work. The classes, interfaces, and annotations that are part of that design are placed in an "API jar" just like my high level parsers are put into a jar. Implementations cannot alter these classes. All the classes that are part of the JAX-RS specification (version 2.x) are put into one single jar javax.ws.rs-api. You can code against that jar, and your code will compile just fine. But there is nothing to make it "work".
You check out both the written specification and the classes defined by the specification and you will notice that the only classes included in the source code are those mentioned in the specification. But what you should notice is that the written specification doesn't mention anything at all about how it is supposed to be implementation. Take for example the following code
#Path("/test")
public class TestResource {
#GET
public String get() {
return "Testing";
}
}
#ApplicationPath("/api")
public class MyApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<>();
classes.add(TestResource.class);
return classes;
}
}
Now the specification states that this is all we need to run a JAX-RS application in a servlet container. And that's all it says. It says nothing about how it all supposed to work. This is just how it is designed to work.
So what, is there some magic voodoo in Java that we don't know about that will make this Application class start a server, and some hocus pocus that will make a #Path annotated class automatically accept requests. No. Some body needs to provide the engine. The engine might be 20,000 lines of code just to make the above code work as specified.
That being said, Jersey is just the name of an implementation. It's like when I outsourced my parser implementation to Stack Overflow; The name Jersey itself is just the name of the project, just like Hadoop is a name of the project. In this case, what the project is, is an implementation of the JAX-RS specification. And because JAX-RS is just a specification, it means that anyone can implement it. If you wanted to, you could write your own implementation. As long as it works how it is defined to work in the written specification, then you can say that your code is an implementation of JAX-RS. There's more than just Jersey out there; you also have RESTEasy, which is another implementation.
As far as how Jersey implements the engine, that is way too broad. What I can do, is give you a high level overview of what happens behinds the scenes.
A JAX-RS application is defined to run inside of a servlet container. If you understand servlet containers and the servlet spec, then you'll know that the only way to handle requests is either by writing a HttpServlet or Filter. So if you want to implement JAX-RS then you need to able to handle requests either through a HttpServlet or a Filter. The ServletContainer you mentioned, is actually both. So for Jersey, this is the "entry point" into the Jersey application, as far as request processing is concerned. It can be configured in a number of ways (I've leave that research to you).
And if you understand how to write your own servlet, then you know all you get is an HttpServletRequest and HttpServletResponse. You need to figure out what to do from there; get request info from the request, and send response info back out in the response. Jersey handles all of this.
If you really want to get into the gory details of what is going on under the hood, you will just need to to dig into the source code, starting from the entry point, the ServletContainer. Be prepared to spend months on this to get a really good understanding of how it all works. It's not something that can be explained in one Stack Overflow post, if that's what you're expecting.
You already pointed that JAX-RS is a specification and Jersey is the implementation which is how is Java especially Java EE work, maybe this article can explain more better.
To summarize JAX-RS is just a specification, there is no real implementation. The real implementation was done by Jersey and other library that following JAX-RS specification.
BACKGROUND:
I have a REST API implemented in Java using Jersey. My API uses four verbs: GET, POST, PUT, DELETE.
I find developing REST APIs in java very easy and straight forward.
eg here is an elaborate hello webservice (I say elaborate because there are easier ways, but this is more representative):
import javax.ws.rs.*;
#Path("/myresource")
public class MyResource{
#GET
#Path("name/{name}")
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response sayHello(#PathParam("name") String name){
return Response.ok("Hello "+name).build();
}
}
PROBLEM:
I am learning python. I want to convert my Java Jersey REST API into python.
Basically Jersey is Java's implementation of REST (aka JAX-RS: Java API for RESTful Web Services). Does python have a reference implementation of REST? If not, is there any implementation out there that comes close and would be easy to use for someone coming from Java-Jersey?
You may want to check the previous similar question: Recommendations of Python REST (web services) framework?
Python does not have a built-in REST framework, but I personally have had good experiences with Flask and Bottle.
It's very similar in use to Jersey (Bottle example):
#route('/')
#route('/hello/<name>')
def greet(name='Stranger'):
return template('Hello {{name}}, how are you?', name=name)
Handling HTTP verbs:
#app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
do_the_login()
else:
show_the_login_form()
I want to implement REST calls in a web application. I took a look at the different available frameworks to achieve that. It seems JBoss Resteasy provides what I need:
#GET
#Path("book/{id}/comments")
public Collection<Comment> getComments(#PathParam("id") String bookId);
What I would like would be something like:
#GET
#Path("book/{id}/comments")
public Collection<Comment> getComments(#PathParam("id") **Book** bookId);
So instead of receiving a String I would be interested in binding directly the value. Meaning if my Book extends a AbstractEntity class, it would directly do the findById in the database.
I used to achieve this with Spring MVC by using Custom Conversion Services that would do the findById directly. Is there such functionality in RestEasy, or any other REST framework?
Thanks!
I've not done this, but RESTEasy has a StringConverter interface that might accomplish this. Check out Chapter 24 in the RESTEasy documentation: http://docs.jboss.org/resteasy/docs/2.3.1.GA/userguide/html/StringConverter.html
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/
I googled some information about web services, it seems like a enterprise level application. I found that RESTful design is very cool idea on this. I find that Apache CXF looks cool, it support RESTful design and Java. It is a good choice for beginner to start writing an application using Apache CXF? or any other framework is suggested?
I'd go for Jersey, the RI of JAX-RS (JSR 311), the Java API for RESTful Web Services (i.e. a standard).
I recommend to use JAX-RS because IMHO it is the most neutral framework in terms of telling you how REST should be done. I have not used CXF, only Jersey. It is a very solid implementation and comes with a good client side connector, too (client side not part of JAX-RS yet).
Being neutral with regard to 'how to do REST' is important because there is not yet an acknowledged 'best' way to approach certain aspects (e.g. design of hypermedia).
Congrats to going the REST way - you won't regret it.
Jan
The much simpler implementation for a beginner would be spring 3.0 REST support. Spring MVC 3.0 has REST support and is very much simpler compared to Apache CXF.
Restlet in another RESTful web framework for Java : http://www.restlet.org/
I get started REST with RESTEasy and get it up in 30 minutes. You can use it as stand-alone lib in your favorite servlet container without all this JBoss stuff.
You should try PlayFramework. Just take a loot at a sample route file and you will know how easy it is to use play to implement RESTFul web app:
# ====== Order service =========================
GET /orders Orders.list
GET /orders/{<[0-9]+>id} Orders.show
PUT /orders/{<[0-9]+>id} Order.saveUpdate
POST /orders Orders.saveNew
# ==============================================
And corresponding controller methods:
public class Orders extends Controller {
public static void list() {
List<Order> orders = Order.all();
render(orders);
}
public static void show(long id) {
Order order = Order.findById(id);
notFoundIfNull(order);
render(order);
}
public static void saveUpdate(long id, Order update) {
Order order = Order.findById(id);
notFoundIfNull(order);
order.update(update);
show(id);
}
public static void saveNew(Order order) {
order.save();
show(order.getId());
}
}
There are some utilities enable you to interact with other Web Services:
String url = "https://ajax.googleapis.com/ajax/services/search/web";
Map<String, Object> params = new HashMap<String, Object>();
params.put("v", "1.0");
params.put("q", searchStr);
params.put("key", Play.configuration.get("app.google.key"));
params.put("userip", myIpAddr);
HttpResponse resp = WS.url(url).params(params).get();
return resp.getString();