• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

RequestDispatcher.forward not working

 
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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!
 
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Save yourself a lot of time - use Struts..
 
Rob Lynn
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Sheriff
Posts: 67752
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
Rob Lynn
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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);
 
Ranch Hand
Posts: 167
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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?
 
Rob Lynn
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Sheriff
Posts: 67752
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What about the url mapping for the servlet?
 
Rob Lynn
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Sheriff
Posts: 67752
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes! Typing it in like that works, but going through the controller does not.
 
Rob Lynn
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 783
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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!
 
Rob Lynn
Greenhorn
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The message is:

"HTTP Status 404 ..."
"The requested resource (/Requirements/WEB-INF/classes/com/requirements/servlets/RequirementList) is not available"
 
Sharad Agarwal
Ranch Hand
Posts: 167
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 167
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 167
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Sheriff
Posts: 67752
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Sheriff
Posts: 67752
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 28
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Try 100 things. 2 will work out, but you will never know in advance which 2. This tiny ad might be one:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic