Link to home
Start Free TrialLog in
Avatar of Ashwin
Ashwin

asked on

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
Avatar of petmagdy
petmagdy
Flag of Canada image

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
Avatar of Ashwin
Ashwin

ASKER

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
 
u didn't post the complete code of the function u overwrite struts default behaviour in ur controller servlet
Avatar of Ashwin

ASKER

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
Ashwin,

What was ur need to overwrite this function? Why did u parsed the struts config ur self?
Avatar of Ashwin

ASKER

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..

and how will the other application intends to call u?
Avatar of Ashwin

ASKER

its a call to the servlet and pass the xml request. we might extend this for a web support also,
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");
Avatar of Ashwin

ASKER

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.
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
            }
}
>>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??
Avatar of Ashwin

ASKER

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
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;
   }
ASKER CERTIFIED SOLUTION
Avatar of petmagdy
petmagdy
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial