How to determine why Spring #Controller is not getting requests? - java

I am having trouble getting requests routed to one of my Spring #Controller that use #RequestMapping it is usually caused by a typo on my part but it is still annoying to hunt down those typos when you have a lot of controllers like I do.
for example a URI like /abc/{id}/something/{anotherId}
Is there some way to get spring to print out the process it used to determine that there was no match? In particular what would be useful is to know how far down the URI path there was a match as that would make finding typos a lot easier.
What debug flags exist for troubleshooting routing problems?

There are a few things that you can do -
Increase the log level - to DEBUG or may be even TRACE, this will clearly show how Spring MVC is trying to match your request to a handler method.
Debug - you can put a breakpoint as early as the DispatcherServlet and see how the mapping is being resolved.
You can implement a Endpoint Documentation Controller - something along these lines - http://biju-allandsundry.blogspot.com/2012/03/endpoint-documentation-controller-for.html, which can show all the endpoints URI's supported in the application.

Related

Difference between handling errors in web.xml and spring mvc config file

I have an Spring MVC web application, that has a org.springframework.web.servlet.handler.HandlerExceptionResolver that catches all exceptions and maps them to corresponding pre-defined error views and http status code. This HandlerExceptionResolver is defined in webmvc-config.xml file under src/main/webapp/WEB-INF.
Now, my client insists that I need to also map http status codes and exceptions in my web.xml file, which I am failing to understand because I don't see in what case my Spring MVC app would fail to catch an error, that would need to be handled by web.xml.
With that being said, this led me to the question of what is the fundamental difference between catching errors in web.xml and my custom spring mvc config file.
Can anyone help? Many thanks!
You could add a generic error handler for java.lang.Exception in the web.xml, just in case that anything escapes Spring MVC error handling mechanism. For example, you misconfigure something in the Spring MVC infrastructure itself, so Spring error handlers don't even get a chance to handle the error.
However, you should not re-map http status codes in the web.xml, because then the container will intercept all the generated error responses returned from Spring MVC and replace them with results generated by the error handlers defined in the web.xml. Of course, you could take care that the error handlers invoke the same logic as Spring ones, so that returned error responses are the same, but obviously that's quite an unnecessary work.
I would say that you should discuss this with your client in more detail and explain them the concepts and best practices related to Front Controller pattern.
Both mechanisms works. However the HandlerExceptionResolver is more flexible than the standard web.xml mappings in web.xml. The HandlerExceptionResolver provides you with a programmatic approach to handling exceptions as compared to the error mappings in web.xml.
For example you can override a provided implementation or implement a custom HandlerExceptionResolver with custom logic e.g sending an email to a system administrator before forwarding to your view.
Another advantage is that your handler exception resolver is a Spring bean which can have access to all services in your application context.
However you have to ensure that your HandlerExceptionResolver maps all possible exception.If you have an entry for Throwable then this should be sufficient.
Your client is just being cautious in case your HandlerExceptionResolver misses some exceptions. If its properly setup the web.xml mappings becomes redudant

Spring MVC: custom error page for 404s without web.xml file

I have a pretty big project with a lot of different controllers. I do have a main controller that has all of the mappings for the start of the program like (/login, /resetPassword, /logout, etc). I also do not have a web.xml file in the project. I need to add a custom error page for all unmapped requests. I have tried creating my own exception class and didn't work. Most of the solutions I find are to add error location to the web.xml. I would prefer not to have to create one but if anybody has any tips or can push me in the right direction that would help out so much. I've been stuck on this problem for a couple of days now. Thanks.
You should use 404 mapped to an error page in web.xml. Because it will handle even url requests that are not mapped to your DispatcherServlet. For example, imagine your Spring DispatcherServlet is mapped to any url ending in .htm, now some mistypes and tried to access something/somethingelse.do your application server will now present its own default error page to the user, which might not be pleasant.
The only time you should think about serving custom error pages from your MVC controllers, is when you have something specific to show the user. Specific as in, if an exception is encountered in this particular controller, I want to show a specific message, or redirect the user to a specific page. In these cases, you can use #ExceptionHandler methods in Spring controllers.
For more, look at this blog post, or refer the MVC documentation: https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
See this answer: How to make a filter to detect if the user requested a page that is not found?
Make a Filter
Use HttpServletResponseWrapper and override the sendError() and setStatus()
Pass the wrapped response through chain.doFilter(req, wrapper)
If you get a sendError() in your wrapper, see if it's a 404.
Take appropriate response.

Is it possible to use AOP for web app licence validation?

