UDDI stands
for Universal, Description, Discovery, and Integration. It is the discovery
layer in the web services protocol stack.
The RESTFul web
services are simple to implement and test. It supports various data formats
such as XML, JSON etc.
REST is over HTTP, but SOAP can be
over any transport protocols such HTTP, FTP, STMP, JMS etc.
SOAP is using soap envelope, but REST
is just XML.
</servlet-mapping>
jersey will consider all the classes which are under the package com.test.services.gmap
How to expose one service implementation as Restful and webservice?
Create a normal web application in eclipse and use the below files. I assume you are aware of pom.xml
package com.sudheer.cxf.demo.servImpl;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import org.springframework.util.StringUtils;
import com.example.employeeservice.Employee;
import com.example.employeeservice.EmployeeService;
import com.example.employeeservice.NoSuchEmployeeException;
import com.javatch.cxf.dao.utils.EmployeeUtils;
@Path("/")
public class EmployeeServiceImpl implements EmployeeService{
@GET
@Path("/getemployee/{name}/")
@Produces(value = {"application/json" })
public Employee getEmployeesByName(@PathParam("name") String name)
throws NoSuchEmployeeException {
if(EmployeeUtils.employees.containsKey(name)) {
return EmployeeUtils.employees.get(name);
} else {
throw new NoSuchEmployeeException("Employee " + name + "doesn't exists");
}
}
@POST
@Path("/addemployee/")
@Consumes(value="application/json")
@Produces(value = {"application/json" })
public void addEmployee(Employee employee) {
if(StringUtils.hasText(employee.getName())){
EmployeeUtils.employees.put(employee.getName(), employee);
} else {
System.out.println("Invalid Employee object");
}
}
}
package com.sudheer.test.client;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
public class RestClient {
public static void main(String[] args) {
System.out.println("Sent HTTP GET request to query customer info");
URL url;
try {
url = new URL("http://localhost:8080/cxfpoc/employeeservice/getemployee/Ryan");
getStringFromIOStream(url);
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
private static void getStringFromIOStream(URL url) {
try {
InputStream in = url.openStream();
BufferedInputStream bis = new BufferedInputStream(in);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result = bis.read();
while(result != -1) {
byte b = (byte)result;
buf.write(b);
result = bis.read();
}
System.out.println(buf.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.sudheer.test.client;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.example.employeeservice.Employee;
import com.example.employeeservice.EmployeeService;
import com.example.employeeservice.NoSuchEmployeeException;
public class SoapClient {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]
{"/client-beans.xml"});
EmployeeService client = (EmployeeService) context.
getBean("orderClient");
// Populate the Order bean
Employee employee;
try {
employee = client.getEmployeesByName("Ryan");
System.out.println("Employee Name : "+employee.getName());
} catch (NoSuchEmployeeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
client-bean.xml
This will be used in SoapClient java
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:client id="orderClient" serviceClass=
"com.example.employeeservice.EmployeeService" address=
"http://localhost:8080/cxfpoc/EmployeeService" />
</beans>
cxfbeans.xml
Used to expose Restful and webservice
<?xml version="1.0" encoding="UTF-8"?>
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for additional
information regarding copyright ownership. The ASF licenses this file to
you under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of
the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License. -->
<!-- START SNIPPET: beans -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" >
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="employeeServicesRS" class="com.hrblock.cxf.demo.servImpl.EmployeeServiceImpl" />
<jaxrs:server id="EmployeeServiceRS" address="/employeeservice" >
<jaxrs:serviceBeans>
<ref bean="employeeServicesRS" />
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
</jaxrs:providers>
</jaxrs:server>
<jaxws:endpoint id="EmployeeService"
implementor="#employeeServicesRS" address="/EmployeeService" />
<aop:config>
<!-- Method level entry and exit logging -->
<aop:aspect ref="beforeAndAfterLogging">
<aop:pointcut expression="within(com.hrblock.cxf.demo.servImpl.*)" id="before-method" />
<aop:before method="beforeMethod" pointcut-ref="before-method" />
</aop:aspect>
<aop:aspect ref="beforeAndAfterLogging">
<aop:pointcut expression="within(com.hrblock.cxf.demo.servImpl.*)" id="after-method" />
<aop:after method="afterMethod" pointcut-ref="after-method" />
</aop:aspect>
</aop:config>
<bean id="beforeAndAfterLogging" class="com.hrblock.cxf.intercepters.logging.DemoLoggingInterceptor">
<property name="category" value="Information"></property>
<property name="level" value="INFO"></property>
</bean>
</beans>
<!-- END SNIPPET: beans -->
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/cxfbeans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javatch.cxf</groupId>
<artifactId>cxfpoc</artifactId>
<packaging>war</packaging>
<version>1</version>
<name>com.javatch.cxf Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<cxf.version>2.5.1</cxf.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<resources>
<resource>
<directory>src/main/resources/wsdl</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1</version>
<configuration>
<!-- <webXml>${cxf.release.base}/etc/web.xml</webXml> -->
<webResources>
<resource>
<directory>src/main/resources/wsdl</directory>
<targetPath>WEB-INF</targetPath>
<includes>
<include>*.wsdl</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<targetPath>WEB-INF</targetPath>
<includes>
<include>**.*</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>${cxf.version}</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${basedir}/target/generated/cxf</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>src/main/resources/wsdl/EmployeeService.wsdl</wsdl>
<!-- <bindingFiles> <bindingFile>${basedir}/wsdl/binding.xml</bindingFile>
</bindingFiles> -->
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Service listings and WADL queries
Links to WADL instances for RESTful endpoints are available from {base endpointaddress}/services, in addition to SOAP endpoints if any.
Base address : 'http://localhost:8080'
WAR name : 'restpoc'
CXFServlet : '/books/*'
jaxrs:server/@address = '/getemployee'
and visiting
http://localhost:8080/restpoc/books
http://localhost:8080/restpoc/books/services
will let you see all the WADL links.
Going to the service listings page is not the only way to see WADL instances, one can also get it using a ?_wadl query.
http://localhost:8080/restpoc/books/getemployee?_wadl
will give you the description of all the root resource classes registered
with a given jaxrs:server endpoint.
For example, if the following 2 root resource classes has been registered with this endpoint:
@Path("/fiction")
public class FictionBookgetemployee {
}
@Path("/sport")
public class SportBookgetemployee {
}
then WADL will contain the description of both FictionBookgetemployee and SportBookgetemployee resources.
> http://localhost:8080/restpoc/books/getemployee/fiction?_wadl
> http://localhost:8080/restpoc/books/getemployee/sport?_wadl
Service listings and WADL queries - Jersey
To get the WADL from Jersey
WAR NAME - Jersey-Sample
Jersey Servlet Mapping - /*
http://localhost:8080/Jersey-Sample/application.wadl
Use this URL to call the below service
http://localhost:8080/Jersey-Sample/getemployee/sdheer/32
@Path("/")
public class EmployeeServiceImpl{
@Path("/getemployee/{name}/{name}")
@Produces(value = {"application/json" })
public Employee getEmployeesByName(@PathParam("name") String name,@PathParam("age") int age)
Use this URL to call the below service
@Path("/")
public class EmployeeServiceImpl{
http://localhost:8080/Jersey-Sample/
@GET
@Produces(value = {"application/json" })
public Employee getEmployeesByName()
You cannot have two different services like below without proper path
@GET
@Produces(value = {"application/json" })
public Employee getEmployeesByName(){
}
@GET
@Produces(value = {"application/json" })
public Employee anotherMethod(){
}
Error, A message body writer for Java type, class com.jersey.demo.beans.Employee, and MIME media type, application/json, was not found
Add @XmlRootElement top of the bean class Employee
A Complete Simple Jersey Rest Service Example
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>Jersey Sample</display-name>
<servlet>
<display-name>JAX-RS REST Servlet</display-name>
<servlet-name>services</servlet-name>
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.jersey.demo.servImpl</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>services</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
package com.jersey.demo.servImpl;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import com.jersey.demo.beans.Employee;
@Path("/")
public class EmployeeServiceImpl{
@GET
@Path("/getemployee/{name}/{name}")
@Produces(value = {"application/json" })
public Employee getEmployeesByName(){
Employee employee = new Employee();
employee.setName("name");
employee.setAge(123);
return employee;
}
}
package com.jersey.demo.beans;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Employee {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}