What is the replacement for Spring's deprecated NoSuchRequestHandlingMethodException? - spring

The NoSuchRequestHandlingMethodException was deprecated in Spring 4.3, in favor of annotation-driven handler methods. What does this mean? The exception is still listed in the documentation, without mentioning its deprecated status. If I understand correctly, this exception is thrown when there is no request mapper for a given request. It appears to be handled by the DefaultExceptionHandlerResolver, here, and the relevant method has been deprecated as well.
If this method is deprecated, can I assume Spring does not throw this exception anymore? How am I supposed to replace this functionality with annotation-driven exception handling? Which exception am I supposed to handle, if this one is deprecated?
Side note: I also noticed a newer NoHandlerFoundException, here. Is this a replacement? If so, why? It appears to do the same thing. And why are the exceptions related to other HTTP status codes not deprecated? It all doesn't make a lot of sense.

The NoSuchRequestHandlingMethodException exception is part of the multiaction package that has been deprecated in Spring:
https://docs.spring.io/spring-framework/docs/2.5.x/javadoc-api/org/springframework/web/servlet/mvc/multiaction/class-use/NoSuchRequestHandlingMethodException.html
If you don't use multiactions, you can safely get rid of that catch statement and/or stop trying to catch and handle that exception. For example, some "Exception-to-Response error handlers" sample code might look like this to try and catch cases when the dispatcher doesn't find a proper mapping:
#ControllerAdvice
public class RestErrorHandler {
#ExceptionHandler({FileNotFoundException.class, NoSuchRequestHandlingMethodException.class})
#ResponseStatus(HttpStatus.NOT_FOUND)
#ResponseBody
public ErrorInfo process404(HttpServletRequest req, Exception ex) {
return handleException(req, HttpStatus.NOT_FOUND, ex);
}
}
But the latest dispatcher (non-multiaction) will never throw such an exception, so you could simply get rid of the NoSuchRequestHandlingMethodException and, instead, handle the NoHandlerFoundException (which is not thrown by default, but you can configure the spring dispatcher to throw it IF you really need to, because, by default, the dispatcher already returns a 404).

Related

How to catch exception thrown by save method of JpaRepository interface

I have a SpingBoot project that uses Spring Data Jpa as its repository level abstraction. I have a repository that extends JpaRepository interface. I call the save() method from within my Service layer as follows :
myCustomeRepository.save(new ObjectXYZ(abc,xyz));
I also observed that the save() method inherited from the CrudRepository throws IllegalArgumentException when receiving null entities.
Should I go ahead and try to catch the IllegalArgumentException in my Service layer ?i.e.
try{
myCustomeRepository.save(new ObjectXYZ(abc,xyz));
}catch (IllegalArgumentException iae){
}
NOTE: I have already implemented validation(#NotEmpty) at the DTO level using Hibernate Validator.
IllegalArgumentException extends RuntimeException, so the compiler will not force you to catch it.
Whether you catch it or not depends on what you want to do if it occurs:
If you expect it to never happen, because of the validation you have in place, then don't catch it. If it does happen (e.g. there's a problem with your validation) then your application will fail and you will find out that there's a problem.
If it indicates that the client has passed bad data to your service layer, you could catch it and do whatever your service layer does to report invalid data to its clients, or you could just not catch it, and (assuming you are writing a web application) have a global mapping of the exception to a 400 bad request status.
What you should not do is catch it and ignore it, because then you will have difficulty figuring out what is wrong with your system if it is ever thrown.

Global Exception Handling via Spring Advice In a MQ based Spring Boot Application

I've a MQ Spring Boot PaaS application where I need to implement exception handling via a common exception handler class (GlobalExceptionHandler). My PaaS application receives message from a source queue, perform some database operations via spring jpa and write the response back to a destination queue.
I need to handle all the database RuntimeException, custom business exceptions and other checked exceptions via GlobalExceptionHandler class.
My GlobalExceptionHandler will have handlers (method) defined for every exception. In my handler, I will be logging the exception first and then I will be creating a [error code, desc] and then I need to return it back to main flow.
I do not have any controller in my application. So I think, I can't use #ControllerAdvice. Currently I'm using spring AOP #AfterThrowing as below but I'm not able to return the [code, desc] from handlers.
#AfterThrowing(pointcut = "execution(* com.abc.xyz.service..*(..)) ",
throwing = "dataNotFoundException")
public void handleDataNotFoundException(DataNotFoundException dataNotFoundException) {
LOGGER.info("Info : " + dataNotFoundException.getMessage());
// code, desc need to create here and send it back to calling place.
// I need to change the return type here from void.
}
Can anyone please guide me in implementing exception handling here.
As I explained here, #AfterThrowing cannot modify return values or otherwise change the execution flow of your epplication. You cannot even catch the exception there. You need to use an #Around advice instead.
I suggest you read some documentation first and then ask more follow-up questions.

