Struts Controller Servlet error

Hi,

For a particular requirement I have to parse an input xml and determine the action to be performed on the basis on the value specified by a tag "request_type". For doing this I extended a class from ActionServlet and used JDOM (v1.0) to parse the xml and retrieve the request type. Now how can I forward the request to the appropriate action class.

I have the following definition in my struts-config.xml

<action-mappings type="org.apache.struts.action.ActionMapping">
    <action
                  path = "/xyz"
                 type="com.infosys.vru.actions.LoginAction">
     </action>
</action-mappings

I tried the following in the Controller (servlet extended from Action Servlet) and defined in web.xml as below

###### definition of servlet-class in web.xml
<servlet-class>Controller</servlet-class>

########## process method in Controller ##########

/* after determining the request type i tired the following to forward the request to the appropriate action class*/

ModuleConfig modConfig = this.getModuleConfig(request);
ActionConfig aConf = modConfig.findActionConfig("/"+requestType);
AtionMapping map = new ActionMapping();
map.setForward(aConf.getName());
ForwardAction fAction = new ForwardAction();
ActionForward forward = fAction.execute(map,(ActionForm)null,request,response);

I tried all this as the ActionServlet.findForward and findMappiing methods have been depricated.

please help me in fixing this issue. could any among you give a brief idea about what needs to be done while extending an action servlet.

And following is the error which I get:

[11/15/04 19:04:15:010 PST]  71c64e1 WebGroup      E SRVE0026E: [Servlet Error]-[action]: com.ibm.ws.webcontainer.webapp.WebAppErrorReport: No context-relative URI specified via the &#39;parameter&#39; attribute
      at com.ibm.ws.webcontainer.srt.SRTServletResponseContext.sendError(SRTServletResponseContext.java:152)
      at com.ibm.ws.webcontainer.srt.SRTServletResponse.sendError(SRTServletResponse.java:626)
      at org.apache.struts.actions.ForwardAction.execute(ForwardAction.java:143)
      at Controller.process(Controller.java:82)
      at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
      at com.ibm.ws.webcontainer.servlet.StrictServletInstance.doService(StrictServletInstance.java:110)
      at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet._service(StrictLifecycleServlet.java:174)
      at com.ibm.ws.webcontainer.servlet.IdleServletState.service(StrictLifecycleServlet.java:313)
      at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet.service(StrictLifecycleServlet.java:116)
      at com.ibm.ws.webcontainer.servlet.ServletInstance.service(ServletInstance.java:283)
      at com.ibm.ws.webcontainer.servlet.ValidServletReferenceState.dispatch(ValidServletReferenceState.java:42)
      at com.ibm.ws.webcontainer.servlet.ServletInstanceReference.dispatch(ServletInstanceReference.java:40)
      at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.handleWebAppDispatch(WebAppRequestDispatcher.java:948)
      at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:530)
      at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:176)
      at com.ibm.ws.webcontainer.srt.WebAppInvoker.doForward(WebAppInvoker.java:79)
      at com.ibm.ws.webcontainer.srt.WebAppInvoker.handleInvocationHook(WebAppInvoker.java:201)
      at com.ibm.ws.webcontainer.cache.invocation.CachedInvocation.handleInvocation(CachedInvocation.java:71)
      at com.ibm.ws.webcontainer.srp.ServletRequestProcessor.dispatchByURI(ServletRequestProcessor.java:182)
      at com.ibm.ws.webcontainer.oselistener.OSEListenerDispatcher.service(OSEListener.java:334)
      at com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java:56)
      at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:610)
      at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:431)
      at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:593)

Thanks,
Ashwin
AshwinAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

petmagdyCommented:
Hi Ashwin,

I need the complete definition of ur conroller servlet in web.xml, the struts version u r using, and the full function u overwrite in ur controller
0
AshwinAuthor Commented:
The following is my servlet definition is web.xml:-

<servlet>
            <servlet-name>action</servlet-name>
<!--            <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> -->
                  <servlet-class>Controller</servlet-class>
            <init-param>
                  <param-name>config</param-name>
                  <param-value>WEB-INF/struts-config.xml</param-value>
            </init-param>
            <init-param>
                  <param-name>debug</param-name>
                  <param-value>2</param-value>
            </init-param>
            <init-param>
                  <param-name>detail</param-name>
                  <param-value>2</param-value>
            </init-param>
            <init-param>
                  <param-name>validate</param-name>
                  <param-value>true</param-value>
            </init-param>
            <load-on-startup>2</load-on-startup>
      </servlet>
      <servlet-mapping>
            <servlet-name>action</servlet-name>
            <url-pattern>*.do</url-pattern>
      </servlet-mapping>

The version of struts i am using is 1.1.

the function which I am trying to overwrite in my controller is the process method and here is what I try to do there

i have a input xml which is of the following type

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<header>
<request_type>xyz</request_type>
<channel_id/>
</header>
<payload>
<code>1234</code>
</payload>

now in my controller i use JDOM to parse this xml and retrieve the request_type field. This is nothing but the name of the action which I need to take. Now how can i map this to my definition in the struts-config.xml

<action-mappings>
<action>
path="/xyz"
type="com.ashwin.xyzAction"
<forward name="success" path="/response.jsp">
</action>
</action-mappings>

THe main problem which I have is how can I forward the requests to the action definitions I have in my struts-config file. let me know if you need more information
 
0
petmagdyCommented:
u didn't post the complete code of the function u overwrite struts default behaviour in ur controller servlet
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

AshwinAuthor Commented:
import org.apache.struts.action.ActionServlet;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.config.ActionConfig;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.RequestProcessor;
import org.apache.struts.actions.ForwardAction;

import javax.servlet.ServletInputStream;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;

