?
Solved

Struts Controller Servlet error

Posted on 2004-11-15
15
Medium Priority
?
1,260 Views
Last Modified: 2013-11-24
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
0
Comment
Question by:Ashwin
  • 9
  • 6
15 Comments
 
LVL 13

Expert Comment

by:petmagdy
ID: 12590746
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
 

Author Comment

by:Ashwin
ID: 12591024
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
 
LVL 13

Expert Comment

by:petmagdy
ID: 12591186
u didn't post the complete code of the function u overwrite struts default behaviour in ur controller servlet
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Ashwin
ID: 12591237
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
 
LVL 13

Expert Comment

by:petmagdy
ID: 12591269
Ashwin,

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

Author Comment

by:Ashwin
ID: 12591421
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
 
LVL 13

Expert Comment

by:petmagdy
ID: 12591470
and how will the other application intends to call u?
0
 

Author Comment

by:Ashwin
ID: 12591615
its a call to the servlet and pass the xml request. we might extend this for a web support also,
0
 
LVL 13

Expert Comment

by:petmagdy
ID: 12591690
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
 

Author Comment

by:Ashwin
ID: 12591947
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
 
LVL 13

Expert Comment

by:petmagdy
ID: 12591976
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
 
LVL 13

Expert Comment

by:petmagdy
ID: 12592052
>>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
 

Author Comment

by:Ashwin
ID: 12592059
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
 
LVL 13

Expert Comment

by:petmagdy
ID: 12592188
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
 
LVL 13

Accepted Solution

by:
petmagdy earned 1500 total points
ID: 12592240
just miss tepo correction:

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

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

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Java contains several comparison operators (e.g., <, <=, >, >=, ==, !=) that allow you to compare primitive values. However, these operators cannot be used to compare the contents of objects. Interface Comparable is used to allow objects of a cl…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.
Suggested Courses
Course of the Month12 days, 19 hours left to enroll

579 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question