I want to understand the logic of JAX-RS with ExceptionMapper
lets assume that I have class
#Provider
#Singleton
public class MyExceptionMapper implements ExceptionMapper<ApiException> {
/**
* check the exception type and build Response with the status body and the type of the error
*/
#Override
public Response toResponse(ApiException exception) {
........
}
}
How is call this class ?
I saw that there is class ApplicationPrivderBinder that has method getExceptionMapper
Does it is the logic?
Who call to this method ? where is the call to the method toResponse from the
interface ExceptionMapper
The JAX-RS framework does automatically call this when an exception of the specified type (here: ApiException) propagates out of a resource method.
Related
I do have a Spring boot controller class and a corresponding ControllerAdvice class which has ExceptionHandlers to handle different exception.
My controller method calls a simple validation helper class to validate input fields which throws an exception if validation fails. Now if I don't put a try catch block in my controller it keeps complaining me that you have a method which has untangled exception even through the logic for handling validation exception is defined in controlleradvice class. Please suggest how do I solve it.
From the method of ValidationHelper class if you throw any Checked Exception then you need to use a try-catch block to call that method.
If you don't want then it's better to use any Custom Exception class which will extend the RuntimeException class and you throw that exception. Then you don't need to explicitly mention the throws as well as you don't need to have a try-catch block at the controller.
#RestController
#RequiredArgsConstructor
public class SampleController {
private final ValidationHelper validationHelper;
#ResponseStatus(HttpStatus.OK)
#GetMapping("/sample")
public String getRequest(#RequestParam String name) {
validationHelper.validate(name);
return "";
}
}
#Service
public class ValidationHelper {
public Boolean validate(String name) {
throw new CustomException("Validation Failed");
}
}
public class CustomException extends RuntimeException {
public CustomException(String message) {
super(message);
}
}
My Spring boot app is standalone application which don't have controller. I am calling service layer from main method of spring boot application.
I have tried to use #ExceptionHandler #ControllerAdvice annotations in my class as below. but control never comes to My Exception Handler method
package com.test.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
#ControllerAdvice
public class MyExceptionHandler {
#ExceptionHandler(NullPointerException.class)
public void handleNullpointerExcetion() {
System.out.println("Handling Null pointer exception");
}
}
Tried with package name as well which i need to scan in #ControllerAdvice but it is not working
#ControllerAdvice("com.test.utility")
public class MyExceptionHandler {
#ExceptionHandler(NullPointerException.class)
public void handleNullpointerExcetion() {
System.out.println("Handling Null pointer exception");
}
}
Are we not able to handle exception at centralized place if i we don't have controller class which we annotate with #RestContoller or #Controller
I don't think so.
ControllerAdvice is only used whenever a controller would return an exception,
It is a layer that exists after your endpoint in the controller returns and before actually returning the response, to interject and globally handle the exception and is meant to be global only for controllers.
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html
since you don't have a controller, I'd imagine the ControllerAdvice will not help you there.
If you want a centralized error handling mechanism, you'd have to implement something similar to the controller advice yourself around your "Main" function, to which you can have unified exception handling responses.
I have an abstract class which are implementing some basic interface.
(attack method is not inherited from basic interface)
public abstract class AbstractClass implements BasicInterface {
public void attack(String attackerId, float attackerAttackSpeed) {
... // method body
}
}
I have also an class which are extending abstract class.
#Service
public class A extends AbstractClass {
// other methods...
}
Right now im trying to observe method attack(String attackerId, float attackerSpeedAttack)
#Aspect
#Component
public class AspectJ{
#After(value = "execution(* package.A.attack(attackerId, ..)) && args(attackerId)")
public void broadcastAttackMessage(String attackerId) {
... //method body
}
}
But unfortunately Intellij told me that This advise advises to no methods.
Also during starting the application i received error with a stack trace :
Caused by: java.lang.IllegalArgumentException: error at ::0 name binding only allowed in target, this, and args pcds
What i'm doing wrong? Is there any way to observe method from super class? Do i miss something?
I have to replace the deprecated class AbstractMarshallingPayloadEndpoint from springws 2.0. which my class was extending and overriding the invokeInternal method as below.
Example :
public class UpdateUserEndpoint extends AbstractMarshallingPayloadEndpoint {
#Override
protected Object invokeInternal(Object request){
//MY BUSINESS LOGIC here.
}
}
I am trying to replace my class with endpoint annotation.
#PayloadRoot(localPart = "MyRequest", namespace = "MyNamespace")
public MyResponse updateUser(MyRequest request) { ... }
I am ending up with exception while the server startup with a BeanCreationException:
I use Castor marshaller and unmarshaller in mapping.
Need some thoughts to proceed in a right way.
I would like to use Spring Event to "speak" with my beans in my web application.
So, for example, my bean which fires event is like this:
#Controller
#Scope("request")
#KeepAlive
public class Controller extends InitializingBean, ApplicationEventPublisherAware {
private ApplicationEventPublisher applicationEventPublisher;
public void test() {
applicationEventPublisher.publishEvent(new TestEvent(this));
}
}
And my listener event is like this:
#Component
#Scope("request")
#KeepAlive
public class Module implements ApplicationListener<TestEvent> {
#Override
public void onApplicationEvent(TestEvent event) {
}
}
The most important point is these beans are scope request because they need to be initialized at every time the page is called.
But in startup, I get this message:
Caused by: java.lang.IllegalStateException: No thread-bound request
found: Are you referring to request attributes outside of an actual
web request, or processing a request outside of the originally
receiving thread? If you are actually operating within a web request
and still receive this message, your code is probably running outside
of DispatcherServlet/DispatcherPortlet: In this case, use
RequestContextListener or RequestContextFilter to expose the current
request.
Like if Spring try to instantiate my Module bean in startup and as the bean is scope request, it can't do this (the context request is not instantiate)
If I delete event management, everything works fine.
So, my question is:
Is it possible to have event listener is scope request ? And how to do this ?
Thanks
Try to inject a scoped proxy in a Singleton ApplicationListener to handle the TestEvent.
#Scope(proxyMode=ScopedProxyMode.TARGET_CLASS, value="request")
public class TestEventHandler {
public void onTestEvent(TestEvent event)
// ...
}
}
public class TestEventApplicationListener implements ApplicationListener<TestEvent> {
#Autowired
private TestEventHandler handler;
#Override
public void onApplicationEvent(TestEvent event) {
handler.onTestEvent(event);
}
}