At present I have a Spring MVC web application, which uses ServletFilter to filter each HTTP request and check whether the user has really purchased the licence by checking and validating the licence file content.
I have mapped the filter in both spring xml file as well as web.xml appropriately. As I have access to HttpServletRequest and HttpServletResponse in the filter, I am able to redirect the user to error page if the validation fails.
So, now as the title suggests is it possible to do the same thing using Spring AOP? How can Spring AOP be configured to get access to the request and response objects created by the container to redirect the user?
How can Spring AOP be configured to get access to the request and
response objects created by the container to redirect the user?
You won't be able to get the same exact behavior as servlet Filters. A Filter operates around the target Servlet by passing in the ServletRequest and ServletResponse objects. In that sense, you can get similar behavior since AOP advice can operate around the joinpoint and intercept arguments that get passed around.
However, the AOP advice can't magically have access to the request and response. It either needs to advise a method that receives them or get them from some ThreadLocal or other container. For example, Spring has RequestContextHolder which you can use to get the HttpServletRequest. But it doesn't have anything to give you the HttpServletResponse (not technically true, but it's not reliable). You could write something similar that does.
Once the advice has access to the objects, it can simply invoke HttpServletResponse#sendRedirect(..) or forward() or whatever.
The best way to implement this would be using exceptions. That way the check and the handling can be different in different situation, e.g. web application vs. normal application.
Your check could be added to particular joinpoints using aop. In case it finds something amiss, it would throw a InvalidLicenseException (extends RuntimeException). Now there are several ways in which you can redirect a request to an error page when an exception is thrown. You could add this to your web.xml :
<error-page><exception-type>InvalidLicenseException</exception-type><location>/license-error.jsp</location></error-page>
Since you're using spring, you could also use annotations. Read this
You can do it out with AOP Advises,
Advice: Advices are actions taken for a particular join point. In
terms of programming, they are methods that gets executed when a
certain join point with matching pointcut is reached in the
application. You can think of Advices as Struts2 interceptors or
Servlet Filters.
So you can configure an advice to take care of validation . you can also configure them to execute at a particular point (i.e) where it needs to be executed .
But remember scope of AOP remains only for method invocation and it doesn't provide response as servlet filters does.
Learn More ..
Simple example here to start with.

Spring Webapp throwing 404 errors with no console log

I am working on a web application using the Spring framework and Hibernate. My problem is that I often receive 404 errors caused by a mistake I have made somewhere in the codebase but there are no exception messages in the console. Because of this I am struggling to find where the mistake is because the project has become very large and manually trying to find the problem is impractical. I'm assuming that Spring is causing the problem so my question is: is there some way of enabling more detailed error messages? Thanks
404 is an http error and only your web server might be knowing of it. Very likely with these failed requests, your application server or Spring container was never hit. Look for web server logs to identify the problem.
Troubleshooting 404 on IIS server
http://blogs.iis.net/tomkmvp/archive/2009/04/27/troubleshooting-a-404.aspx
Troubleshooting 404 on RAD web server
http://www-304.ibm.com/support/docview.wss?uid=swg27035752&aid=1
As a couple of people have already alluded to it, the issue here is that certain errors (like the 404 exception) get intercepted by the Servlet container, therefore never reaching Spring and whatever logging mechanisms you have may have set up. So the trick here is to change the order of importance of your Exceptions so that Spring gets a crack at it.
The best approach I have ever come across to catch, handle and adequately log all exceptions in Spring is described in this article: http://steveliles.github.io/configuring_global_exception_handling_in_spring_mvc.html
I have been implementing this setup since I came across that blog post, and it has been a lifesaver to say the least. It will give you the detailed error messages you need. The key is to basically create a custom Exception Handler by implementing Spring's HandlerExceptionResolver and Ordered interfaces, then returning the lowest possible order number, thus moving your exception handling up the totem pole:
import org.springframework.core.*;
import org.springframework.web.servlet.*
public class LoggingHandlerExceptionResolver
implements HandlerExceptionResolver, Ordered {
public int getOrder() {
return Integer.MIN_VALUE; // we're first in line, yay!
}
public ModelAndView resolveException(
HttpServletRequest aReq, HttpServletResponse aRes,
Object aHandler, Exception anExc
) {
anExc.printStackTrace(); // again, you can do better than this ;)
return null; // trigger other HandlerExceptionResolver's
}
}
The problem ended up being that there were a couple of missing annotations from one of my Hibernate entities. Following the procedure from the link below helped track it down by providing more detailed error messages:
http://www.captaindebug.com/2011/07/using-hibernate-validation-annotation.html
I also hit the problem of no console output while 404 error.
As in The Saint's answer, one of the causes of no console log:
the issue here is that certain errors (like the 404 exception) get intercepted by the Servlet container
"spring-framework-reference-3.2.3.pdf" --> 1.3 --> Logging --> Using Log4J, solved the problem in my environment.

Stop RestTemplate logging warning on 404 not found

We have a service based platform where its possible (/common) for a resource not to be found - e.g. calling our security module with the wrong username will return 404 Not Found, something that will happen every time a user makes a typo in their login box.
We use Spring RestTemplate for these calls, which is great, but every time a 404 is encountered it dutifully logs a warning which is spamming our logs.
We obviously don't want to suppress warnings, except in the specific case of 404 not found but there doesn't appear to be a way to do this (logger is private/final, method to invoke it is private etc).
Our solution is not good - to return 200/OK with empty dataset and handle a null pointer, which is both nasty and not a good restful implementation.
Does anyone know a better way to do this?
How about using a RegexFilter filter on your logging appender?
http://logging.apache.org/log4j/2.x/manual/filters.html#RegexFilter
... that's the Log4J way of doing it, but I'm guessing there must be similar filters for other logging libraries.
Implement a ResponseErrorHandler that returns false for hasError().
Assign it to your rest template using setErrorHandler().
The warning will not be logged.
This was logged in as issue SPR-12760 in the issue tracker of Spring Framework and resolved earlier this year (2015) in version 4.1.6. The solution was twofold: first, the warning message was downgraded to a debug message, and second, it was made easier to override the part of the code that is responsible for handling errors. So as a solution to your problem, upgrade the org.springframework:spring-web module to at least version 4.1.6.RELEASE.

Categories

Resources