How to get a thrown exception from MailerClient of Playframework

I'm working with Play-Mailer inside of a Play application. I'm able to send emails to correct email addresses. So far so good. - But with none existing email addresses an exception is thrown from org.apache.commons.mailer but method mailerClient.send(email) itself throws nothing. - Is there a way to catch any exceptions form Play-Mailer?
EDIT:
I looked at the Play-Mailer plugin and saw that it is written in Scala. Scala does not have the notion of checked exceptions. Scala compiles directly to JVM bytecode and this is the "trick" how you can call Java code in Scala which throws checked exceptions but you do not have to rethrow them (the rules for checked exceptions are a bit different on JVM bytecode level).
You are free to use standard try-catch block in your Java code to handle the exceptions.
What kind of exceptions is the commons mailer throwing? Are you referring to: https://commons.apache.org/proper/commons-email/javadocs/api-release/org/apache/commons/mail/Email.html#send--
The send() methods throws an EmailException which is not a RuntimeException, so the exception would be propagated. If the Play-Mailer plugin is not catching it, you have to do it in your code:
try {
// try to send the mail
mailer.send(email);
} catch (EmailException e) {
// do something with the exception
}

how to apply #ControllerAdvice in intellij idea?

i am working with intellij idea.
and i plan to make use of #ControllerAdvice to handle exceptions.
then intellij reports "unhandled exception", because i don't have a try-catch block in my code. then how to solve it? there must be a way.
If you're not going to handle the checked exceptions with a try catch, you'll need to rethrow the exception in the method signature. This will force the method that calls that method to handle the exception
public void someMethod() throws IOException {
}
https://docs.oracle.com/javase/tutorial/essential/exceptions/
Annotations can not affect language semantics. You may use #ControllerAdvice to handle exceptions at runtime, but they must be declared for the code to be accepted by the Java compiler.

Integrate GWT with Spring Security framework

I have searched for tutorials on this topics, but all of them are outdated. Could anyone provide to me any links, or samples about integrating Spring security into GWT?
First of all, you have to bear in mind that GWT application is turned into javascript running on client-side, so there is nothing you can really do about securing some resources out there. All sensitive information should be stored on server side (as in every other case, not only for GWT), so the right way is to think of Spring Security integration from the point of view of application services layer and integrating that security with communication protocol you use - in case of GWT it is request factory in most cases.
The solution is not very simple, but I could not do it in any better way... any refinement suggestions are welcome.
You need to start with creating GWT ServiceLayerDecorator that will connect the world of request factory with world of Spring. Overwrite createServiceInstance method taking name of spring service class to be invoked from ServiceName annotation value and return instance of this service (you need to obtain it from Spring ApplicationContext):
final Class<?> serviceClass = requestContext.getAnnotation(ServiceName.class).value();
return appContext.getBean(serviceClass);
Also, you need to override superclass invoke(Method, Object...) method in order to catch all thrown runtime exceptions.
Caught exception cause should be analyzed, if it's an instance of Spring Security AccessDeniedException. If so, exception cause should be rethrown. In such case, GWT will not serialize exception into string, but rethrow it again, thus, dispatcher servlet can handle it by setting appropriate HTTP response status code. All other types of exceptions will be serialized by GWT into String.
Actually, you could catch only GWT ReportableException, but unfortunately it has package access modifier (heh... GWT is not so easily extensible). Catching all runtime exceptions is much more safe (althouth not very elegant, we have no choice) - if GWT implementation change, this code will still work fine.
Now you need to plug in your decorator. You can do it easily by extending request factory servlet and defining your's servlet constructor as follows:
public MyRequestFactoryServlet() {
this(new DefaultExceptionHandler(), new SpringServiceLayerDecorator());
}
The last thing - you need to do a dirty hack and overwrite request factory servlet doPost method changing the way how it handles exceptions - by default, exception is serialized into string and server sends 500 status code. Not all exceptions should result in 500 s.c - for example security exceptions should result in unauthorized status code. So what you need to do is to overwrite exception handling mechanism in the following way:
catch (RuntimeException e) {
if (e instanceof AccessDeniedException) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
} else {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
LOG.log(Level.SEVERE, "Unexpected error", e);
}
}
Instead of extending classes, you can try to use some 'around' aspects - it is cleaner solution in this case.
That's it! Now you can annotate your application services layer as usual with Spring Security annotations (#Secured and so forth).
I know - it's all complicated, but Google's request factory is hardly extendable. Guys did a great work about communication protocol, but design of this library is just terrible. Of course the client-side code has some limitations (it is compiled to java script), but server-side code could be designed much better...

Resources