import java.io.ByteArrayInputStream;
import java.io.PrintWriter;
import java.util.List;
import java.util.Iterator;

public class Controller extends ActionServlet {

      /**
       * method to process the input and determine the action to take
       */
      protected void process(javax.servlet.http.HttpServletRequest request,
                                 javax.servlet.http.HttpServletResponse response)
                        throws java.io.IOException,
                                 javax.servlet.ServletException{
                                       
            //retrieve the input
            String inXML = request.getParameter("inXml");
            System.out.println("request XML:- "+inXML);
            
            //domify this xml
            //create the SAXBuilder object
            SAXBuilder saxBuilder = new SAXBuilder();
            Document jdomDocument = new Document();
        
              try{
                    //create the jdom object
                    saxBuilder.setIgnoringElementContentWhitespace(true);
                    //build the stream and pass this stream to jdomDocument
                    ByteArrayInputStream stream = new ByteArrayInputStream(inXML.getBytes());
                          jdomDocument = saxBuilder.build(stream);
                    
                    //identify the request type
                    //find the request type field from the input xml
                  XPath path = XPath.newInstance("Request_Type");
                  List list = path.selectNodes(jdomDocument.getRootElement());
                  Iterator it = list.listIterator();
                  Element e = jdomDocument.getRootElement();
                  while (it.hasNext()) {
                        e = (Element) it.next();
                  }
                  String requestType = e.getText();
                  
                  System.out.println("Request Type:- "+ requestType);
                  
      /*            ModuleConfig modConfig = this.getModuleConfig(request);
                  ActionConfig aConf = modConfig.findActionConfig("/"+requestType);
                  
                  
                  ActionMapping map = new ActionMapping();
                  map.setForward(aConf.getName());
                  ForwardAction fAction = new ForwardAction();
                  ActionForward forward = fAction.execute(map,(ActionForm)null,request,response);
      */
                  request.getRequestDispatcher("/"+requestType).forward(request,response);
                  System.out.println(request.getServletPath());            
                        
            }
              catch(JDOMException je){
                    je.printStackTrace();
              }
              catch(Exception e){
                    e.printStackTrace();
              }
        }
}


thats the code I am attempting to write. i am unable to forward my reques to my action classess. how can i doi that
0
petmagdyCommented:
Ashwin,

What was ur need to overwrite this function? Why did u parsed the struts config ur self?
0
AshwinAuthor Commented:
the need is this from the input xml which i get I will have to determine the request type from the xml and take appropriate action. this is because my design is such that this system will be called by another application and not a browser. It can also be a browser..

0
petmagdyCommented:
and how will the other application intends to call u?
0
AshwinAuthor Commented:
its a call to the servlet and pass the xml request. we might extend this for a web support also,
0
petmagdyCommented:
why don't ur other application calls the normal struts action normally like this:

1-suppose u used the default Struts ActionServlet and in ur strutsConfig:

  <action
                 path = "/xyz"
                type="com.infosys.vru.actions.LoginAction">
     </action>

2- and then the other application will just call:

URL url = new URL("http://host/myapp/xyz.do?caller=Otherapplication");
0
AshwinAuthor Commented:
no i want to use struts as there is a lot flexibility. I dont want my application and the web-enabled services to access it differently. there should be only one entry point.
0
petmagdyCommented:
and here is another way to do this
1- in ur strutsconfig do something like this:
  <action
                 path = "/web/xyz"
                type="com.infosys.vru.actions.LoginAction">
     </action>
 <action
                 path = "/otherapplication/xyz"
                type="com.infosys.vru.actions.LoginAction">
     </action>

2- from ur broweser u will call like this:

http://host/myapp/web/xyz.do

3- from ur other application do:

URL url = new URL("http://host/myapp/otherapplication/xyz.do");
 // Connect

4- in ur action class LoginAction will recieve the both requests and u can even if u want deffereniate between both caller with something like this:

    public ActionForward execute(
        ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response)
        throws Exception
        {

            String l_szPath = mapping.getPath();

            if( l_szPath.equals( "/web/xyz" ) )
            {
                    //do for web client                  
            }
            else if( l_szPath.equals( "/otherapplication/xyz" ) )
            {
                  // do for other application
            }
}
0
petmagdyCommented:
>>no i want to use struts as there is a lot flexibility
and what i were using in my comment?? The answer I was using Struts

>> I dont want my application and the web-enabled services to access it differently
if the action respond in the same way for Web and Other application then you will invoke ur action in the same way

>>there should be only one entry point
Default Struts ActionServlet already do that, why do u want to overwrite it??
0
AshwinAuthor Commented:
xyz is not the only action which I have to call, I need to change the action based on the request_type field specided in my xml. thats the main reason I am extending the servlet. any way you know I can call the right action method from the request type
0
petmagdyCommented:
ok finally I got U

U r overwriting the wrong Class, u shouldn't overwride Action Servlet, u should overwrite org.apache.struts.action.RequestProcessor
1- u r going to Create a class for Example MyRequestProcessor

2- in ur struts config put this line:

    <controller processorClass="MyPackage.MyRequestProcessor" />

3- in MyRequestProcessor u will extend RequestProcessor and overwrite the method processMapping(...) like this:

    protected ActionMapping processMapping(HttpServletRequest request,
                                           HttpServletResponse response,
                                           String path)  throws IOException
    {
          ActionMapping defaultMapping = super.processMapping( request,     respopath);
         // Parse ur input xml and get the PAth for example /xyz
          defaultMapping.setPath("/xyz");
          return defaultMapping;
   }
0
petmagdyCommented:
just miss tepo correction:

>>          ActionMapping defaultMapping = super.processMapping( request,     respopath);
i mean:

          ActionMapping defaultMapping = super.processMapping( request,     response, path);
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java EE

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.