Understanding the <url-pattern>/*</url-pattern>
Other Questions of similar pattern:
1) How to exclude from url-pattern in servlet mapping?
2) To exclude content from url-pattern
While developing web.xml in application, do take care of the <url-pattern>.
Try not to give a generic url-pattern ie., <url-pattern>/*</url-pattern>.The disadvantage of this URL Pattern is, any request coming to the server will fall in this URL PATTERN(except for those you have explicitly defined). Suppose browser is requesting a page which has images,css,etc then you will find page will load with the servlet response,while the images,css,js,etc are not getting loaded and it will be very difficult to find the reason for this type of behaviour.
The reason is as:-
Our browser requests in the following steps
Step1: The browser requests the page and gets back the response which contains all other path.
Step2: The browser again requests all the other path to the server and these path contains the images,css,etc
What happens in our problem is in step 2,the browser's request goes to the server and now the images,etc also falls in the <url-pattern >/*</url-pattern>,which redirects to a servlet and this is the problem. This is the reason why we don't get images and other files in our web page.
Let us solve this with the help of example:
web.xml
abc.jsp
Whenever a request comes as localhost:8080/TestApp/abc.jsp, the abc.jsp loads and images are not getting loaded. The images goes to the SevletDefault mapping. You can see this by printing any text in doGet or doPost method of ServletDefault class.
Reason is,all files other than abc.jsp will go to ServletDefault.
Solution for /* type pattern in web.xml
I found two approaches to solve this problem
Approach 1:
Make a common servlet which consumes all the files which have the pattern for images,css,javascript,etc
web.xml (modified)
Keep the images in the 'images' folder. For a new request to the servlet, you will find,all the images,css,js requests goes to CommonServlet. Write a CommonServlet which retuns back the file itself in the response.
CommonServlet.java
The above servlet write the contents of file in the response and our problem is solved.
Approach 2:
This approach sets the context in jboss server.xml file.
server.xml is found at Jboss_home\server\default\deploy\jboss-web.deployer path.
Open server.xml in edit mode
Add the context in server.xml.
Find text similar to the following code in server.xml
set docBase,path according to your path.This will solve your problem.
These were the two approaches which i found out for this problem. Please let me know if you know any more approach.
Other Questions of similar pattern:
1) How to exclude from url-pattern in servlet mapping?
2) To exclude content from url-pattern
While developing web.xml in application, do take care of the <url-pattern>.
Try not to give a generic url-pattern ie., <url-pattern>/*</url-pattern>.The disadvantage of this URL Pattern is, any request coming to the server will fall in this URL PATTERN(except for those you have explicitly defined). Suppose browser is requesting a page which has images,css,etc then you will find page will load with the servlet response,while the images,css,js,etc are not getting loaded and it will be very difficult to find the reason for this type of behaviour.
The reason is as:-
Our browser requests in the following steps
Step1: The browser requests the page and gets back the response which contains all other path.
Step2: The browser again requests all the other path to the server and these path contains the images,css,etc
What happens in our problem is in step 2,the browser's request goes to the server and now the images,etc also falls in the <url-pattern >/*</url-pattern>,which redirects to a servlet and this is the problem. This is the reason why we don't get images and other files in our web page.
Let us solve this with the help of example:
web.xml
TestUrlPattern ServletDefault com.test.ServletDefault ServletDefault /* abcd /abc.jsp abcd /abc.jsp
abc.jsp
<html> <head> <title>TestUrlPattern</title> </head> <body> Sample text <img src="Desert.jpg" > </body> </html>
Whenever a request comes as localhost:8080/TestApp/abc.jsp, the abc.jsp loads and images are not getting loaded. The images goes to the SevletDefault mapping. You can see this by printing any text in doGet or doPost method of ServletDefault class.
Reason is,all files other than abc.jsp will go to ServletDefault.
Solution for /* type pattern in web.xml
I found two approaches to solve this problem
Approach 1:
Make a common servlet which consumes all the files which have the pattern for images,css,javascript,etc
web.xml (modified)
TestUrlPattern CommonServlet com.test.CommonServlet Servlet com.test.Servlet Servlet /* abcd /abc.jsp abcd /abc.jsp CommonServlet /images/ CommonServlet /stylesheet.css CommonServlet /javascript.js
Keep the images in the 'images' folder. For a new request to the servlet, you will find,all the images,css,js requests goes to CommonServlet. Write a CommonServlet which retuns back the file itself in the response.
CommonServlet.java
public class CommonServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext sc = getServletContext(); String path=req.getRequestURI().substring(req.getContextPath().length()+1, req.getRequestURI().length()); String filename = sc.getRealPath(path); // Get the MIME type of the image String mimeType = sc.getMimeType(filename); if (mimeType == null) { sc.log("Could not get MIME type of "+filename); resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } // Set content type resp.setContentType(mimeType); // Set content size File file = new File(filename); resp.setContentLength((int)file.length()); // Open the file and output streams FileInputStream in = new FileInputStream(file); OutputStream out = resp.getOutputStream(); // Copy the contents of the file to the output stream byte[] buf = new byte[1024]; int count = 0; while ((count = in.read(buf)) >= 0) { out.write(buf, 0, count); } in.close(); out.close(); } }
The above servlet write the contents of file in the response and our problem is solved.
Approach 2:
This approach sets the context in jboss server.xml file.
server.xml is found at Jboss_home\server\default\deploy\jboss-web.deployer path.
Open server.xml in edit mode
Add the context in server.xml.
Find text similar to the following code in server.xml
<Host name="localhost" autoDeploy="false" deployOnStartup="false" deployXML="false"configClass="org.jboss.web.tomcat.security.config.JBossContextConfig" >Below the above code add the context as:
set docBase,path according to your path.This will solve your problem.
These were the two approaches which i found out for this problem. Please let me know if you know any more approach.
Great Post!!!Thanks a lot for such post.
ReplyDelete:-)
I have almost the same problem but I want to avoid these solutions. But it look like to be the only one working.
ReplyDeleteThx for posting your solutions! It helps!
Finally I use another solution. I put a filter that redirect "/" page to my start serlvet.
ReplyDeleteThe filter:
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String pageName = req.getServletPath();
if(pageName.equals("/")) {
res.sendRedirect( req.getContextPath() + "/start" );
} else {
chain.doFilter(request, response);
}
web.xml:
RootRedirectionFilter
com.servlet.filter.RootRedirectionFilter
RootRedirectionFilter
/*
com.servlet.GameLogin
GameStart
GameStart
/start
very nice tutorial. another thing the readers would like to know is that a JSP can also be mapped to url.
ReplyDeletehi i want to know once the servlet is created can we change the url pattern what we had mentioned while creating it. If yes how to do.
ReplyDeleteI did not get your question properly..
DeleteAccording to my understanding your question is to change the URL pattern of servlet. If that is the question, then definitely, we can change the Url pattern of any servlet any time. Just edit or create entry in web-xml for that servlet.
Why should this be so complex! What about performance?
ReplyDeleteWhen the web server is very well capable of serving static files directly, you are reading the static content unnecessarily in java code and sending the same back.
My WebContent folder has some static files and of-course the servlet is in a separate source folder.
A very simple alternative which works.. change the url pattern from / or /* to something like /1/* or /1/
MyServlet
/1/
This ensures that all such calls go to my Servlet
http://localhost:8080/Servlet/1/*
And static content in other folders get directly served by the web server
http://localhost:8080/Servlet/Images/*
Let me know what you think
There are many cases, where the application is already running and change is URL is not affordable. In that case, you can use the above approach...
DeleteHi Bipin,
ReplyDeleteWhy should this be so complex! What about performance?
Performance impact can be determined only when you implement for some actual requirement.
2. You are right in the sense that Web servers can handle static content well and support caching as well. Here we have shown only a demo application. But you might have requirement where you want to change the url of a image every time, there it will be useful to render static content through java code.
Demo just explains /* and / pattern and does not mandate use of any approach in any form.
Thanks Vinkal,
ReplyDeleteThis was a very useful and very well written blog - it saved me a lot of time with troubleshooting. Karen.
Awesome, this topic is very useful for me, i got more information from this site
ReplyDeletenice post.this post is very useful for us keep it up.
ReplyDeletehi i got some problem like this exactly like this
ReplyDeletei'm using tomcat 8.0.0 and
my URL is http://localhost:8084/SocMedPrototype
I'm gonna create something like facebook profile so its become
http://localhost:8084/SocMedPrototype/user/123123
but then all link become http://localhost:8084/SocMedPrototype/user/123123/img/testImage
:(
anyone can help me?
"Nice and good article.. it is very useful for me to learn and understand easily.. thanks for sharing your valuable information and time.. please keep updating.php jobs in hyderabad.
ReplyDelete"
Nice post.this post is very useful for us keep it up.
ReplyDeleteaws Training in Bangalore
python Training in Bangalore
hadoop Training in Bangalore
angular js Training in Bangalore
bigdata analytics Training in Bangalore
python Training in Bangalore
aws Training in Bangalore
I am really happy with your blog because your article is very unique and powerful for new reader.
ReplyDeleteaws Training in Bangalore
python Training in Bangalore
hadoop Training in Bangalore
angular js Training in Bangalore
bigdata analytics Training in Bangalore
python Training in Bangalore
aws Training in Bangalore
Nice and good article.. it is very useful for me to learn and understand easily.. thanks for sharing your valuable information and time
ReplyDeleteMicrosoft Windows Azure Training | Online Course | Certification in chennai | Microsoft Windows Azure Training | Online Course | Certification in bangalore | Microsoft Windows Azure Training | Online Course | Certification in hyderabad | Microsoft Windows Azure Training | Online Course | Certification in pune