RESTful web services are based on the way how our web works. Our very own world wide web (www) – the largest distributed application – is based on an architectural style called REST – Representational State Transfer. REST is neither a standard nor a protocol. It is just an architectural style like say for example client-server architecture (client-server is neither a standard nor a protocol). Web services following this architectural style are said to be RESTful Web services.
RESTful web services are based on HTTP protocol and its methods PUT, GET, POST, and DELETE. These web services are better integrated with HTTP than SOAP-based services are, and as such do not require XML SOAP messages or WSDL service definitions.
Java provides support for Restful web services through Java API for RESTful Web Services JAX-RS. The complete specification is available as JSR 311. JAX-RS is an annotation-based API for implementing RESTful web services, based on HTTP, in Java. Essentially, classes and methods are annotated with information that enables a runtime to expose them as resources – an approach that is very different from the one exposed by the servlet programming model. A runtime that implements JAX-RS mediates between the HTTP protocol and the Java classes, taking into account URIs, requested and accepted content types, and HTTP methods. Jersey is a production quality reference implementation of JAX-RS API.
Contents
package com.theopentutorials.jaxrs.calc;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/calc")
public class CalcREST {
@GET
@Path("/add/{a}/{b}")
@Produces(MediaType.TEXT_PLAIN)
public String addPlainText(@PathParam("a") double a, @PathParam("b") double b) {
return (a + b) + "";
}
@GET
@Path("/sub/{a}/{b}")
@Produces(MediaType.TEXT_PLAIN)
public String subPlainText(@PathParam("a") double a, @PathParam("b") double b) {
return (a - b) + "";
}
@GET
@Path("/add/{a}/{b}")
@Produces(MediaType.TEXT_XML)
public String add(@PathParam("a") double a, @PathParam("b") double b) {
return "<?xml version=\"1.0\"?>" + "<result>" + (a + b) + "</result>";
}
@GET
@Path("/sub/{a}/{b}")
@Produces(MediaType.TEXT_XML)
public String sub(@PathParam("a") double a, @PathParam("b") double b) {
return "<?xml version=\"1.0\"?>" + "<result>" + (a - b) + "</result>";
}
}
package com.theopentutorials.jaxrs.calc;
import java.io.IOException;
import com.sun.jersey.api.container.httpserver.HttpServerFactory;
import com.sun.net.httpserver.HttpServer;
public class CalcRESTStartUp {
static final String BASE_URI = "http://localhost:9999/calcrest/";
public static void main(String[] args) {
try {
HttpServer server = HttpServerFactory.create(BASE_URI);
server.start();
System.out.println("Press Enter to stop the server. ");
System.in.read();
server.stop(0);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
http://localhost:9999/calcrest/application.wadl
. A Web Application Description Language (WADL) should be displayed. This is similar to WSDL. WADL is not standardized by W3C.
http://localhost:9999/calcrest/calc/add/20/30/
and
http://localhost:9999/calcrest/calc/sub/20/30/
Even though the web service is accessible via browser, the primary purpose of web service is for machines to communicate. So let us access this web service programmatically by creating a client.
package com.theopentutorials.jaxrs.calc.client;
import javax.ws.rs.core.MediaType;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
public class CalcRESTClient {
static final String REST_URI = "http://localhost:9999/calcrest";
static final String ADD_PATH = "calc/add";
static final String SUB_PATH = "calc/sub";
public static void main(String[] args) {
int a = 122;
int b = 34;
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource(REST_URI);
WebResource addService = service.path(ADD_PATH).path(a + "/" + b);
System.out.println("Add Response: " + getResponse(addService));
System.out.println("Add Output as XML: " + getOutputAsXML(addService));
System.out.println("Add Output as Text: " + getOutputAsText(addService));
System.out.println("---------------------------------------------------");
WebResource subService = service.path(SUB_PATH).path(a + "/" + b);
System.out.println("Sub Response: " + getResponse(subService));
System.out.println("Sub Output as XML: " + getOutputAsXML(subService));
System.out.println("---------------------------------------------------");
}
private static String getResponse(WebResource service) {
return service.accept(MediaType.TEXT_XML).get(ClientResponse.class).toString();
}
private static String getOutputAsXML(WebResource service) {
return service.accept(MediaType.TEXT_XML).get(String.class);
}
private static String getOutputAsText(WebResource service) {
return service.accept(MediaType.TEXT_PLAIN).get(String.class);
}
}
Add Response: GET http://localhost:9999/calcrest/calc/add/122/34 returned a response status of 200 OK
Add Output as XML:
Add Output as Text: 156.0
—————————————————
Sub Response: GET http://localhost:9999/calcrest/calc/sub/122/34 returned a response status of 200 OK
Sub Output as XML:
—————————————————
32 Responses
Excellent tutorial. It is very easy to understand. Thank you so much.
a WordPress rating system
very nice tutorial……..
a WordPress rating system
EveryThing in this tutorial is good but one jar file must be added as–
JAXB-API.jar
If I am wrong then plz correct me…
Thanks
a WordPress rating system
You only need Jersey jars. If you use Java 6 and above you do not need jaxb jar as JAXB is part of Java.
a WordPress rating system
When server and client are running in windows ,there are no problems at all.
Problem is—–>
Hosted Rest server program in linux box.
Tried running client program from windows PC.
Client is giving connection refused exception.why?
a WordPress rating system
Open the port in linux firewall.
a WordPress rating system
Thanks a ton Praveen. I made the necessary changes in linux box.But ,it is still showing exception as:
Exception in thread “main” com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:151)
at com.sun.jersey.api.client.Client.handle(Client.java:648)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:680)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:507)
at com.poc.jaxrsApproach.client.RESTClient.getResponse(RESTClient.java:58)
at com.poc.jaxrsApproach.client.RESTClient.callApproveService(RESTClient.java:52)
at com.poc.jaxrsApproach.client.RESTClient.main(RESTClient.java:26)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
:
:
Can you help me on this?
a WordPress rating system
From the client machine’s browser check the wsdl is accessible and also see whether any response is shown in the browser for REST urls. If not then there is a firewall issue.
a WordPress rating system
ok..thanks.It seems to be a firewall problem although ‘iptables’ in linux box is not denying my IP explicitly…Curious,why the prblem persists?…However,as you suggested,url is not accessible to see the wsdl file.
Is there is anything beyond these common troubleshooting?…
a WordPress rating system
Disable the firewall. See the linux documentation for the appropriate command.
a WordPress rating system
thanks praveen…We are working on a linux hardware which is designed by our hardware team…Probably,they made the OS a bit headless to tackle so many other priorities to suit their hardware needs…I told abt the firewall problem and they are working on it…
By the way,can you provide a simple tutorial to implement REST Websrvces using Apache axis?..Is it mandatory to use Jersey..?
Can you provide a simple tutorial of REST using Axis (without jersey)..?It would be of great help .
a WordPress rating system
Can you provide a simple tutorial of JAX-RS using apache CXF?
a WordPress rating system
Hi Praveen
I got the below error in console when run this URL: http://localhost:9999/calcrest/calc/add/20/30
Exception in thread “pool-1-thread-4″ java.lang.IncompatibleClassChangeError: Class javax.ws.rs.core.Response$Status does not implement the requested interface javax.ws.rs.core.Response$StatusType
at com.sun.jersey.spi.container.ContainerResponse.getStatus(ContainerResponse.java:564)
at com.sun.jersey.spi.container.ContainerResponse$CommittingOutputStream.commitWrite(ContainerResponse.java:156)
at com.sun.jersey.spi.container.ContainerResponse$CommittingOutputStream.write(ContainerResponse.java:133)
at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
pls help
a WordPress rating system
Hi Praveen,
I am pasting the full stack trace below…
Exception in thread “pool-1-thread-1″ java.lang.IncompatibleClassChangeError: Class javax.ws.rs.core.Response$Status does not implement the requested interface javax.ws.rs.core.Response$StatusType
at com.sun.jersey.spi.container.ContainerResponse.getStatus(ContainerResponse.java:564)
at com.sun.jersey.spi.container.ContainerResponse$CommittingOutputStream.commitWrite(ContainerResponse.java:156)
at com.sun.jersey.spi.container.ContainerResponse$CommittingOutputStream.write(ContainerResponse.java:133)
at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlush(Unknown Source)
at sun.nio.cs.StreamEncoder.flush(Unknown Source)
at java.io.OutputStreamWriter.flush(Unknown Source)
at java.io.BufferedWriter.flush(Unknown Source)
at com.sun.jersey.core.util.ReaderWriter.writeToAsString(ReaderWriter.java:191)
at com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider.writeToAsString(AbstractMessageReaderWriterProvider.java:128)
at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:88)
at com.sun.jersey.core.impl.provider.entity.StringProvider.writeTo(StringProvider.java:58)
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:306)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1437)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
at com.sun.jersey.server.impl.container.httpserver.HttpHandlerContainer.handle(HttpHandlerContainer.java:191)
at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source)
at sun.net.httpserver.AuthFilter.doFilter(Unknown Source)
at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source)
at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(Unknown Source)
at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source)
at sun.net.httpserver.ServerImpl$Exchange.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
a WordPress rating system
Use proper jar files as mentioned in the post.
a WordPress rating system
Hi praveen,
Can you provide a simple tutorial of JAX-RS using apache CXF?
It would be of great help…
a WordPress rating system
Hi Praveen
Thnx a ton..it got resolved, the problem was I was using jersey 1.8 jars
Thnx again for the most lucid example for RESTful WS.
a WordPress rating system
Hi Praveen,
Thanks for this great tutorial.Its working like charm.
But I am facing little problem.When I try to access “http://localhost:9998/testServer/sample/get” behind proxy it is accessible all time even after stopping the server,or closing eclipse or system completely.I have tried doing it when I am not behind proxy and it works perfectly.I can start and even stop the server.Can you please help with it?
a WordPress rating system
Possibly the proxy or your browser may be caching the requests. Try to disable it.
a WordPress rating system
How to use @QueryParam annotation and @MatrixParam annotation in JAX-RS?what exactly are these semantically?Can you explain me?
a WordPress rating system
Thank you very much , Your examples are simple and easy to grasp.
I have configured the webservice, it is working fine for PLAIN_TEXT,
and in other cases getting the error.
returned a response status of 406 Not Acceptable
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:686)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:507)
a WordPress rating system
@sanjeev goto mkyong site u ll get @QueryParam and @MatrixParam examples for jax-rs
a WordPress rating system
Thanks, works fine in ubuntu 12.04 with Oracle JDK 7.
a WordPress rating system
Thanks for the tutorial and it is working fine but when iam giving my ip instead of localhost I am getting “Connection refused error” .Please tell me why this is happening. I have changed the server setting localhost to my ip
a WordPress rating system
Turn off firewall. That could be the issue.
a WordPress rating system
it is the best description which i find. Thanks a lot! Could you please help me? How can i use it, if server use authorization?
a WordPress rating system
Hi Praveen, I copied/pasted your codes and I keep getting red error lines in CalcRESTStartup class in lines 5, 13, and 17 saying it’s “restricted”. It wouldn’t even let me run it as a java application or any other as a matter of fact. Could you please tell me what I’m doing wrong here? I am using the latest jersey archive 1.17
a WordPress rating system
Go to the Build Path settings in the project properties. Remove the JRE System Library. Add it back. Select “Add Library” and select the JRE System Library.
a WordPress rating system
Hi Pravin , I am getting below error while hitting the service…m kindaa new to web services…..please let me know what needs to be done…..thanks, in advance
——————————————————————————–
type Status report
message /calcrest/application.wadl
description The requested resource (/calcrest/application.wadl) is not available.
——————————————————————————–
JBoss Web/2.1.3.GA
a WordPress rating system
I like tutorials that manually go through the steps instead of throwing you into a complicated container environment where it’s not clear to a beginner what all is taking place. This was at the perfect level for what I needed to know about RESTful services. Thanks for a great tutorial!
a WordPress rating system
I have used your code. This is really helpful. And I am creating simple REST Client Server through this. I am in need of the information how to transfer one ZIP file from client to Server and get that file in the server. Could you please tell me how to do this?
a WordPress rating system
hi…
This example is excellent for Rest in java..
a WordPress rating system