Changing default Servlet response - java

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.

Related

In Spring MVC, does using 'redirect:process' or 'redirect:/process' differ regarding causing a lost session or session value?

I am experiencing strange behavior in my Spring MVC 3.2 application, and I noticed that this only happening when the redirect is done in an alternate way; so my questions are:
Is doing 'redirect:/process' any different from
'redirect:process' for redirecting to an internal controller ?
Does the added slash make any difference, such as affecting session handling ?
What are the reasons for a lost session (or lost session attributes) ?
There's a value I read through my application; even thou I do redirects in many cases, when I add a slash before the Controller URI, on production I am sometimes losing this value.
Any clue on how to troubleshoot the lost session value ?
Note: I am using methods httpRequest.getSession().setAttribute and httpSession.getAttribute for accessing the session.
with '/' you are declaring a path from root, which is your servlet context path. without '/', usually it's going to a path relative to your current sub path. for example, if you are at '/go/url', your are pointing to '/go/url/next', not '/next'.
I didn't check spring source code but that's how it works in web browser usually.
EDIT:
I'm sorry, in Spring MVC, you must always provide full path, not just relative path. So you should do "redirect:/full/path".
Just a note: / is a slash, backslash is \.
Except for external causes because of other errors, neither redirect:process not redirect:/process should change anything as long as the session is concerned.
But those 2 redirects are not supposed to do the same thing, unless you are on the root application page. Assuming that your application runs on HTTP port 80 on server.domain, with a servlet context of myapp, and you are processing a request to http://server.domain/myapp/local/part, redirect:process would ask browser to request http://server.domain/myapp/local/part/process, when redirect:/process would ask browser to request http://server.domain/myapp/process.
What happens next depends on your controller mappings.
You probably want to analyse, what is causing the lost session attributes. One approach would be to implement your own HttpSessionAttributeListener and log in public void attributeRemoved(HttpSessionBindingEvent event) implementation. Also keep spring log level to debug.

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.

Spring #RequestMapping redirect to same path with additional info

A somewhat unusual scenario perhaps, but we need to redirect in a Spring MVC controller from:
/js/hal-browser/browser.html
to:
/js/hal-browser/browser.html#/some_path/
All my attempted solutions to date have resulted in a redirect loop, as Spring performs the redirect but is then repeatedly matching /browser.html in the redirect URL, regardless of the additional info. What I need to say is 'match /browser.html ONLY if it's the end of the path'.
I have tried setUseSuffixPatternMatch(Boolean.FALSE); on the PathMatchConfigurer to no avail, also tried the following URI template regex pattern in the request mapping itself:
"/js/hal-browser/{file:browser\\.html$}"
..but still get a redirect loop. Ideas appreciated - this is Spring 4.1.6 in a SpringBoot 1.2.3 microservice, by way of context.
Update:
On further investigation and a better understanding of the URL fragment in use by the HAL browser to determine which path it will make a request to within the microservice itself, I believe the solution may lie not in trying to redirect off browser.html, as Spring will map this to the same controller method on every request regardless of the fragment value, but instead either reverting to the default context path for the application (/), which the HAL browser has set as its default entry point, or finding a way to configure the embedded tomcat container to respond with something sensible (not just a 404) on the default context path even though the app is mapped to /some_path.
As further context, we can redirect no problem at all from a convenience path of /browser (or whatever) into the HAL browser with the correct entry point fragment as the context path of the service - that works fine. The issue is the browser itself has a 'Go to entry point' button which, when pulling it in as a webjar, is hardcoded to /. The other alternative is to ditch the webjar and just copy in the static files for the browser and update the entry point.
The part after the # will never be sent to the server so in this case you'll always end-up with the same request within the loop.
What you can do is add a custom header in your controller, and make your controller intercept only the code where the header is not present by using the negation of the headers attribute, here's a pseudo code
#RequestMapping(value=[YOUR MAPPING], method=RequestMethod.GET, headers="!CustomHeader")
You could try not redirecting the user, but sending back the content you intended with some javascript to make the client browser to jump to the anchor on the after it loads, e.g. something like:
window.location.hash="/some_path/";

Spring MVC application context path

My Spring MVC application is runnning on a Tomcat behind an Apache 2 acting as a proxy. I access my app directly in tomcat via an url like http://localhost:8080/myapp. I access my app via proxy with an url like http://localhost/tomcat/myapp.
The second url makes my app behave incorrectly, because it supposes it lives in /myapp context path, but via the proxy it should live in /tomcat/myapp.
Is there a variable in Spring or Servlet API, that holds /tomcat/myapp if I am accessing it via the proxy, and /myapp if I am accessing it directly?
Thanx
I think you need to enable proxy support then. This link might help you or give a little hint in this regards.
http://tomcat.apache.org/tomcat-6.0-doc/proxy-howto.html
Just stumbled upon this post while searching for the config setting for tomcat.
There is a much easier way to configure tomcat to handle the exact situation you are experiencing. See:
http://tomcat.apache.org/tomcat-5.5-doc/proxy-howto.html
Simple configure a connector for the proxy in tomcat, and the servlet/struts context path issues will resolve.
-edit: Obviously I didn't read #2 comment...
I mean when I redirect to "/index.jsp"
it actually redirects to
"http://localhost/myapp/index.jsp"
instead of
"http://localhost/tomcat/myapp/index.jsp"
Redirect to index.jsp instead of /index.jsp
When you redirect to /index.jsp this acts as an absolute url and it gets redirected to myapp/index.jsp. index.jsp is a relative url and will redirect to tomcat/myapp/index.jsp

Basic question about servlet mapping

I am new to J2EE and related stuff in general. I am trying to move a particular web application from a Sun One server deployment on to JBoss. The application is filled with a lot of servlets where each one re-directs to another.
There are way too many servlets for me to enter a mapping between each of these servlet class to a URL-mapping individually in web.xml. The application code has many redirects where they name the servlet class names itself in the redirect-URL. As of now when I run it on JBoss the redirections to URL with servlet classnames in URL don't seem to work on JBoss (it gives a 404: Not Found, probably since there is no mapping in the web.xml). So is there any config setting that I can set to allow this to happen or should manually enter each and every URLpattern-to-Servlet mapping in the web.xml?
Thank you.
There are two solutions.
As we know JBoss uses Tomcat under the hood as a servlet container. You can enable invoker servlet, that would save you from mapping the whole lot in web.xml. But beware, it will be naive to do that, and not at all encouraged.
Secondly, you can write another servlet/filter and map just that in your web.xml for every url pattern, may be. Then that new servlet of your can forward the requests to whatever servlet it should.
I hope you get my point.
Not sure what you mean by this
the application code has many redirects where they name the servlet class names itself in the redirect-URL
Do you have hardcoded urls in the servlet classes? How many servlets? If you have hardcoded urls they may all have broken because the context is slightly different, or the appname, etc.etc. Can you post an example?
Well, there are some hard-coded URLs in the code, but even if i typed in the right URLs in browser directly I still get a 404. There are about 30 servlets (a conservative approximation). Ex: http://FQDN_SERVER.com/?arg1=ABCD&arg2=XYZ
Here the servlet-classname is literally the classname of the servlet without ".class" extension, which may not be a good practice. But the code is full of such redirections and if I have to change this then I have to add a new url-pattern to each of these servlets in the web.xml and construct a new red-rect URL for each of these servlets. So is there anyway I can avoid this or will I have to go through the pain of doing the above mentioned?
Thanks,
Manoj
Sorry the URL-pattern looks this http://FQDN_SERVER.com/servlet-classname?arg1=ABCD&arg2=XYZ

Categories

Resources