aspose file tools*
The moose likes Servlets and the fly likes RequestDispatcher.forward not working Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Servlets
Bookmark "RequestDispatcher.forward not working" Watch "RequestDispatcher.forward not working" New topic
Author

RequestDispatcher.forward not working

Rob Lynn
Greenhorn

Joined: Jun 27, 2005
Posts: 28
This one should be easy, but I'm new to this stuff and can't get it working. I am trying to switch from using web.xml to forward to the requested servlet to using a 'Front Controller' servlet. I can get to the controller servlet and the path for the new servlet in the error message is correct, but I get an error that the requested resource is not found. My code is:

getServletConfig().getServletContext()
.getRequestDispatcher(newPage).forward(request, response);

where newPage is a string, e.g.: "RequirementList" (which is another servlet found currently in the same directory as the controller & with doGet & doPost methods.)

What am I doing wrong?

Thanks!
PJ Crump
Ranch Hand

Joined: Feb 06, 2002
Posts: 51
Save yourself a lot of time - use Struts..
Rob Lynn
Greenhorn

Joined: Jun 27, 2005
Posts: 28
That's tempting - I'll be starting another application soon & would like to try Struts. This app, however is very small compared to the other one so I was trying to keep it simple.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61043
    
  66

In my opinion: save yourself a lot of time and avoid Struts.

I believe the problem with your forward request is the absence of the leading /.

Also, if this is in a servlet, why not just use the request.getRequestDispatcher() method?


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Rob Lynn
Greenhorn

Joined: Jun 27, 2005
Posts: 28
I hadn't used request.getRequestDispatcher because I'm new to this & am copying whatever sample code I can find.

I made 2 changes and get the same error:

newPage = "/RequirementList";
request.getRequestDispatcher(newPage).forward(request, response);
Sharad Agarwal
Ranch Hand

Joined: Sep 11, 2002
Posts: 167
Originally posted by Rob Lynn:

newPage = "/RequirementList";
request.getRequestDispatcher(newPage).forward(request, response);


The changes look good. Is the 'RequirementList' servlet registered in web.xml?


Alco-Haul: We move spirits.
Demented Deliberations of a Dilettante
Rob Lynn
Greenhorn

Joined: Jun 27, 2005
Posts: 28
Yes:

<servlet>
<servlet-name>RequirementList</servlet-name>
<servlet-class>com.requirements.servlets.RequirementList</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

I added the load-on-startup just to see if it would make a difference.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61043
    
  66

What about the url mapping for the servlet?
Rob Lynn
Greenhorn

Joined: Jun 27, 2005
Posts: 28
I had taken that out, so I put it back in. I got the same results.

<servlet-mapping>
<servlet-name>RequirementList</servlet-name>
<url-pattern>/RequirementList</url-pattern>
</servlet-mapping>
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61043
    
  66

How did you expect it to work without a mapping?

Can you hit the servlet directly? As in: http://yourserver/context/RequirementList

What exactly happens?
[ June 27, 2005: Message edited by: Bear Bibeault ]
Rob Lynn
Greenhorn

Joined: Jun 27, 2005
Posts: 28
Yes! Typing it in like that works, but going through the controller does not.
Rob Lynn
Greenhorn

Joined: Jun 27, 2005
Posts: 28
BTW, the answer to your first question: I was trying to use the controller to get to the next screen (replacing that functionality in web.xml) and assumed the 'mapping' would happen there. I originally took out all of the servlet & servlet mapping elements from web.xml and added one of each to direct everything to the controller. Right now I'm back where I started - with everything in web.xml. If I changed to the original names and deleted the controller entries everything would work again.
Paul Bourdeaux
Ranch Hand

Joined: May 24, 2004
Posts: 783
What is the error mesage that you are getting?

Also "save yourself a lot of time and avoid Struts." - I agree! Struts is good if you are familiar with it and you have a web application large enough to take advantage of it... if not you are just adding a lot of work!


“Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.” - Rich Cook
Rob Lynn
Greenhorn

Joined: Jun 27, 2005
Posts: 28
The message is:

"HTTP Status 404 ..."
"The requested resource (/Requirements/WEB-INF/classes/com/requirements/servlets/RequirementList) is not available"
Sharad Agarwal
Ranch Hand

Joined: Sep 11, 2002
Posts: 167
I know you have already shared some of these, but can you post the following things again:
1. Servlet Definition
2. Servlet Mapping
3. Direct browser URL that works
4. Code snippet of RequestDispatcher that gives an error

I think the key is in one of these four and could be as simple as a small typo. Please use the CODE UBB tag (button below text area) so that the code is more easily readable.
[ June 27, 2005: Message edited by: Sharad Agarwal ]
Rob Lynn
Greenhorn

Joined: Jun 27, 2005
Posts: 28
Here's the main part of the servlet, which also contains the RequestDispatcher command that failed:



(The '.do' is not due to struts - it came out of a book.)

Here's the servlet mapping for this servlet:




The direct browser URL really doesn't matter because it has nothing to do with this servlet. I had everything working through the web.xml before using these urls and what I really wanted is to move this control out of web.xml and into a servlet. If everything still has to be declared in web.xml then I may as well stick with my original code and skip the 'controller.'

BTW, thanks for all your help!
Sharad Agarwal
Ranch Hand

Joined: Sep 11, 2002
Posts: 167
The parameter for the getRequestDispatcher() method needs to be a URL and not physical paths for the class. The path can either be relative to the URL for the servlet that you invoke it from. Or it can be absolute (begins with a '/'). Note that the absolute path is always from the context root.

