Initial Contribution
Signed-off-by: Jan Supol <jan.supol@oracle.com>
diff --git a/examples/exception-mapping/README.MD b/examples/exception-mapping/README.MD
new file mode 100644
index 0000000..613624d
--- /dev/null
+++ b/examples/exception-mapping/README.MD
@@ -0,0 +1,49 @@
+[//]: # " Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved. "
+[//]: # " "
+[//]: # " This program and the accompanying materials are made available under the "
+[//]: # " terms of the Eclipse Distribution License v. 1.0, which is available at "
+[//]: # " http://www.eclipse.org/org/documents/edl-v10.php. "
+[//]: # " "
+[//]: # " SPDX-License-Identifier: BSD-3-Clause "
+
+Exception Mapping Example
+=========================
+
+This example demonstrates how to create a custom exception mapping. There are described several common use-cases such as
+`WebApplicationException`, custom exceptions and an exception mapper inheritance.
+
+The full description how to handle exception and map them to Response object can be found in Jersey User Guide, chapter
+[WebApplicationException and Mapping Exceptions to Responses](https://jersey.java.net/documentation/latest/representations.html#d0e6567).
+
+Contents
+--------
+
+The mapping of the URI path space is presented in the following table:
+
+URI path | HTTP methods | Allowed Values | Description
+----------------------------------------- | ------------- |-------------------------------------------- | ----------------
+**_/exception_** | GET | --- | returns "ping!"
+**_/exception/webapplication_entity_** | POST | two numbers delimited by colons e.g. 1:201 | not handled by `WebApplicationExceptionMapper` (already has an entity in the exception)
+**_/exception/webapplication_noentity_** | POST | e.g. 1:201 | handled by `WebApplicationExceptionMapper`
+**_/exception/my_** | POST | e.g. 1:201 | handled by `MyExceptionMapper`
+**_/exception/mysub_** | POST | e.g. 1:201 | handled by `MySubExceptionMapper`
+**_/exception/mysubsub_** | POST | e.g. 1:201 | handled by `MySubExceptionMapper`
+**_/exception/request_exception_** | POST | String "Request Exception" | not reached a resource method, processed by `ContainerRequestFilter`
+**_/exception/response_exception_** | GET | --- | response handled and changed by `ContainerResponseFilter`
+
+
+Application is based on Grizzly container (see `App`). Everything needed
+(resources/providers) is registered in `ExceptionResource` and custom exceptions
+along with mappers can be found in `Exceptions` class.
+
+Running the Example
+-------------------
+
+Run the example as follows:
+
+> mvn clean compile exec:java
+
+This deploys the example using [Grizzly](http://grizzly.java.net/) container.
+
+- <http://localhost:8080/base/exception>
+- <http://localhost:8080/base/exception/response_exception>
diff --git a/examples/exception-mapping/pom.xml b/examples/exception-mapping/pom.xml
new file mode 100644
index 0000000..68f418d
--- /dev/null
+++ b/examples/exception-mapping/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Copyright (c) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Distribution License v. 1.0, which is available at
+ http://www.eclipse.org/org/documents/edl-v10.php.
+
+ SPDX-License-Identifier: BSD-3-Clause
+
+-->
+
+<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>
+
+ <parent>
+ <groupId>org.glassfish.jersey.examples</groupId>
+ <artifactId>project</artifactId>
+ <version>2.28-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>exception-mapping</artifactId>
+ <packaging>jar</packaging>
+ <name>jersey-examples-exception-mapping</name>
+
+ <description>Jersey example showing exception mappers in action.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.glassfish.jersey.containers</groupId>
+ <artifactId>jersey-container-grizzly2-http</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.inject</groupId>
+ <artifactId>jersey-hk2</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+ <artifactId>jersey-test-framework-provider-bundle</artifactId>
+ <type>pom</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <configuration>
+ <mainClass>org.glassfish.jersey.examples.exception.App</mainClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
diff --git a/examples/exception-mapping/src/main/java/org/glassfish/jersey/examples/exception/App.java b/examples/exception-mapping/src/main/java/org/glassfish/jersey/examples/exception/App.java
new file mode 100644
index 0000000..b520eda
--- /dev/null
+++ b/examples/exception-mapping/src/main/java/org/glassfish/jersey/examples/exception/App.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0, which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.glassfish.jersey.examples.exception;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
+import org.glassfish.jersey.server.ResourceConfig;
+
+import org.glassfish.grizzly.http.server.HttpServer;
+
+/**
+ * Hello world!
+ */
+public class App {
+
+ private static final URI BASE_URI = URI.create("http://localhost:8080/base/");
+ public static final String ROOT_PATH = "exception";
+
+ public static void main(String[] args) {
+ try {
+ System.out.println("\"Exception Mapping\" Jersey Example App");
+
+ final ResourceConfig resourceConfig = new ResourceConfig(
+ ExceptionResource.class,
+ ExceptionResource.MyResponseFilter.class,
+ ExceptionResource.WebApplicationExceptionFilter.class,
+ Exceptions.MyExceptionMapper.class,
+ Exceptions.MySubExceptionMapper.class,
+ Exceptions.WebApplicationExceptionMapper.class);
+
+ final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, resourceConfig, false);
+ Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
+ @Override
+ public void run() {
+ server.shutdownNow();
+ }
+ }));
+ server.start();
+
+ System.out.println(String.format(
+ "Application started.%n"
+ + "Try out %s%s%n"
+ + "Stop the application using CTRL+C",
+ BASE_URI, ROOT_PATH));
+
+ Thread.currentThread().join();
+ } catch (IOException | InterruptedException ex) {
+ Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ }
+}
diff --git a/examples/exception-mapping/src/main/java/org/glassfish/jersey/examples/exception/ExceptionResource.java b/examples/exception-mapping/src/main/java/org/glassfish/jersey/examples/exception/ExceptionResource.java
new file mode 100644
index 0000000..e4cfe74
--- /dev/null
+++ b/examples/exception-mapping/src/main/java/org/glassfish/jersey/examples/exception/ExceptionResource.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0, which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.glassfish.jersey.examples.exception;
+
+import java.io.IOException;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.InternalServerErrorException;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.Provider;
+
+import org.glassfish.jersey.examples.exception.Exceptions.MyException;
+import org.glassfish.jersey.examples.exception.Exceptions.MySubException;
+import org.glassfish.jersey.examples.exception.Exceptions.MySubSubException;
+import org.glassfish.jersey.server.ContainerRequest;
+
+/**
+ * ExceptionResource class.
+ *
+ * @author Santiago.PericasGeertsen at oracle.com
+ */
+@Path("exception")
+@Consumes("text/plain")
+@Produces("text/plain")
+public class ExceptionResource {
+
+ @Provider
+ static class MyResponseFilter implements ContainerResponseFilter {
+
+ @Override
+ public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
+ System.out.println("MyResponseFilter.postFilter() enter");
+ responseContext.setEntity(
+ responseContext.getEntity() + ":" + getClass().getSimpleName(), null, MediaType.TEXT_PLAIN_TYPE);
+ System.out.println("MyResponseFilter.postFilter() exit");
+ }
+ }
+
+ @Provider
+ static class WebApplicationExceptionFilter implements ContainerRequestFilter, ContainerResponseFilter {
+
+ @Override
+ public void filter(ContainerRequestContext context) throws IOException {
+ System.out.println("WebApplicationExceptionFilter.preFilter() enter");
+
+ String path = ((ContainerRequest) context).getRequestUri().getPath();
+ if (path.endsWith("request_exception") && context.hasEntity() && ((ContainerRequest) context)
+ .readEntity(String.class).equals("Request Exception")) {
+ throw new WebApplicationException(Response.Status.OK);
+ }
+ System.out.println("WebApplicationExceptionFilter.preFilter() exit");
+ }
+
+ @Override
+ public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
+ System.out.println("WebApplicationExceptionFilter.postFilter() enter");
+ if (responseContext.hasEntity() && responseContext.getEntity().equals("Response Exception")) {
+ throw new WebApplicationException(Response.Status.OK);
+ }
+ System.out.println("WebApplicationExceptionFilter.postFilter() exit");
+ }
+ }
+
+ @GET
+ public String pingMe() {
+ return "ping!";
+ }
+
+ @POST
+ @Path("webapplication_entity")
+ public String testWebApplicationExceptionEntity(String s) {
+ String[] tokens = s.split(":");
+ assert tokens.length == 2;
+ int statusCode = Integer.valueOf(tokens[1]);
+ Response r = Response.status(statusCode).entity(s).build();
+ throw new WebApplicationException(r);
+ }
+
+ @POST
+ @Path("webapplication_noentity")
+ public String testWebApplicationExceptionNoEntity(String s) {
+ String[] tokens = s.split(":");
+ assert tokens.length == 2;
+ int statusCode = Integer.valueOf(tokens[1]);
+ Response r = Response.status(statusCode).build();
+ throw new WebApplicationException(r);
+ }
+
+ @POST
+ @Path("my")
+ public String testMyException(String s) {
+ String[] tokens = s.split(":");
+ assert tokens.length == 2;
+ int statusCode = Integer.valueOf(tokens[1]);
+ Response r = Response.status(statusCode).build();
+ throw new MyException(r);
+ }
+
+ @POST
+ @Path("mysub")
+ public String testMySubException(String s) {
+ String[] tokens = s.split(":");
+ assert tokens.length == 2;
+ int statusCode = Integer.valueOf(tokens[1]);
+ Response r = Response.status(statusCode).build();
+ throw new MySubException(r);
+ }
+
+ @POST
+ @Path("mysubsub")
+ public String testMySubSubException(String s) {
+ String[] tokens = s.split(":");
+ assert tokens.length == 2;
+ int statusCode = Integer.valueOf(tokens[1]);
+ Response r = Response.status(statusCode).build();
+ throw new MySubSubException(r);
+ }
+
+ @POST
+ @Path("request_exception")
+ public String exceptionInRequestFilter() {
+ throw new InternalServerErrorException(); // should not reach here
+ }
+
+ @GET
+ @Path("response_exception")
+ public String exceptionInResponseFilter() {
+ return "Response Exception";
+ }
+}
diff --git a/examples/exception-mapping/src/main/java/org/glassfish/jersey/examples/exception/Exceptions.java b/examples/exception-mapping/src/main/java/org/glassfish/jersey/examples/exception/Exceptions.java
new file mode 100644
index 0000000..670bde8
--- /dev/null
+++ b/examples/exception-mapping/src/main/java/org/glassfish/jersey/examples/exception/Exceptions.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0, which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.glassfish.jersey.examples.exception;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+/**
+ * Exceptions class.
+ *
+ * @author Santiago.Pericas-Geertsen at oracle.com
+ */
+public class Exceptions {
+
+ // -- Exceptions
+ public static class MyException extends RuntimeException {
+
+ private Response response;
+
+ public MyException(Response response) {
+ this.response = response;
+ }
+
+ public Response getResponse() {
+ return response;
+ }
+ }
+
+ public static class MySubException extends MyException {
+
+ public MySubException(Response response) {
+ super(response);
+ }
+ }
+
+ public static class MySubSubException extends MySubException {
+
+ public MySubSubException(Response response) {
+ super(response);
+ }
+ }
+
+ // -- Exception Mappers
+ @Provider
+ public static class MyExceptionMapper implements ExceptionMapper<MyException> {
+
+ @Override
+ public Response toResponse(MyException exception) {
+ Response r = exception.getResponse();
+ return Response.status(r.getStatus()).entity(
+ "Code:" + r.getStatus() + ":" + getClass().getSimpleName()).build();
+ }
+ }
+
+ @Provider
+ public static class MySubExceptionMapper implements ExceptionMapper<MySubException> {
+
+ @Override
+ public Response toResponse(MySubException exception) {
+ Response r = exception.getResponse();
+ return Response.status(r.getStatus()).entity(
+ "Code:" + r.getStatus() + ":" + getClass().getSimpleName()).build();
+ }
+ }
+
+ @Provider
+ public static class WebApplicationExceptionMapper implements ExceptionMapper<WebApplicationException> {
+
+ @Override
+ public Response toResponse(WebApplicationException exception) {
+ Response r = exception.getResponse();
+ return Response.status(r.getStatus()).entity("Code:" + r.getStatus() + ":"
+ + getClass().getSimpleName()).build();
+ }
+ }
+}
diff --git a/examples/exception-mapping/src/test/java/org/glassfish/jersey/examples/exception/ExceptionMappingFilterTest.java b/examples/exception-mapping/src/test/java/org/glassfish/jersey/examples/exception/ExceptionMappingFilterTest.java
new file mode 100644
index 0000000..d509934
--- /dev/null
+++ b/examples/exception-mapping/src/test/java/org/glassfish/jersey/examples/exception/ExceptionMappingFilterTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0, which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.glassfish.jersey.examples.exception;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+import static org.glassfish.jersey.examples.exception.ExceptionResource.MyResponseFilter;
+import static org.glassfish.jersey.examples.exception.Exceptions.MyExceptionMapper;
+import static org.glassfish.jersey.examples.exception.Exceptions.MySubExceptionMapper;
+import static org.glassfish.jersey.examples.exception.Exceptions.WebApplicationExceptionMapper;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * ExceptionMappingFilterTest class.
+ *
+ * @author Santiago.PericasGeertsen at oracle.com
+ */
+public class ExceptionMappingFilterTest extends JerseyTest {
+
+ @Override
+ protected ResourceConfig configure() {
+ // mvn test -Djersey.test.containerFactory=org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory
+ // mvn test -Djersey.test.containerFactory=org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory
+
+ final ResourceConfig resourceConfig = new ResourceConfig(
+ ExceptionResource.class,
+ MyResponseFilter.class,
+ ExceptionResource.WebApplicationExceptionFilter.class,
+ MyExceptionMapper.class,
+ MySubExceptionMapper.class,
+ WebApplicationExceptionMapper.class);
+
+ return resourceConfig;
+ }
+
+ /**
+ * Instructs request filter to throw a WebApplicationException which must be mapped
+ * to a response and processed through response pipeline.
+ */
+ @Test
+ public void testWebApplicationExceptionInRequestFilter() {
+ WebTarget t = client().target(UriBuilder.fromUri(getBaseUri()).path(App.ROOT_PATH).path("request_exception").build());
+ Response r = t.request("text/plain").post(Entity.text("Request Exception"));
+ assertEquals(200, r.getStatus());
+ final String entity = r.readEntity(String.class);
+ System.out.println("entity = " + entity);
+ assertTrue(entity.contains(MyResponseFilter.class.getSimpleName()));
+ }
+
+ @Test
+ public void testWebApplicationExceptionInResponseFilter() {
+ WebTarget t = client().target(UriBuilder.fromUri(getBaseUri()).path(App.ROOT_PATH).path("response_exception").build());
+ Response r = t.request("text/plain").get();
+ assertEquals(200, r.getStatus());
+ final String entity = r.readEntity(String.class);
+ System.out.println("entity = " + entity);
+ assertTrue(entity.contains(MyResponseFilter.class.getSimpleName()));
+ }
+}
diff --git a/examples/exception-mapping/src/test/java/org/glassfish/jersey/examples/exception/ExceptionMappingTest.java b/examples/exception-mapping/src/test/java/org/glassfish/jersey/examples/exception/ExceptionMappingTest.java
new file mode 100644
index 0000000..3166312
--- /dev/null
+++ b/examples/exception-mapping/src/test/java/org/glassfish/jersey/examples/exception/ExceptionMappingTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0, which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.glassfish.jersey.examples.exception;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+import static org.glassfish.jersey.examples.exception.ExceptionResource.MyResponseFilter;
+import static org.glassfish.jersey.examples.exception.Exceptions.MyExceptionMapper;
+import static org.glassfish.jersey.examples.exception.Exceptions.MySubExceptionMapper;
+import static org.glassfish.jersey.examples.exception.Exceptions.MySubSubException;
+import static org.glassfish.jersey.examples.exception.Exceptions.WebApplicationExceptionMapper;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * ExceptionMappingTest class.
+ *
+ * @author Santiago.PericasGeertsen at oracle.com
+ */
+public class ExceptionMappingTest extends JerseyTest {
+
+ @Override
+ protected ResourceConfig configure() {
+ // mvn test -Djersey.test.containerFactory=org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory
+ // mvn test -Djersey.test.containerFactory=org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory
+ return new ResourceConfig(
+ ExceptionResource.class,
+ MyResponseFilter.class,
+ MyExceptionMapper.class,
+ MySubExceptionMapper.class,
+ MySubSubException.class,
+ WebApplicationExceptionMapper.class);
+ }
+
+ /**
+ * Ensure we can access resource with response filter installed.
+ */
+ @Test
+ public void testPingAndFilter() {
+ WebTarget t = client().target(UriBuilder.fromUri(getBaseUri()).path(App.ROOT_PATH).build());
+ Response r = t.request("text/plain").get();
+ assertEquals(200, r.getStatus());
+ assertTrue(r.readEntity(String.class).contains(MyResponseFilter.class.getSimpleName()));
+ }
+
+ /**
+ * No mapper should be used if WebApplicationException already contains a
+ * Response with a non-empty entity.
+ */
+ @Test
+ public void testWebApplicationExceptionWithEntity() {
+ WebTarget t = client().target(UriBuilder.fromUri(getBaseUri()).path(App.ROOT_PATH).path("webapplication_entity").build());
+ Response r = t.request("text/plain").post(Entity.text("Code:200"));
+ assertEquals(200, r.getStatus());
+ final String entity = r.readEntity(String.class);
+ assertTrue(entity.contains("Code:200"));
+ assertTrue(entity.contains(MyResponseFilter.class.getSimpleName()));
+ }
+
+ /**
+ * No mapper should be used if WebApplicationException already contains a
+ * Response with a non-empty entity. Same as last test but using 400 code.
+ */
+ @Test
+ public void testWebApplicationExceptionWithEntity400() {
+ WebTarget t = client().target(UriBuilder.fromUri(getBaseUri()).path(App.ROOT_PATH).path("webapplication_entity").build());
+ Response r = t.request("text/plain").post(Entity.text("Code:400"));
+ assertEquals(400, r.getStatus());
+ final String entity = r.readEntity(String.class);
+ assertTrue(entity.contains("Code:400"));
+ assertTrue(entity.contains(MyResponseFilter.class.getSimpleName()));
+ }
+
+ /**
+ * WebApplicationExceptionMapper should be used if WebApplicationException contains
+ * empty entity.
+ */
+ @Test
+ public void testWebApplicationExceptionUsingMapper() {
+ WebTarget t = client()
+ .target(UriBuilder.fromUri(getBaseUri()).path(App.ROOT_PATH).path("webapplication_noentity").build());
+ Response r = t.request("text/plain").post(Entity.text("Code:200"));
+ assertEquals(200, r.getStatus());
+ String entity = r.readEntity(String.class);
+ assertTrue(entity.contains("Code:200"));
+ assertTrue(entity.contains(WebApplicationExceptionMapper.class.getSimpleName()));
+ assertTrue(entity.contains(MyResponseFilter.class.getSimpleName()));
+ }
+
+ /**
+ * MyExceptionMapper should be used if MyException is thrown.
+ */
+ @Test
+ public void testMyException() {
+ WebTarget t = client().target(UriBuilder.fromUri(getBaseUri()).path(App.ROOT_PATH).path("my").build());
+ Response r = t.request("text/plain").post(Entity.text("Code:200"));
+ assertEquals(200, r.getStatus());
+ String entity = r.readEntity(String.class);
+ assertTrue(entity.contains("Code:200"));
+ assertTrue(entity.contains(MyExceptionMapper.class.getSimpleName()));
+ assertTrue(entity.contains(MyResponseFilter.class.getSimpleName()));
+ }
+
+ /**
+ * MySubExceptionMapper should be used if MySubException is thrown.
+ */
+ @Test
+ public void testMySubException() {
+ WebTarget t = client().target(UriBuilder.fromUri(getBaseUri()).path(App.ROOT_PATH).path("mysub").build());
+ Response r = t.request("text/plain").post(Entity.text("Code:200"));
+ assertEquals(200, r.getStatus());
+ String entity = r.readEntity(String.class);
+ assertTrue(entity.contains("Code:200"));
+ assertTrue(entity.contains(MySubExceptionMapper.class.getSimpleName()));
+ assertTrue(entity.contains(MyResponseFilter.class.getSimpleName()));
+ }
+
+ /**
+ * MySubExceptionMapper should be used if MySubSubException is thrown, given that
+ * there is no mapper for MySubSubException and MySubException is the nearest
+ * super type.
+ */
+ @Test
+ public void testMySubSubException() {
+ WebTarget t = client().target(UriBuilder.fromUri(getBaseUri()).path(App.ROOT_PATH).path("mysub").build());
+ Response r = t.request("text/plain").post(Entity.text("Code:200"));
+ assertEquals(200, r.getStatus());
+ String entity = r.readEntity(String.class);
+ assertTrue(entity.contains("Code:200"));
+ assertTrue(entity.contains(MySubExceptionMapper.class.getSimpleName()));
+ assertTrue(entity.contains(MyResponseFilter.class.getSimpleName()));
+ }
+}