1

My spring controller should take any get request of any URI type except a URI which started with /resources/* as this is the call, if I am not wrong, done by spring container to load all the static content in view page.

Current configuration is like this

@RequestMapping(method = RequestMethod.GET, value="/*")

which working fine for request with URI / or /example but if someone make a typo in URI eg. /example/random/char it is throwing exception trace page not found(404) which is pretty obvious and leads me to make value="/**"

@RequestMapping(method = RequestMethod.GET, value="/**")

then the request with URI / or /example are unable to load my static content .js, .css or .png files in my view page. This lead me to the conclusion that spring internally make get call to load these files with an URL pattern eg. http://localhost:8080/resources/my.jpg.

Note:- I intentionally removed my project name by configuring tomcat.

Update Okay @dimitrisli comment make me realize that I need to elaborate a little about my project.

It basically a URL redirecting component. A user simply call my application through get request and ended with redirecting to the actual page.

For example user request me throw their browser with URL let's say http://localhost:8080/sample. Now my application needs to split the URL to get the string sample and search in db for the actual URL against it(so sample is the alias name for a really long URL). If URL exist it will redirect to the actual page else page does not exist message will show.

2 Answers2

1

(Update based on comments)

This is how you can deal with 404 errors.

Option 1

in web.xml include the following to forward on main page:

<error-page>
    <error-code>404</error-code>
    <location>/</location>
</error-page>

or your custom error specific page:

<error-page>
    <error-code>404</error-code>
    <location>/my-custom-error-page</location>
</error-page>

Option 2

Define a catch-all error handler at the Controller layer:

@ExceptionHandler(Exception.class)
public String handleAllExceptions(Exception e) {
    log.error("There was an exception thrown! ", e);
    return "index";
}

Based on the name of the folder you want to exclude (resources) and your description (.js/.css/.png) I'm assuming you are referring to the static content of your web project.

You need to explicitly define the static content in your dispatcher servlet xml as follows (follow the directory convention of your project for static data):

<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:resources mapping="/css/**" location="/resources/css/" />
<mvc:resources mapping="/images/**" location="/resources/images/" />
<mvc:resources mapping="/js/**" location="/resources/js/" />
<mvc:resources mapping="/fonts/**" location="/resources/fonts/" />
dimitrisli
  • 20,895
  • 12
  • 59
  • 63
  • Thanks for your response but that is not my concern. I have already done this. @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); } – Satyaprakash Nayak Aug 17 '16 at 08:09
  • What is exactly your concern? If you have defined the resources details then all static content is served by the webapp and it's not going through the @RequestMapping – dimitrisli Aug 17 '16 at 08:34
  • Yes you are right but it is not going through RequestMapping when value="/*" but it is going to RequestMapping when value="/**" – Satyaprakash Nayak Aug 17 '16 at 09:21
  • This is not how you deal with 404 errors. "/**" at @RequestMapping level is not a viable solution since you are shortcircuiting all requests through this single mapping. I'll amend my answer to include info about how to deal with 404 errors – dimitrisli Aug 17 '16 at 09:42
  • Hmmm...I know how to handle exception in spring. But my business requirement is little different. I need validate all string in requested URL i.e what ever coming after "http://localhost:8080" and then I need to throw the exception in custom way. So over all I need to catch the request in RequestMapping first. – Satyaprakash Nayak Aug 17 '16 at 10:30
  • If a user make a request let's say "http://localhost:8080/x/y/z" then I need to check whether "x/y/z" exist in db or not. – Satyaprakash Nayak Aug 17 '16 at 10:44
0

It sounds like you need add a resource handler to your project. This will allow files in your /resources folder to pass through. Here is another post about it with some example code for reference.

registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");

Another option may be to implement an interceptor that catches all URIs before making it to your controller method. This would allow you to add some logic to make sure things exist in the DB prior to actually reaching your controller rather than having a single controller method doing everything. Extending HandlerInterceptorAdapter might be something to look into.

Community
  • 1
  • 1
itsthejash
  • 138
  • 8
  • The first suggestion of configuring "resource handler" is already there. But the second suggestion about "interceptor" looks very meaningful to me. I have to try for this one. Thanks. – Satyaprakash Nayak Aug 17 '16 at 16:44
  • Maybe also try adding `registry.setOrder(Ordered.HIGHEST_PRECEDENCE);` to make sure it takes highest precedence. – itsthejash Aug 17 '16 at 16:58
  • `registry.setOrder(Ordered.HIGHEST_PRECEDENCE);` did not work for me. This is useful I guess when you have multiple resources to handle. – Satyaprakash Nayak Aug 18 '16 at 06:31