JAVA-29231 Move modules inside existing container modules (#15492)
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
## Jersey
|
||||
|
||||
This module contains articles about Jersey.
|
||||
|
||||
### Relevant Articles
|
||||
- [Jersey Filters and Interceptors](https://www.baeldung.com/jersey-filters-interceptors)
|
||||
- [Jersey MVC Support](https://www.baeldung.com/jersey-mvc)
|
||||
- [Bean Validation in Jersey](https://www.baeldung.com/jersey-bean-validation)
|
||||
- [Set a Response Body in JAX-RS](https://www.baeldung.com/jax-rs-response)
|
||||
- [Exploring the Jersey Test Framework](https://www.baeldung.com/jersey-test)
|
||||
- [Explore Jersey Request Parameters](https://www.baeldung.com/jersey-request-parameters)
|
||||
- [Add a Header to a Jersey SSE Client Request](https://www.baeldung.com/jersey-sse-client-request-headers)
|
||||
- [Exception Handling With Jersey](https://www.baeldung.com/java-exception-handling-jersey)
|
||||
- [@FormDataParam vs. @FormParam in Jersey](https://www.baeldung.com/jersey-formdataparam-vs-formparam)
|
||||
- [Add a List as Query Parameter in Jersey](https://www.baeldung.com/java-jersey-list-query-param)
|
||||
@@ -0,0 +1,110 @@
|
||||
<?xml version="1.0"?>
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>jersey</artifactId>
|
||||
<name>jersey</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>web-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.core</groupId>
|
||||
<artifactId>jersey-server</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.core</groupId>
|
||||
<artifactId>jersey-client</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.bundles</groupId>
|
||||
<artifactId>jaxrs-ri</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.containers</groupId>
|
||||
<artifactId>jersey-container-grizzly2-servlet</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.ext</groupId>
|
||||
<artifactId>jersey-mvc-freemarker</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.ext</groupId>
|
||||
<artifactId>jersey-bean-validation</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.security</groupId>
|
||||
<artifactId>oauth1-client</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.security</groupId>
|
||||
<artifactId>oauth2-client</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.media</groupId>
|
||||
<artifactId>jersey-media-sse</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.test-framework</groupId>
|
||||
<artifactId>jersey-test-framework-core</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
|
||||
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.connectors</groupId>
|
||||
<artifactId>jersey-apache-connector</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.media</groupId>
|
||||
<artifactId>jersey-media-multipart</artifactId>
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>jersey</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>${maven-war-plugin.version}</version>
|
||||
<configuration>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<mainClass>com.baeldung.jersey.server.http.EmbeddedHttpServer</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<jersey.version>3.1.1</jersey.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.baeldung.jersey.client;
|
||||
|
||||
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;
|
||||
import com.baeldung.jersey.server.Greetings;
|
||||
|
||||
import jakarta.ws.rs.client.Client;
|
||||
import jakarta.ws.rs.client.ClientBuilder;
|
||||
import jakarta.ws.rs.client.Entity;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
public class JerseyClient {
|
||||
|
||||
public 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);
|
||||
config.register(Greetings.class);
|
||||
|
||||
return ClientBuilder.newClient(config);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package com.baeldung.jersey.client;
|
||||
|
||||
import com.baeldung.jersey.client.filter.AddHeaderOnRequestFilter;
|
||||
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
|
||||
import org.glassfish.jersey.client.ClientConfig;
|
||||
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
|
||||
import org.glassfish.jersey.client.oauth1.AccessToken;
|
||||
import org.glassfish.jersey.client.oauth1.ConsumerCredentials;
|
||||
import org.glassfish.jersey.client.oauth1.OAuth1ClientSupport;
|
||||
import org.glassfish.jersey.client.oauth2.OAuth2ClientSupport;
|
||||
|
||||
import static org.glassfish.jersey.client.authentication.HttpAuthenticationFeature.*;
|
||||
|
||||
import jakarta.ws.rs.client.Client;
|
||||
import jakarta.ws.rs.client.ClientBuilder;
|
||||
import jakarta.ws.rs.client.Invocation;
|
||||
import jakarta.ws.rs.client.WebTarget;
|
||||
import jakarta.ws.rs.core.Feature;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.sse.InboundSseEvent;
|
||||
import jakarta.ws.rs.sse.SseEventSource;
|
||||
|
||||
public class JerseyClientHeaders {
|
||||
|
||||
private static final String BEARER_CONSUMER_SECRET = "my-consumer-secret";
|
||||
private static final String BEARER_ACCESS_TOKEN_SECRET = "my-access-token-secret";
|
||||
private static final String TARGET = "http://localhost:9998/";
|
||||
private static final String MAIN_RESOURCE = "echo-headers";
|
||||
private static final String RESOURCE_AUTH_DIGEST = "digest";
|
||||
|
||||
private static String sseHeaderValue;
|
||||
|
||||
public static Response simpleHeader(String headerKey, String headerValue) {
|
||||
Client client = ClientBuilder.newClient();
|
||||
WebTarget webTarget = client.target(TARGET);
|
||||
WebTarget resourceWebTarget = webTarget.path(MAIN_RESOURCE);
|
||||
Invocation.Builder invocationBuilder = resourceWebTarget.request();
|
||||
invocationBuilder.header(headerKey, headerValue);
|
||||
return invocationBuilder.get();
|
||||
}
|
||||
|
||||
public static Response simpleHeaderFluently(String headerKey, String headerValue) {
|
||||
Client client = ClientBuilder.newClient();
|
||||
return client.target(TARGET)
|
||||
.path(MAIN_RESOURCE)
|
||||
.request()
|
||||
.header(headerKey, headerValue)
|
||||
.get();
|
||||
}
|
||||
|
||||
public static Response basicAuthenticationAtClientLevel(String username, String password) {
|
||||
//To simplify we removed de SSL/TLS protection, but it's required to have an encryption
|
||||
// when using basic authentication schema as it's send only on Base64 encoding
|
||||
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic(username, password);
|
||||
Client client = ClientBuilder.newBuilder().register(feature).build();
|
||||
return client.target(TARGET)
|
||||
.path(MAIN_RESOURCE)
|
||||
.request()
|
||||
.get();
|
||||
}
|
||||
|
||||
public static Response basicAuthenticationAtRequestLevel(String username, String password) {
|
||||
//To simplify we removed de SSL/TLS protection, but it's required to have an encryption
|
||||
// when using basic authentication schema as it's send only on Base64 encoding
|
||||
HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder().build();
|
||||
Client client = ClientBuilder.newBuilder().register(feature).build();
|
||||
return client.target(TARGET)
|
||||
.path(MAIN_RESOURCE)
|
||||
.request()
|
||||
.property(HTTP_AUTHENTICATION_BASIC_USERNAME, username)
|
||||
.property(HTTP_AUTHENTICATION_BASIC_PASSWORD, password)
|
||||
.get();
|
||||
}
|
||||
|
||||
public static Response digestAuthenticationAtClientLevel(String username, String password) {
|
||||
HttpAuthenticationFeature feature = HttpAuthenticationFeature.digest(username, password);
|
||||
Client client = ClientBuilder.newBuilder().register(feature).build();
|
||||
return client.target(TARGET)
|
||||
.path(MAIN_RESOURCE)
|
||||
.path(RESOURCE_AUTH_DIGEST)
|
||||
.request()
|
||||
.get();
|
||||
}
|
||||
|
||||
public static Response digestAuthenticationAtRequestLevel(String username, String password) {
|
||||
HttpAuthenticationFeature feature = HttpAuthenticationFeature.digest();
|
||||
|
||||
Client client = ClientBuilder.newBuilder().register(feature).build();
|
||||
return client.target(TARGET)
|
||||
.path(MAIN_RESOURCE)
|
||||
.path(RESOURCE_AUTH_DIGEST)
|
||||
.request()
|
||||
.property(HTTP_AUTHENTICATION_DIGEST_USERNAME, username)
|
||||
.property(HTTP_AUTHENTICATION_DIGEST_PASSWORD, password)
|
||||
.get();
|
||||
}
|
||||
|
||||
public static Response bearerAuthenticationWithOAuth1AtClientLevel(String token, String consumerKey) {
|
||||
ConsumerCredentials consumerCredential = new ConsumerCredentials(consumerKey, BEARER_CONSUMER_SECRET);
|
||||
AccessToken accessToken = new AccessToken(token, BEARER_ACCESS_TOKEN_SECRET);
|
||||
Feature feature = OAuth1ClientSupport
|
||||
.builder(consumerCredential)
|
||||
.feature()
|
||||
.accessToken(accessToken)
|
||||
.build();
|
||||
|
||||
Client client = ClientBuilder.newBuilder().register(feature).build();
|
||||
return client.target(TARGET)
|
||||
.path(MAIN_RESOURCE)
|
||||
.request()
|
||||
.get();
|
||||
}
|
||||
|
||||
public static Response bearerAuthenticationWithOAuth1AtRequestLevel(String token, String consumerKey) {
|
||||
ConsumerCredentials consumerCredential = new ConsumerCredentials(consumerKey, BEARER_CONSUMER_SECRET);
|
||||
AccessToken accessToken = new AccessToken(token, BEARER_ACCESS_TOKEN_SECRET);
|
||||
Feature feature = OAuth1ClientSupport
|
||||
.builder(consumerCredential)
|
||||
.feature()
|
||||
.build();
|
||||
|
||||
Client client = ClientBuilder.newBuilder().register(feature).build();
|
||||
return client.target(TARGET)
|
||||
.path(MAIN_RESOURCE)
|
||||
.request()
|
||||
.property(OAuth1ClientSupport.OAUTH_PROPERTY_ACCESS_TOKEN, accessToken)
|
||||
.get();
|
||||
}
|
||||
|
||||
public static Response bearerAuthenticationWithOAuth2AtClientLevel(String token) {
|
||||
Feature feature = OAuth2ClientSupport.feature(token);
|
||||
|
||||
Client client = ClientBuilder.newBuilder().register(feature).build();
|
||||
return client.target(TARGET)
|
||||
.path(MAIN_RESOURCE)
|
||||
.request()
|
||||
.get();
|
||||
}
|
||||
|
||||
public static Response bearerAuthenticationWithOAuth2AtRequestLevel(String token, String otherToken) {
|
||||
Feature feature = OAuth2ClientSupport.feature(token);
|
||||
|
||||
Client client = ClientBuilder.newBuilder().register(feature).build();
|
||||
return client.target(TARGET)
|
||||
.path(MAIN_RESOURCE)
|
||||
.request()
|
||||
.property(OAuth2ClientSupport.OAUTH2_PROPERTY_ACCESS_TOKEN, otherToken)
|
||||
.get();
|
||||
}
|
||||
|
||||
public static Response filter() {
|
||||
Client client = ClientBuilder.newBuilder().register(AddHeaderOnRequestFilter.class).build();
|
||||
return client.target(TARGET)
|
||||
.path(MAIN_RESOURCE)
|
||||
.request()
|
||||
.get();
|
||||
}
|
||||
|
||||
public static Response sendRestrictedHeaderThroughDefaultTransportConnector(String headerKey, String headerValue) {
|
||||
ClientConfig clientConfig = new ClientConfig().connectorProvider(new ApacheConnectorProvider());
|
||||
Client client = ClientBuilder.newClient(clientConfig);
|
||||
System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
|
||||
|
||||
return client.target(TARGET)
|
||||
.path(MAIN_RESOURCE)
|
||||
.request()
|
||||
.header(headerKey, headerValue)
|
||||
.get();
|
||||
}
|
||||
|
||||
public static String simpleSSEHeader() throws InterruptedException {
|
||||
Client client = ClientBuilder.newBuilder()
|
||||
.register(AddHeaderOnRequestFilter.class)
|
||||
.build();
|
||||
|
||||
WebTarget webTarget = client.target(TARGET)
|
||||
.path(MAIN_RESOURCE)
|
||||
.path("events");
|
||||
|
||||
SseEventSource sseEventSource = SseEventSource.target(webTarget).build();
|
||||
sseEventSource.register(JerseyClientHeaders::receiveEvent);
|
||||
sseEventSource.open();
|
||||
Thread.sleep(3_000);
|
||||
sseEventSource.close();
|
||||
|
||||
return sseHeaderValue;
|
||||
}
|
||||
|
||||
private static void receiveEvent(InboundSseEvent event) {
|
||||
sseHeaderValue = event.readData();
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.jersey.client.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import jakarta.ws.rs.client.ClientRequestContext;
|
||||
import jakarta.ws.rs.client.ClientRequestFilter;
|
||||
|
||||
public class AddHeaderOnRequestFilter implements ClientRequestFilter {
|
||||
|
||||
public static final String FILTER_HEADER_VALUE = "filter-header-value";
|
||||
public static final String FILTER_HEADER_KEY = "x-filter-header";
|
||||
|
||||
@Override
|
||||
public void filter(ClientRequestContext requestContext) throws IOException {
|
||||
requestContext.getHeaders().add(FILTER_HEADER_KEY, FILTER_HEADER_VALUE);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.jersey.client.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jakarta.ws.rs.client.ClientRequestContext;
|
||||
import jakarta.ws.rs.client.ClientRequestFilter;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
|
||||
@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");
|
||||
}
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.jersey.client.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jakarta.ws.rs.client.ClientRequestContext;
|
||||
import jakarta.ws.rs.client.ClientResponseContext;
|
||||
import jakarta.ws.rs.client.ClientResponseFilter;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
|
||||
@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");
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.baeldung.jersey.client.interceptor;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jakarta.ws.rs.WebApplicationException;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
import jakarta.ws.rs.ext.WriterInterceptor;
|
||||
import jakarta.ws.rs.ext.WriterInterceptorContext;
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.jersey.client.listdemo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
|
||||
@Path("/")
|
||||
public class JerseyListDemo {
|
||||
@GET
|
||||
public String getItems(@QueryParam("items") List<String> items) {
|
||||
return "Received items: " + items;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.jersey.client.listdemo;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
public class ListDemoApp extends ResourceConfig {
|
||||
public ListDemoApp() {
|
||||
packages("com.baeldung.jersey.client.listdemo");
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.jersey.exceptionhandling;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import com.baeldung.jersey.exceptionhandling.rest.exceptions.IllegalArgumentExceptionMapper;
|
||||
import com.baeldung.jersey.exceptionhandling.rest.exceptions.ServerExceptionMapper;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
|
||||
@ApplicationPath("/exception-handling/*")
|
||||
public class ExceptionHandlingConfig extends ResourceConfig {
|
||||
|
||||
public ExceptionHandlingConfig() {
|
||||
packages("com.baeldung.jersey.exceptionhandling.rest");
|
||||
register(IllegalArgumentExceptionMapper.class);
|
||||
register(ServerExceptionMapper.class);
|
||||
}
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.jersey.exceptionhandling.data;
|
||||
|
||||
import com.baeldung.jersey.exceptionhandling.repo.Identifiable;
|
||||
|
||||
public class Stock implements Identifiable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String id;
|
||||
private Double price;
|
||||
|
||||
public Stock() {
|
||||
}
|
||||
|
||||
public Stock(String id, Double price) {
|
||||
this.id = id;
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Double getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(Double price) {
|
||||
this.price = price;
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.baeldung.jersey.exceptionhandling.data;
|
||||
|
||||
import com.baeldung.jersey.exceptionhandling.repo.Identifiable;
|
||||
|
||||
public class Wallet implements Identifiable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final Double MIN_CHARGE = 50.0;
|
||||
public static final String MIN_CHARGE_MSG = "minimum charge is: " + MIN_CHARGE;
|
||||
|
||||
private String id;
|
||||
private Double balance = 0.0;
|
||||
|
||||
public Wallet() {
|
||||
}
|
||||
|
||||
public Wallet(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Double getBalance() {
|
||||
return balance;
|
||||
}
|
||||
|
||||
public void setBalance(Double balance) {
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
public Double addBalance(Double amount) {
|
||||
if (balance == null)
|
||||
balance = 0.0;
|
||||
|
||||
return balance += amount;
|
||||
}
|
||||
|
||||
public boolean hasFunds(Double amount) {
|
||||
if (balance == null || amount == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (balance - amount) >= 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.jersey.exceptionhandling.repo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Db<T extends Identifiable> {
|
||||
private Map<String, T> db = new HashMap<>();
|
||||
|
||||
public Optional<T> findById(String id) {
|
||||
return Optional.ofNullable(db.get(id));
|
||||
}
|
||||
|
||||
public String save(T t) {
|
||||
String id = t.getId();
|
||||
if (id == null) {
|
||||
id = UUID.randomUUID()
|
||||
.toString();
|
||||
t.setId(id);
|
||||
}
|
||||
db.put(id, t);
|
||||
return id;
|
||||
}
|
||||
|
||||
public void remove(T t) {
|
||||
db.entrySet()
|
||||
.removeIf(entry -> entry.getValue()
|
||||
.getId()
|
||||
.equals(t.getId()));
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.jersey.exceptionhandling.repo;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface Identifiable extends Serializable {
|
||||
void setId(String id);
|
||||
|
||||
String getId();
|
||||
|
||||
public static void assertValid(Identifiable i) {
|
||||
if (i == null)
|
||||
throw new IllegalArgumentException("object cannot be null");
|
||||
|
||||
if (i.getId() == null)
|
||||
throw new IllegalArgumentException("object id cannot be null");
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.baeldung.jersey.exceptionhandling.rest;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.baeldung.jersey.exceptionhandling.data.Stock;
|
||||
import com.baeldung.jersey.exceptionhandling.repo.Db;
|
||||
import com.baeldung.jersey.exceptionhandling.service.Repository;
|
||||
|
||||
import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
@Path("/stocks")
|
||||
public class StocksResource {
|
||||
private static final Db<Stock> stocks = Repository.STOCKS_DB;
|
||||
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response post(Stock stock) {
|
||||
stocks.save(stock);
|
||||
|
||||
return Response.ok(stock)
|
||||
.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{ticker}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response get(@PathParam("ticker") String id) {
|
||||
Optional<Stock> stock = stocks.findById(id);
|
||||
stock.orElseThrow(() -> new IllegalArgumentException("ticker"));
|
||||
|
||||
return Response.ok(stock.get())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package com.baeldung.jersey.exceptionhandling.rest;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.baeldung.jersey.exceptionhandling.data.Stock;
|
||||
import com.baeldung.jersey.exceptionhandling.data.Wallet;
|
||||
import com.baeldung.jersey.exceptionhandling.repo.Db;
|
||||
import com.baeldung.jersey.exceptionhandling.rest.exceptions.InvalidTradeException;
|
||||
import com.baeldung.jersey.exceptionhandling.rest.exceptions.RestErrorResponse;
|
||||
import com.baeldung.jersey.exceptionhandling.service.Repository;
|
||||
|
||||
import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.PUT;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.WebApplicationException;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
@Path("/wallets")
|
||||
public class WalletsResource {
|
||||
private static final Db<Stock> stocks = Repository.STOCKS_DB;
|
||||
private static final Db<Wallet> wallets = Repository.WALLETS_DB;
|
||||
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response post(Wallet wallet) {
|
||||
wallets.save(wallet);
|
||||
|
||||
return Response.ok(wallet)
|
||||
.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response get(@PathParam("id") String id) {
|
||||
Optional<Wallet> wallet = wallets.findById(id);
|
||||
wallet.orElseThrow(IllegalArgumentException::new);
|
||||
|
||||
return Response.ok(wallet.get())
|
||||
.build();
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/{amount}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response putAmount(@PathParam("id") String id, @PathParam("amount") Double amount) {
|
||||
Optional<Wallet> wallet = wallets.findById(id);
|
||||
wallet.orElseThrow(IllegalArgumentException::new);
|
||||
|
||||
if (amount < Wallet.MIN_CHARGE) {
|
||||
throw new InvalidTradeException(Wallet.MIN_CHARGE_MSG);
|
||||
}
|
||||
|
||||
wallet.get()
|
||||
.addBalance(amount);
|
||||
wallets.save(wallet.get());
|
||||
|
||||
return Response.ok(wallet)
|
||||
.build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/{wallet}/buy/{ticker}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response postBuyStock(@PathParam("wallet") String walletId, @PathParam("ticker") String id) {
|
||||
Optional<Stock> stock = stocks.findById(id);
|
||||
stock.orElseThrow(InvalidTradeException::new);
|
||||
|
||||
Optional<Wallet> w = wallets.findById(walletId);
|
||||
w.orElseThrow(InvalidTradeException::new);
|
||||
|
||||
Wallet wallet = w.get();
|
||||
Double price = stock.get()
|
||||
.getPrice();
|
||||
|
||||
if (!wallet.hasFunds(price)) {
|
||||
RestErrorResponse response = new RestErrorResponse();
|
||||
response.setSubject(wallet);
|
||||
response.setMessage("insufficient balance");
|
||||
throw new WebApplicationException(Response.status(Response.Status.NOT_ACCEPTABLE)
|
||||
.entity(response)
|
||||
.build());
|
||||
}
|
||||
|
||||
wallet.addBalance(-price);
|
||||
wallets.save(wallet);
|
||||
|
||||
return Response.ok(wallet)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.baeldung.jersey.exceptionhandling.rest.exceptions;
|
||||
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.ext.ExceptionMapper;
|
||||
|
||||
public class IllegalArgumentExceptionMapper implements ExceptionMapper<IllegalArgumentException> {
|
||||
public static final String DEFAULT_MESSAGE = "an illegal argument was provided";
|
||||
|
||||
@Override
|
||||
public Response toResponse(final IllegalArgumentException exception) {
|
||||
return Response.status(Response.Status.EXPECTATION_FAILED)
|
||||
.entity(build(exception.getMessage()))
|
||||
.type(MediaType.APPLICATION_JSON)
|
||||
.build();
|
||||
}
|
||||
|
||||
private RestErrorResponse build(String message) {
|
||||
RestErrorResponse response = new RestErrorResponse();
|
||||
response.setMessage(DEFAULT_MESSAGE + ": " + message);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.jersey.exceptionhandling.rest.exceptions;
|
||||
|
||||
import jakarta.ws.rs.WebApplicationException;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
public class InvalidTradeException extends WebApplicationException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String MESSAGE = "invalid trade operation";
|
||||
|
||||
public InvalidTradeException() {
|
||||
super(MESSAGE, Response.Status.NOT_ACCEPTABLE);
|
||||
}
|
||||
|
||||
public InvalidTradeException(String detail) {
|
||||
super(MESSAGE + ": " + detail, Response.Status.NOT_ACCEPTABLE);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.baeldung.jersey.exceptionhandling.rest.exceptions;
|
||||
|
||||
public class RestErrorResponse {
|
||||
private Object subject;
|
||||
private String message;
|
||||
|
||||
public RestErrorResponse() {
|
||||
}
|
||||
|
||||
public RestErrorResponse(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public RestErrorResponse(Object subject, String message) {
|
||||
this.subject = subject;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Object getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public void setSubject(Object subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package com.baeldung.jersey.exceptionhandling.rest.exceptions;
|
||||
|
||||
import jakarta.ws.rs.WebApplicationException;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.ext.ExceptionMapper;
|
||||
|
||||
public class ServerExceptionMapper implements ExceptionMapper<WebApplicationException> {
|
||||
public static final String HTTP_405_MESSAGE = "use one of";
|
||||
|
||||
@Override
|
||||
public Response toResponse(final WebApplicationException exception) {
|
||||
String message;
|
||||
Response response = exception.getResponse();
|
||||
Response.Status status = response.getStatusInfo()
|
||||
.toEnum();
|
||||
|
||||
switch (status) {
|
||||
case METHOD_NOT_ALLOWED:
|
||||
message = HTTP_405_MESSAGE + response.getAllowedMethods();
|
||||
break;
|
||||
case INTERNAL_SERVER_ERROR:
|
||||
message = "internal validation - " + exception;
|
||||
break;
|
||||
default:
|
||||
message = "[unhandled response code] " + exception;
|
||||
}
|
||||
|
||||
return Response.status(status)
|
||||
.entity(status + ": " + message)
|
||||
.type(MediaType.TEXT_PLAIN)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.jersey.exceptionhandling.service;
|
||||
|
||||
import com.baeldung.jersey.exceptionhandling.data.Stock;
|
||||
import com.baeldung.jersey.exceptionhandling.data.Wallet;
|
||||
import com.baeldung.jersey.exceptionhandling.repo.Db;
|
||||
|
||||
public class Repository {
|
||||
public static Db<Stock> STOCKS_DB = new Db<>();
|
||||
public static Db<Wallet> WALLETS_DB = new Db<>();
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.baeldung.jersey.server;
|
||||
|
||||
import com.baeldung.jersey.client.filter.AddHeaderOnRequestFilter;
|
||||
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.sse.OutboundSseEvent;
|
||||
import jakarta.ws.rs.sse.Sse;
|
||||
import jakarta.ws.rs.sse.SseEventSink;
|
||||
|
||||
@Path("/echo-headers")
|
||||
public class EchoHeaders {
|
||||
|
||||
static final String REALM_KEY = "realm";
|
||||
static final String REALM_VALUE = "Baeldung";
|
||||
static final String QOP_KEY = "qop";
|
||||
static final String QOP_VALUE = "auth";
|
||||
static final String NONCE_KEY = "nonce";
|
||||
static final String NONCE_VALUE = "dcd98b7102dd2f0e8b11d0f600bfb0c093";
|
||||
static final String OPAQUE_KEY = "opaque";
|
||||
static final String OPAQUE_VALUE = "5ccc069c403ebaf9f0171e9517f40e41";
|
||||
static final String SSE_HEADER_KEY = "x-sse-header-key";
|
||||
|
||||
@Context
|
||||
HttpHeaders headers;
|
||||
|
||||
@GET
|
||||
public Response getHeadersBack() {
|
||||
return echoHeaders();
|
||||
}
|
||||
|
||||
@RolesAllowed("ADMIN")
|
||||
@GET
|
||||
@Path("/digest")
|
||||
public Response getHeadersBackFromDigestAuthentication() {
|
||||
// As the Digest authentication require some complex steps to work we'll simulate the process
|
||||
// https://en.wikipedia.org/wiki/Digest_access_authentication#Example_with_explanation
|
||||
if (headers.getHeaderString("authorization") == null) {
|
||||
String authenticationRequired = "Digest " + REALM_KEY + "=\"" + REALM_VALUE + "\", " + QOP_KEY + "=\"" + QOP_VALUE + "\", " + NONCE_KEY + "=\"" + NONCE_VALUE + "\", " + OPAQUE_KEY + "=\"" + OPAQUE_VALUE + "\"";
|
||||
return Response.status(Response.Status.UNAUTHORIZED)
|
||||
.header("WWW-Authenticate", authenticationRequired)
|
||||
.build();
|
||||
} else {
|
||||
return echoHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/events")
|
||||
@Produces(MediaType.SERVER_SENT_EVENTS)
|
||||
public void getServerSentEvents(@Context SseEventSink eventSink, @Context Sse sse) {
|
||||
OutboundSseEvent event = sse.newEventBuilder()
|
||||
.name("echo-headers")
|
||||
.data(String.class, headers.getHeaderString(AddHeaderOnRequestFilter.FILTER_HEADER_KEY))
|
||||
.build();
|
||||
eventSink.send(event);
|
||||
}
|
||||
|
||||
private Response echoHeaders() {
|
||||
Response.ResponseBuilder responseBuilder = Response.noContent();
|
||||
|
||||
headers.getRequestHeaders()
|
||||
.forEach((k, v) -> {
|
||||
v.forEach(value -> responseBuilder.header(k, value));
|
||||
});
|
||||
|
||||
return responseBuilder.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.jersey.server;
|
||||
|
||||
import com.baeldung.jersey.server.config.HelloBinding;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
@Path("/greetings")
|
||||
public class Greetings {
|
||||
|
||||
@GET
|
||||
@HelloBinding
|
||||
public String getHelloGreeting() {
|
||||
return "hello";
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/hi")
|
||||
public String getHiGreeting() {
|
||||
return "hi";
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/custom")
|
||||
public Response getCustomGreeting(String name) {
|
||||
return Response.status(Response.Status.OK.getStatusCode())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.baeldung.jersey.server;
|
||||
|
||||
import jakarta.ws.rs.FormParam;
|
||||
import jakarta.ws.rs.HeaderParam;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
|
||||
public class ItemParam {
|
||||
|
||||
@HeaderParam("headerParam")
|
||||
private String shopKey;
|
||||
|
||||
@PathParam("pathParam")
|
||||
private String itemId;
|
||||
|
||||
@FormParam("formParam")
|
||||
private String price;
|
||||
|
||||
public String getShopKey() {
|
||||
return shopKey;
|
||||
}
|
||||
|
||||
public void setShopKey(String shopKey) {
|
||||
this.shopKey = shopKey;
|
||||
}
|
||||
|
||||
public String getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
|
||||
public void setItemId(String itemId) {
|
||||
this.itemId = itemId;
|
||||
}
|
||||
|
||||
public String getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(String price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ItemParam{shopKey='" + shopKey + ", itemId='" + itemId + ", price='" + price + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.baeldung.jersey.server;
|
||||
|
||||
import jakarta.ws.rs.BeanParam;
|
||||
import jakarta.ws.rs.CookieParam;
|
||||
import jakarta.ws.rs.FormParam;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.HeaderParam;
|
||||
import jakarta.ws.rs.MatrixParam;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
|
||||
@Path("items")
|
||||
public class Items {
|
||||
|
||||
@GET
|
||||
@Path("/cookie")
|
||||
public String readCookieParam(@CookieParam("cookieParamToRead") String cookieParamToRead) {
|
||||
return "Cookie parameter value is [" + cookieParamToRead + "]";
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/header")
|
||||
public String readHeaderParam(@HeaderParam("headerParamToRead") String headerParamToRead) {
|
||||
return "Header parameter value is [" + headerParamToRead + "]";
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/path/{pathParamToRead}")
|
||||
public String readPathParam(@PathParam("pathParamToRead") String pathParamToRead) {
|
||||
return "Path parameter value is [" + pathParamToRead + "]";
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/query")
|
||||
public String readQueryParam(@QueryParam("queryParamToRead") String queryParamToRead) {
|
||||
return "Query parameter value is [" + queryParamToRead + "]";
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/form")
|
||||
public String readFormParam(@FormParam("formParamToRead") String formParamToRead) {
|
||||
return "Form parameter value is [" + formParamToRead + "]";
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/matrix")
|
||||
public String readMatrixParam(@MatrixParam("matrixParamToRead") String matrixParamToRead) {
|
||||
return "Matrix parameter value is [" + matrixParamToRead + "]";
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/bean/{pathParam}")
|
||||
public String readBeanParam(@BeanParam ItemParam itemParam) {
|
||||
return itemParam.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.baeldung.jersey.server;
|
||||
|
||||
import com.baeldung.jersey.server.model.Person;
|
||||
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
@Path("/response")
|
||||
public class Responder {
|
||||
|
||||
@GET
|
||||
@Path("/ok")
|
||||
public Response getOkResponse() {
|
||||
|
||||
String message = "This is a text response";
|
||||
|
||||
return Response
|
||||
.status(Response.Status.OK)
|
||||
.entity(message)
|
||||
.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/not_ok")
|
||||
public Response getNOkTextResponse() {
|
||||
|
||||
String message = "There was an internal server error";
|
||||
|
||||
return Response
|
||||
.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity(message)
|
||||
.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/text_plain")
|
||||
public Response getTextResponseTypeDefined() {
|
||||
|
||||
String message = "This is a plain text response";
|
||||
|
||||
return Response
|
||||
.status(Response.Status.OK)
|
||||
.entity(message)
|
||||
.type(MediaType.TEXT_PLAIN)
|
||||
.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/text_plain_annotation")
|
||||
@Produces({ MediaType.TEXT_PLAIN })
|
||||
public Response getTextResponseTypeAnnotated() {
|
||||
|
||||
String message = "This is a plain text response via annotation";
|
||||
|
||||
return Response
|
||||
.status(Response.Status.OK)
|
||||
.entity(message)
|
||||
.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/pojo")
|
||||
public Response getPojoResponse() {
|
||||
|
||||
Person person = new Person("Abh", "Nepal");
|
||||
|
||||
return Response
|
||||
.status(Response.Status.OK)
|
||||
.entity(person)
|
||||
.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/json")
|
||||
public Response getJsonResponse() {
|
||||
|
||||
String message = "{\"hello\": \"This is a JSON response\"}";
|
||||
|
||||
return Response
|
||||
.status(Response.Status.OK)
|
||||
.entity(message)
|
||||
.type(MediaType.APPLICATION_JSON)
|
||||
.build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/xml")
|
||||
@Produces(MediaType.TEXT_XML)
|
||||
public String sayXMLHello() {
|
||||
return "<?xml version=\"1.0\"?>" + "<hello> This is a xml response </hello>";
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/html")
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
public String sayHtmlHello() {
|
||||
return "<html> " + "<title>" + " This is a html title </title>" + "<body><h1>" + " This is a html response body " + "</body></h1>" + "</html> ";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.baeldung.jersey.server.config;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import jakarta.ws.rs.NameBinding;
|
||||
|
||||
@NameBinding
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface HelloBinding {
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.baeldung.jersey.server.config;
|
||||
|
||||
import com.baeldung.jersey.server.Greetings;
|
||||
import com.baeldung.jersey.server.filter.ResponseServerFilter;
|
||||
|
||||
import jakarta.ws.rs.container.DynamicFeature;
|
||||
import jakarta.ws.rs.container.ResourceInfo;
|
||||
import jakarta.ws.rs.core.FeatureContext;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
|
||||
@Provider
|
||||
public class HelloDynamicBinding implements DynamicFeature {
|
||||
|
||||
@Override
|
||||
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
|
||||
|
||||
if (Greetings.class.equals(resourceInfo.getResourceClass()) && resourceInfo.getResourceMethod()
|
||||
.getName()
|
||||
.contains("HiGreeting")) {
|
||||
context.register(ResponseServerFilter.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.jersey.server.config;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
|
||||
@ApplicationPath("/*")
|
||||
public class ServerConfig extends ResourceConfig {
|
||||
|
||||
public ServerConfig() {
|
||||
packages("com.baeldung.jersey.server");
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user