sebastiandaschner news
Konnichiwa from Hokkaido!
The last days were full of riding motorbike all across Japan to visit Java User Groups. Similar to our last motorbike Java tours, Steve Chin and myself are on the “Oracle Code Japan Tour” which had the stop in Sapporo yesterday. Now we are exploring the island of Hokkaido and will return to Tokyo in the next days. It is always great to see the engagement of the Japanese Java Community all across the country.
At the JUGs I presented the topic of “Cloud Native Java EE” a buzzword-driven presentation how Java EE shines in the age of modern enterprise environments — Java EE in Docker containers orchestrated by Kubernetes. You can watch the recording of the Hiroshima JUG presentation.
What’s new
Java EE quiz solution #3
More Java EE quizzes from the official Java twitter handle as part of #100DaysOfJava:
The solution of my next Java EE related question is:
Invoking ask()
will output
intercepted! intercepted! asked first asked second intercepted! asked second
The QuizInterceptor
is included to intercept all invocations of business method on Quiz
instances.
Therefore the ask()
method will be intercepted and intercepted!
will be printed first.
The askFirst()
and askSecond()
method calls inside are invoked on another instance of Quiz
and therefore intercepted on that object as well.
The askSecond()
method call inside of askFirst()
is not intercepted since this is just a direct method invocation on the same object — see quiz solution #2 of my last newsletter.
Java EE quiz solution #4
See the solution of my JAX-RS related question.
Method two()
and three()
are annotated with @Produces
which makes things clear for these methods — they will output application/json
and text/plain
, respectively.
The Content-Type of the one()
method is determined dynamically by the container based on which Accept
header is requested and which Java type returned from the method.
Depending on the available MessageBodyWriter
s the container will send a corresponding type — or application/octet-stream
as a default.
For the String
return type the result is very flexible — you can try this out by sending different Accept
headers via an HTTP client.
For those who are more interested into this topic have a look into the JSR 339 specification chapter 3.5 and 3.8.
Handle custom exceptions with JAX-RS status codes
In the last newsletter issue I showed how to use JAX-RS exceptions to send specific HTTP error status codes and how to avoid the wrapping of exceptions thrown in EJBs. Now we want to combine custom exceptions — thrown in either EJBs or CDI beans — to send custom HTTP responses.
Assuming we have an “exceptional” EJB again:
@Stateless
public class Hello {
public String greeting() {
if (new Random().nextBoolean())
throw new GreetingException("Could not greet");
return "hello";
}
}
@ApplicationException
public class GreetingException extends RuntimeException {
public GreetingException(String message) {
super(message);
}
}
The EJB is used in our JAX-RS resource:
@Path("hello")
public class HelloResource {
@Inject
Hello hello;
@GET
public String hello() {
return hello.greeting();
}
}
Now to map the occurring exception to a custom HTTP response we can define a JAX-RS ExceptionMapper
.
@Provider
public class GreetingExceptionMapper
implements ExceptionMapper<GreetingException> {
@Override
public Response toResponse(GreetingException exception) {
return Response.status(Response.Status.CONFLICT)
.header("Conflict-Reason", exception.getMessage())
.build();
}
}
The exception mapper is registered as a JAX-RS extension (by @Provider
) and will handle any GreetingException
thrown by a resource method.
The example will occasionally output HTTP 409 Conflict
with header Conflict-Reason: Could not greet
.
Thanks a lot for reading and see you next time!
Did you like the content? You can subscribe to the newsletter for free:
All opinions are my own and do not reflect those of my employer or colleagues.