In brief, the working URL is all-important. If http://yourserver/context/yourServlet is working from the browser, then a correct getRequestDispatcher call would be:

req.getRequestDispatcher("/yourServlet")

Also note that the parameter is from the URL-pattern defined in web.xml and NOT the name of the servlet class.

Originally posted by Rob Lynn:
The direct browser URL really doesn't matter because it has nothing to do with this servlet. I had everything working through the web.xml before using these urls and what I really wanted is to move this control out of web.xml and into a servlet. If everything still has to be declared in web.xml then I may as well stick with my original code and skip the 'controller.'

BTW, thanks for all your help!


By design, these settings have to be declared in web.xml. Why are you averse from having settings there? It is a spec-complaint abstraction that allows you to change many things without having to touch your Java code.
The concept of the controller in MVC frameworks is a little more than a router, but that is a longer discussion and a bit out of scope in this particular forum.

Hope this helps.
[ June 28, 2005: Message edited by: Sharad Agarwal ]
Rob Lynn
Greenhorn

Joined: Jun 27, 2005
Posts: 28
In other words, in order to use the RequestDispatcher for a servlet (I have successfully forwarded to many jsps in other parts of the application) the servlet must be registered in web.xml with both a <servlet> and <servlet-mapping>? Do people who use a servlet in the MVC design pattern to control which servlet to forward to use a RequestDispatcher or some other means to forward control that does not require each servlet to be declared in web.xml? Do they forward to servlets which extend HttpServlet? I have not seen any good solid examples so far, especially containing the url in the example (I have seen some which read from some non-existent file... and go to a non-existent servlet) - do you know of any examples I can look at?

Thanks!
Sharad Agarwal
Ranch Hand

Joined: Sep 11, 2002
Posts: 167
Originally posted by Rob Lynn:
In other words, in order to use the RequestDispatcher for a servlet (I have successfully forwarded to many jsps in other parts of the application) the servlet must be registered in web.xml with both a <servlet> and <servlet-mapping>?

Yes.

Do people who use a servlet in the MVC design pattern to control which servlet to forward to use a RequestDispatcher or some other means to forward control that does not require each servlet to be declared in web.xml?

Struts does not use RequestDispatcher to forward control to Actions. In fact, the Struts Controller retains its thread until the Action is done with it's processing and then it (the Controller) decides which view JSP to forward to.

Do they forward to servlets which extend HttpServlet?

They don't forward to Actions. They delegate to actions. Actions do not extend HttpServlet, they extend the struts Action class (org.apache.struts.action.Action).

I have not seen any good solid examples so far, especially containing the url in the example (I have seen some which read from some non-existent file... and go to a non-existent servlet) - do you know of any examples I can look at?


If you are interested in Struts, I would suggest reading up at the Apache Struts homepage (http://struts.apache.org/). Or get a good book, you should be up and running with basic knowledge in a few days.
[ June 28, 2005: Message edited by: Sharad Agarwal ]
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61043
    
  66

For some good and simple examples of JSP/servlet "stuff" see Ben Souther's Simple Stuff page.

Sharad is correct in that most Front Controller patterns do not rely upon forwarding to other servlets, but delegate to classes that conform to an interface that the Front Controller expects (frequently referred to as an "action" -- which is an unfortunate naming collision with the latest JSP specification which uses the term "action" to mean standard and custom tags). And although Struts follows this pattern, I still do not recommend it as it is simply too bloated with other stuff for it to be a good example for learning.

Setting up such a pattern is fairly straight-fowrward:

1) Define an interface with a method called something like "execute" or "perform" or whatever verb makes the most sense to you. Context info such as the request and response is passed to this method.

Let's call this interface "Actionable" for this example.

2) All your "actions" implement this interface.

3) Set up your Front Controller servlet as the entry point for all requests. Info on the end of the URL (known as "path info") or, less elegantly, a request parameter, is used to identify which of your Actionable classes is to be instantitied and "executed".

The pathInfo->class mapping can be defined in a properties file, an XML file (like Struts and my own implementation do), or (bad idea) as the full classname as the Invoker does.

4) The Front Controller instatiates the action class and calls the "execute" method.

The only tricky part is deciding how you want to define your pathInfo to actionClassName mappings. A properties file is probably the path of least resistance if you don't want to go the XML route.

For example:

Let's say you have an "action" that deletes an item. You could have a mapping for the pathInfo of "deleteItem" to an Actionable class named org.bibeault.this.that.theother.DeleteItemAction.

Let's say that the Front Controller servlet is mapped to "/action", and let's say your app context is "xyz".

So the URL for this action would be http://www.whatever.com/xyz/action/deleteItem

The Front Controller obtains the "/deleteItem" via request.getPathInfo() and uses it to map to the action class. Class.forName( actionClassName ).newInstance() is used to instatiate it as an Actionable, and then the "execute" method is called.

Clear as mud?
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61043
    
  66

Or.....

I've also seen Front Controllers implemented using a request dispatcher forward and all the definitions are in the web.xml as you surmised. And yes, every such distinct "action" requires a servlet declaration and a mapping declaration.

Many find that too "wordy" in the web.xml and so opt to factor out the mappings to another mechansism as described above.
Rob Lynn
Greenhorn

Joined: Jun 27, 2005
Posts: 28
Thanks for all the great advice!

BTW, my original problem where nothing worked was because I had moved my controller servlet (when I couldn't get it to work where it was) and forgot to change my web.xml entry. So then when I had the right format for forwarding, it never got to the servlet.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: RequestDispatcher.forward not working