diff --git a/jersey/pom.xml b/jersey/pom.xml
new file mode 100644
index 0000000000..0c8b6b9281
--- /dev/null
+++ b/jersey/pom.xml
@@ -0,0 +1,63 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ jersey
+ 0.0.1-SNAPSHOT
+ war
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+ 2.26
+ 1.7.25
+ 3.2.0
+
+
+
+ jersey
+
+
+ maven-war-plugin
+ ${maven-war-plugin.version}
+
+ false
+
+
+
+
+
+
+
+ org.glassfish.jersey.core
+ jersey-server
+ ${jersey.version}
+
+
+ org.glassfish.jersey.core
+ jersey-client
+ ${jersey.version}
+
+
+ org.glassfish.jersey.bundles
+ jaxrs-ri
+ ${jersey.version}
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+
+
+
+
+
diff --git a/jersey/src/main/java/com/baeldung/jersey/client/JerseyClient.java b/jersey/src/main/java/com/baeldung/jersey/client/JerseyClient.java
new file mode 100644
index 0000000000..88ad891411
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/client/JerseyClient.java
@@ -0,0 +1,45 @@
+package com.baeldung.jersey.client;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+
+import com.baeldung.jersey.client.filter.RequestClientFilter;
+import com.baeldung.jersey.client.filter.ResponseClientFilter;
+import com.baeldung.jersey.client.interceptor.RequestClientWriterInterceptor;
+
+public class JerseyClient {
+
+ private static final String URI_GREETINGS = "http://localhost:8080/jersey/greetings";
+
+ public static String getHelloGreeting() {
+ return createClient().target(URI_GREETINGS)
+ .request()
+ .get(String.class);
+ }
+
+ public static String getHiGreeting() {
+ return createClient().target(URI_GREETINGS + "/hi")
+ .request()
+ .get(String.class);
+ }
+
+ public static Response getCustomGreeting() {
+ return createClient().target(URI_GREETINGS + "/custom")
+ .request()
+ .post(Entity.text("custom"));
+ }
+
+ private static Client createClient() {
+ ClientConfig config = new ClientConfig();
+ config.register(RequestClientFilter.class);
+ config.register(ResponseClientFilter.class);
+ config.register(RequestClientWriterInterceptor.class);
+
+ return ClientBuilder.newClient(config);
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/client/filter/RequestClientFilter.java b/jersey/src/main/java/com/baeldung/jersey/client/filter/RequestClientFilter.java
new file mode 100644
index 0000000000..8c6ac2c5fb
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/client/filter/RequestClientFilter.java
@@ -0,0 +1,24 @@
+package com.baeldung.jersey.client.filter;
+
+import java.io.IOException;
+
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.ext.Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Provider
+public class RequestClientFilter implements ClientRequestFilter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RequestClientFilter.class);
+
+ @Override
+ public void filter(ClientRequestContext requestContext) throws IOException {
+ LOG.info("Request client filter");
+
+ requestContext.setProperty("test", "test client request filter");
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/client/filter/ResponseClientFilter.java b/jersey/src/main/java/com/baeldung/jersey/client/filter/ResponseClientFilter.java
new file mode 100644
index 0000000000..1676fa2094
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/client/filter/ResponseClientFilter.java
@@ -0,0 +1,26 @@
+package com.baeldung.jersey.client.filter;
+
+import java.io.IOException;
+
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientResponseContext;
+import javax.ws.rs.client.ClientResponseFilter;
+import javax.ws.rs.ext.Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Provider
+public class ResponseClientFilter implements ClientResponseFilter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ResponseClientFilter.class);
+
+ @Override
+ public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
+ LOG.info("Response client filter");
+
+ responseContext.getHeaders()
+ .add("X-Test-Client", "Test response client filter");
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/client/interceptor/RequestClientWriterInterceptor.java b/jersey/src/main/java/com/baeldung/jersey/client/interceptor/RequestClientWriterInterceptor.java
new file mode 100644
index 0000000000..7216cf18cc
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/client/interceptor/RequestClientWriterInterceptor.java
@@ -0,0 +1,28 @@
+package com.baeldung.jersey.client.interceptor;
+
+import java.io.IOException;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.ext.Provider;
+import javax.ws.rs.ext.WriterInterceptor;
+import javax.ws.rs.ext.WriterInterceptorContext;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Provider
+public class RequestClientWriterInterceptor implements WriterInterceptor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RequestClientWriterInterceptor.class);
+
+ @Override
+ public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
+ LOG.info("request writer interceptor in the client side");
+
+ context.getOutputStream()
+ .write(("Message added in the writer interceptor in the client side").getBytes());
+
+ context.proceed();
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java b/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java
new file mode 100644
index 0000000000..5e2781ee3c
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java
@@ -0,0 +1,29 @@
+package com.baeldung.jersey.server;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import com.baeldung.jersey.server.config.HelloBinding;
+
+@Path("/greetings")
+public class Greetings {
+
+ @GET
+ @HelloBinding
+ public String getHelloGreeting() {
+ return "hello";
+ }
+
+ @GET
+ @Path("/hi")
+ public String getHiGreeting() {
+ return "hi";
+ }
+
+ @POST
+ @Path("/custom")
+ public String getCustomGreeting(String name) {
+ return "hello " + name;
+ }
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/config/HelloBinding.java b/jersey/src/main/java/com/baeldung/jersey/server/config/HelloBinding.java
new file mode 100644
index 0000000000..49b11adeab
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/config/HelloBinding.java
@@ -0,0 +1,11 @@
+package com.baeldung.jersey.server.config;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import javax.ws.rs.NameBinding;
+
+@NameBinding
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HelloBinding {
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/config/HelloDynamicBinding.java b/jersey/src/main/java/com/baeldung/jersey/server/config/HelloDynamicBinding.java
new file mode 100644
index 0000000000..e56cdec140
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/config/HelloDynamicBinding.java
@@ -0,0 +1,31 @@
+package com.baeldung.jersey.server.config;
+
+import javax.ws.rs.container.DynamicFeature;
+import javax.ws.rs.container.ResourceInfo;
+import javax.ws.rs.core.FeatureContext;
+import javax.ws.rs.ext.Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.baeldung.jersey.server.Greetings;
+import com.baeldung.jersey.server.filter.ResponseServerFilter;
+
+@Provider
+public class HelloDynamicBinding implements DynamicFeature {
+
+ private static final Logger LOG = LoggerFactory.getLogger(HelloDynamicBinding.class);
+
+ @Override
+ public void configure(ResourceInfo resourceInfo, FeatureContext context) {
+ LOG.info("Hello dynamic binding");
+
+ if (Greetings.class.equals(resourceInfo.getResourceClass()) && resourceInfo.getResourceMethod()
+ .getName()
+ .contains("HiGreeting")) {
+ context.register(ResponseServerFilter.class);
+ }
+
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/config/ServerConfig.java b/jersey/src/main/java/com/baeldung/jersey/server/config/ServerConfig.java
new file mode 100644
index 0000000000..4670cc291c
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/config/ServerConfig.java
@@ -0,0 +1,14 @@
+package com.baeldung.jersey.server.config;
+
+import javax.ws.rs.ApplicationPath;
+
+import org.glassfish.jersey.server.ResourceConfig;
+
+@ApplicationPath("/*")
+public class ServerConfig extends ResourceConfig {
+
+ public ServerConfig() {
+ packages("com.baeldung.jersey.server");
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/filter/PrematchingRequestFilter.java b/jersey/src/main/java/com/baeldung/jersey/server/filter/PrematchingRequestFilter.java
new file mode 100644
index 0000000000..181fa7f043
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/filter/PrematchingRequestFilter.java
@@ -0,0 +1,27 @@
+package com.baeldung.jersey.server.filter;
+
+import java.io.IOException;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.ext.Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Provider
+@PreMatching
+public class PrematchingRequestFilter implements ContainerRequestFilter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PrematchingRequestFilter.class);
+
+ @Override
+ public void filter(ContainerRequestContext ctx) throws IOException {
+ LOG.info("prematching filter");
+ if (ctx.getMethod()
+ .equals("DELETE")) {
+ LOG.info("\"Deleting request");
+ }
+ }
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/filter/ResponseServerFilter.java b/jersey/src/main/java/com/baeldung/jersey/server/filter/ResponseServerFilter.java
new file mode 100644
index 0000000000..de0dcbdce7
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/filter/ResponseServerFilter.java
@@ -0,0 +1,23 @@
+package com.baeldung.jersey.server.filter;
+
+import java.io.IOException;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ResponseServerFilter implements ContainerResponseFilter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ResponseServerFilter.class);
+
+ @Override
+ public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
+ LOG.info("Response server filter");
+
+ responseContext.getHeaders()
+ .add("X-Test", "Filter test");
+ }
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/filter/RestrictedOperationsRequestFilter.java b/jersey/src/main/java/com/baeldung/jersey/server/filter/RestrictedOperationsRequestFilter.java
new file mode 100644
index 0000000000..cb0cd185f7
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/filter/RestrictedOperationsRequestFilter.java
@@ -0,0 +1,36 @@
+package com.baeldung.jersey.server.filter;
+
+import java.io.IOException;
+
+import javax.annotation.Priority;
+import javax.ws.rs.Priorities;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Provider;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.baeldung.jersey.server.config.HelloBinding;
+
+@Provider
+@Priority(Priorities.AUTHORIZATION)
+@HelloBinding
+public class RestrictedOperationsRequestFilter implements ContainerRequestFilter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RestrictedOperationsRequestFilter.class);
+
+ @Override
+ public void filter(ContainerRequestContext ctx) throws IOException {
+ LOG.info("Restricted operations filter");
+ if (ctx.getLanguage() != null && "EN".equals(ctx.getLanguage()
+ .getLanguage())) {
+ LOG.info("Aborting request");
+ ctx.abortWith(Response.status(Response.Status.FORBIDDEN)
+ .entity("Cannot access")
+ .build());
+ }
+
+ }
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/interceptor/RequestServerReaderInterceptor.java b/jersey/src/main/java/com/baeldung/jersey/server/interceptor/RequestServerReaderInterceptor.java
new file mode 100644
index 0000000000..e9cc57fc2a
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/interceptor/RequestServerReaderInterceptor.java
@@ -0,0 +1,36 @@
+package com.baeldung.jersey.server.interceptor;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.stream.Collectors;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.ext.Provider;
+import javax.ws.rs.ext.ReaderInterceptor;
+import javax.ws.rs.ext.ReaderInterceptorContext;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Provider
+public class RequestServerReaderInterceptor implements ReaderInterceptor {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RequestServerReaderInterceptor.class);
+
+ @Override
+ public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
+ LOG.info("Request reader interceptor in the server side");
+
+ InputStream is = context.getInputStream();
+ String body = new BufferedReader(new InputStreamReader(is)).lines()
+ .collect(Collectors.joining("\n"));
+
+ context.setInputStream(new ByteArrayInputStream((body + " message added in server reader interceptor").getBytes()));
+
+ return context.proceed();
+ }
+
+}
diff --git a/jersey/src/main/resources/logback.xml b/jersey/src/main/resources/logback.xml
new file mode 100644
index 0000000000..d87a87bf53
--- /dev/null
+++ b/jersey/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %date [%thread] %-5level %logger{36} - %message%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jersey/src/test/java/com/baeldung/jersey/client/JerseyClientTest.java b/jersey/src/test/java/com/baeldung/jersey/client/JerseyClientTest.java
new file mode 100644
index 0000000000..b4bdccfd86
--- /dev/null
+++ b/jersey/src/test/java/com/baeldung/jersey/client/JerseyClientTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.jersey.client;
+
+import javax.ws.rs.core.Response;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class JerseyClientTest {
+
+ private static int HTTP_OK = 200;
+
+ @Test
+ public void getHelloGreetingTest() {
+ String response = JerseyClient.getHelloGreeting();
+
+ Assert.assertEquals("hello", response);
+ }
+
+ @Test
+ public void getHiGreetingTest() {
+ String response = JerseyClient.getHiGreeting();
+
+ Assert.assertEquals("hi", response);
+ }
+
+ @Test
+ public void getCustomGreetingTest() {
+ Response response = JerseyClient.getCustomGreeting();
+
+ Assert.assertEquals(HTTP_OK, response.getStatus());
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index fc0c8f8ba7..271fb847d3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,6 +1,5 @@
-
+
4.0.0
com.baeldung
parent-modules
@@ -281,7 +280,8 @@
lucene
vraptor
persistence-modules/java-cockroachdb
-
+ jersey
+
@@ -384,4 +384,4 @@
-
+
\ No newline at end of file