Stop RestTemplate logging warning on 404 not found - java

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.

Related

Handle # character in spring web

I am trying to add an exception for security rules in Spring but getting 401 meaning my mapping is not recognized. The uri is /test/acc#v1=1&v2=2...
I have security configured:
http.authorizeExchange().pathMatchers("/test/acc*{v:.+}")
and
http.authorizeExchange().pathMatchers("/test/acc*")
And my controller annotation is:
#GetMapping("/test/acc{suffix:.+}")
None of it works, I keep on getting 401. Can someone help me out here?
It is a general consensus that Server does not receive the URL fragmentation details and it is applicable for all major servers java based servers like tomcat, jetty..etc please refer for more details

Dropwizard and Jersey SSE (Server side events)

Does anyone used this Jersey SSE feature already in a Dropwizard application? I tried it with DW 0.9.1 but all I get is this Exception at startup:
[main]: /:?:?- unavailable
org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization.
[[FATAL] No injection source found for a parameter of type public org.glassfish.jersey.media.sse.EventOutput .......
Authentication and Authorization is also done like here with SecurityContext. I tried also a very simple no authentication/authorization app and there is the same problem. Perhaps I have to register SSE, but I dont know how if this solves my problem, because Jersey documentation says that there is a automated registering since version 2.8.x.
What i tried, but does not help:
environment.jersey().register(SseFeature.class);
environment.jersey().getResourceConfig().register(SseFeature.class);
System.out.println("sse feature:" + environment.jersey().getResourceConfig().getConfiguration().isRegistered(SseFeature.class));
Output:
...
sse feature:true
WARN [2015-11-11 10:12:58,845] [main]: org.glassfish.jersey.internal.Errors:?:?- The following warnings have been detected: WARNING: Cannot create new registration for component type class org.glassfish.jersey.media.sse.SseFeature: Existing previous registration found for the type.
...
Does anyone know how to solve this problem or have any ideas?
This is a really strange problem. Dont know why it works now. Perhaps if others have the same problem, I have done this:
environment.jersey().register(new EventOutputMesssageBodyWriter());
The MsgBodyWriter does no write (writeTo method is empty), but it works. Really strange ...

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.

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

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.

Changing default Servlet response

I have a Java Web application that has several servlets with the following mappings.
ServletOne -> /one
ServletTwo -> /two
ServletThree -> /three
When I make a request for an action that doesn't exist I get a 403 (Forbidden), ie: /foo. I would like to change that to give a 404 (Not Found). How can I do that?
If getting a 404 is default behavior, then where can I look for that setting that's throwing things off? I tried googling for this, but I wasn't able to come up with a search query that yielded anything related.
TIA!
Have a servlet map to / (which will capture everything) and then make that return a 404 in the doGet/processRequest calls. That way you won't rely on any specific behaviour of the app server you're using to configure it.
What servlet container are you using?
Tomcat, by default, maps /* to DefaultServlet (according to the $TOMCAT_HOME/conf/web.xml) for the server, which I just confirmed will throw a 404 by default if the mapping doesn't exist.
I would suggest starting by looking at your servlet container's web.xml file to see if a similar default mapping exists.

Categories

Resources