diff --git a/apache-cxf/cxf-jaxrs-implementation/pom.xml b/apache-cxf/cxf-jaxrs-implementation/pom.xml
new file mode 100644
index 0000000000..1f83ecf934
--- /dev/null
+++ b/apache-cxf/cxf-jaxrs-implementation/pom.xml
@@ -0,0 +1,54 @@
+
+
+
+ 4.0.0
+ cxf-jaxrs-implementation
+
+ com.baeldung
+ apache-cxf
+ 0.0.1-SNAPSHOT
+
+
+ UTF-8
+ 3.1.7
+ 4.5.2
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+
+ com.baeldung.cxf.jaxrs.implementation.RestfulServer
+
+
+
+ maven-surefire-plugin
+ 2.19.1
+
+
+ **/ServiceTest
+
+
+
+
+
+
+
+ org.apache.cxf
+ cxf-rt-frontend-jaxrs
+ ${cxf.version}
+
+
+ org.apache.cxf
+ cxf-rt-transports-http-jetty
+ ${cxf.version}
+
+
+ org.apache.httpcomponents
+ httpclient
+ ${httpclient.version}
+
+
+
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Baeldung.java b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Baeldung.java
new file mode 100644
index 0000000000..5617f482f8
--- /dev/null
+++ b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Baeldung.java
@@ -0,0 +1,68 @@
+package com.baeldung.cxf.jaxrs.implementation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+
+@Path("baeldung")
+@Produces("text/xml")
+public class Baeldung {
+ private Map courses = new HashMap<>();
+
+ {
+ Student student1 = new Student();
+ Student student2 = new Student();
+ student1.setId(1);
+ student1.setName("Student A");
+ student2.setId(2);
+ student2.setName("Student B");
+
+ List course1Students = new ArrayList<>();
+ course1Students.add(student1);
+ course1Students.add(student2);
+
+ Course course1 = new Course();
+ Course course2 = new Course();
+ course1.setId(1);
+ course1.setName("REST with Spring");
+ course1.setStudents(course1Students);
+ course2.setId(2);
+ course2.setName("Learn Spring Security");
+
+ courses.put(1, course1);
+ courses.put(2, course2);
+ }
+
+ @GET
+ @Path("courses/{courseOrder}")
+ public Course getCourse(@PathParam("courseOrder") int courseOrder) {
+ return courses.get(courseOrder);
+ }
+
+ @PUT
+ @Path("courses/{courseOrder}")
+ public Response putCourse(@PathParam("courseOrder") int courseOrder, Course course) {
+ Course existingCourse = courses.get(courseOrder);
+ Response response;
+ if (existingCourse == null || existingCourse.getId() != course.getId() || !(existingCourse.getName().equals(course.getName()))) {
+ courses.put(courseOrder, course);
+ response = Response.ok().build();
+ } else {
+ response = Response.notModified().build();
+ }
+ return response;
+ }
+
+ @Path("courses/{courseOrder}/students")
+ public Course pathToStudent(@PathParam("courseOrder") int courseOrder) {
+ return courses.get(courseOrder);
+ }
+}
\ No newline at end of file
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Course.java b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Course.java
new file mode 100644
index 0000000000..9ab74bea58
--- /dev/null
+++ b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Course.java
@@ -0,0 +1,73 @@
+package com.baeldung.cxf.jaxrs.implementation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Response;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "Course")
+public class Course {
+ private int id;
+ private String name;
+ private List students;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List getStudents() {
+ return students;
+ }
+
+ public void setStudents(List students) {
+ this.students = students;
+ }
+
+ @GET
+ @Path("{studentOrder}")
+ public Student getStudent(@PathParam("studentOrder")int studentOrder) {
+ return students.get(studentOrder);
+ }
+
+ @POST
+ public Response postStudent(Student student) {
+ if (students == null) {
+ students = new ArrayList();
+ }
+ students.add(student);
+ return Response.ok(student).build();
+ }
+
+ @DELETE
+ @Path("{studentOrder}")
+ public Response deleteStudent(@PathParam("studentOrder") int studentOrder) {
+ Student student = students.get(studentOrder);
+ Response response;
+ if (student != null) {
+ students.remove(studentOrder);
+ response = Response.ok().build();
+ } else {
+ response = Response.notModified().build();
+ }
+ return response;
+ }
+}
\ No newline at end of file
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/RestfulServer.java b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/RestfulServer.java
new file mode 100644
index 0000000000..bb35bab3f8
--- /dev/null
+++ b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/RestfulServer.java
@@ -0,0 +1,21 @@
+package com.baeldung.cxf.jaxrs.implementation;
+
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+
+public class RestfulServer {
+ public static void main(String args[]) throws Exception {
+ JAXRSServerFactoryBean factoryBean = new JAXRSServerFactoryBean();
+ factoryBean.setResourceClasses(Baeldung.class);
+ factoryBean.setResourceProvider(new SingletonResourceProvider(new Baeldung()));
+ factoryBean.setAddress("http://localhost:8080/");
+ Server server = factoryBean.create();
+
+ System.out.println("Server ready...");
+ Thread.sleep(60 * 1000);
+ System.out.println("Server exiting");
+ server.destroy();
+ System.exit(0);
+ }
+}
\ No newline at end of file
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Student.java b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Student.java
new file mode 100644
index 0000000000..de782e4edb
--- /dev/null
+++ b/apache-cxf/cxf-jaxrs-implementation/src/main/java/com/baeldung/cxf/jaxrs/implementation/Student.java
@@ -0,0 +1,25 @@
+package com.baeldung.cxf.jaxrs.implementation;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "Student")
+public class Student {
+ private int id;
+ private String name;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
\ No newline at end of file
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/course.xml b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/course.xml
new file mode 100644
index 0000000000..465c337745
--- /dev/null
+++ b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/course.xml
@@ -0,0 +1,4 @@
+
+ 3
+ Apache CXF Support for RESTful
+
\ No newline at end of file
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/main/resources/student.xml b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/student.xml
new file mode 100644
index 0000000000..7fb6189815
--- /dev/null
+++ b/apache-cxf/cxf-jaxrs-implementation/src/main/resources/student.xml
@@ -0,0 +1,5 @@
+
+
+ 3
+ Student C
+
\ No newline at end of file
diff --git a/apache-cxf/cxf-jaxrs-implementation/src/test/java/com/baeldung/cxf/jaxrs/implementation/ServiceTest.java b/apache-cxf/cxf-jaxrs-implementation/src/test/java/com/baeldung/cxf/jaxrs/implementation/ServiceTest.java
new file mode 100644
index 0000000000..48749a568e
--- /dev/null
+++ b/apache-cxf/cxf-jaxrs-implementation/src/test/java/com/baeldung/cxf/jaxrs/implementation/ServiceTest.java
@@ -0,0 +1,93 @@
+package com.baeldung.cxf.jaxrs.implementation;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+import javax.xml.bind.JAXB;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.InputStreamEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+
+public class ServiceTest {
+ private static final String BASE_URL = "http://localhost:8080/baeldung/courses/";
+ private static CloseableHttpClient client;
+
+ @BeforeClass
+ public static void createClient() {
+ client = HttpClients.createDefault();
+ }
+
+ @AfterClass
+ public static void closeClient() throws IOException {
+ client.close();
+ }
+
+ @Test
+ public void whenPutCourse_thenCorrect() throws IOException {
+ HttpPut httpPut = new HttpPut(BASE_URL + "3");
+ InputStream resourceStream = this.getClass().getClassLoader().getResourceAsStream("course.xml");
+ httpPut.setEntity(new InputStreamEntity(resourceStream));
+ httpPut.setHeader("Content-Type", "text/xml");
+
+ HttpResponse response = client.execute(httpPut);
+ assertEquals(200, response.getStatusLine().getStatusCode());
+
+ Course course = getCourse(3);
+ assertEquals(3, course.getId());
+ assertEquals("Apache CXF Support for RESTful", course.getName());
+ }
+
+ @Test
+ public void whenPostStudent_thenCorrect() throws IOException {
+ HttpPost httpPost = new HttpPost(BASE_URL + "2/students");
+ InputStream resourceStream = this.getClass().getClassLoader().getResourceAsStream("student.xml");
+ httpPost.setEntity(new InputStreamEntity(resourceStream));
+ httpPost.setHeader("Content-Type", "text/xml");
+
+ HttpResponse response = client.execute(httpPost);
+ assertEquals(200, response.getStatusLine().getStatusCode());
+
+ Student student = getStudent(2, 0);
+ assertEquals(3, student.getId());
+ assertEquals("Student C", student.getName());
+ }
+
+ @Test
+ public void whenDeleteStudent_thenCorrect() throws IOException {
+ HttpDelete httpDelete = new HttpDelete(BASE_URL + "1/students/0");
+ HttpResponse response = client.execute(httpDelete);
+ assertEquals(200, response.getStatusLine().getStatusCode());
+
+ Course course = getCourse(1);
+ assertEquals(1, course.getStudents().size());
+ assertEquals(2, course.getStudents().get(0).getId());
+ assertEquals("Student B", course.getStudents().get(0).getName());
+ }
+
+ private Course getCourse(int courseOrder) throws IOException {
+ URL url = new URL(BASE_URL + courseOrder);
+ InputStream input = url.openStream();
+ Course course = JAXB.unmarshal(new InputStreamReader(input), Course.class);
+ return course;
+ }
+
+ private Student getStudent(int courseOrder, int studentOrder) throws IOException {
+ URL url = new URL(BASE_URL + courseOrder + "/students/" + studentOrder);
+ InputStream input = url.openStream();
+ Student student = JAXB.unmarshal(new InputStreamReader(input), Student.class);
+ return student;
+ }
+}
\ No newline at end of file
diff --git a/apache-cxf/pom.xml b/apache-cxf/pom.xml
index 022fc59f9b..af7949bb6c 100644
--- a/apache-cxf/pom.xml
+++ b/apache-cxf/pom.xml
@@ -8,6 +8,7 @@
cxf-introduction
cxf-spring
+ cxf-jaxrs-implementation