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.ac tion.Actio nMapping">
<action
path = "/xyz"
type="com.infosys.vru.acti ons.LoginA ction">
</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-c lass>
########## 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(reque st);
ActionConfig aConf = modConfig.findActionConfig ("/"+reque stType);
AtionMapping map = new ActionMapping();
map.setForward(aConf.getNa me());
ForwardAction fAction = new ForwardAction();
ActionForward forward = fAction.execute(map,(Actio nForm)null ,request,r esponse);
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.we bapp.WebAp pErrorRepo rt: No context-relative URI specified via the 'parameter' attribute
at com.ibm.ws.webcontainer.sr t.SRTServl etResponse Context.se ndError(SR TServletRe sponseCont ext.java:1 52)
at com.ibm.ws.webcontainer.sr t.SRTServl etResponse .sendError (SRTServle tResponse. java:626)
at org.apache.struts.actions. ForwardAct ion.execut e(ForwardA ction.java :143)
at Controller.process(Control ler.java:8 2)
at org.apache.struts.action.A ctionServl et.doPost( ActionServ let.java:5 25)
at javax.servlet.http.HttpSer vlet.servi ce(HttpSer vlet.java: 760)
at javax.servlet.http.HttpSer vlet.servi ce(HttpSer vlet.java: 853)
at com.ibm.ws.webcontainer.se rvlet.Stri ctServletI nstance.do Service(St rictServle tInstance. java:110)
at com.ibm.ws.webcontainer.se rvlet.Stri ctLifecycl eServlet._ service(St rictLifecy cleServlet .java:174)
at com.ibm.ws.webcontainer.se rvlet.Idle ServletSta te.service (StrictLif ecycleServ let.java:3 13)
at com.ibm.ws.webcontainer.se rvlet.Stri ctLifecycl eServlet.s ervice(Str ictLifecyc leServlet. java:116)
at com.ibm.ws.webcontainer.se rvlet.Serv letInstanc e.service( ServletIns tance.java :283)
at com.ibm.ws.webcontainer.se rvlet.Vali dServletRe ferenceSta te.dispatc h(ValidSer vletRefere nceState.j ava:42)
at com.ibm.ws.webcontainer.se rvlet.Serv letInstanc eReference .dispatch( ServletIns tanceRefer ence.java: 40)
at com.ibm.ws.webcontainer.we bapp.WebAp pRequestDi spatcher.h andleWebAp pDispatch( WebAppRequ estDispatc her.java:9 48)
at com.ibm.ws.webcontainer.we bapp.WebAp pRequestDi spatcher.d ispatch(We bAppReques tDispatche r.java:530 )
at com.ibm.ws.webcontainer.we bapp.WebAp pRequestDi spatcher.f orward(Web AppRequest Dispatcher .java:176)
at com.ibm.ws.webcontainer.sr t.WebAppIn voker.doFo rward(WebA ppInvoker. java:79)
at com.ibm.ws.webcontainer.sr t.WebAppIn voker.hand leInvocati onHook(Web AppInvoker .java:201)
at com.ibm.ws.webcontainer.ca che.invoca tion.Cache dInvocatio n.handleIn vocation(C achedInvoc ation.java :71)
at com.ibm.ws.webcontainer.sr p.ServletR equestProc essor.disp atchByURI( ServletReq uestProces sor.java:1 82)
at com.ibm.ws.webcontainer.os elistener. OSEListene rDispatche r.service( OSEListene r.java:334 )
at com.ibm.ws.webcontainer.ht tp.HttpCon nection.ha ndleReques t(HttpConn ection.jav a:56)
at com.ibm.ws.http.HttpConnec tion.readA ndHandleRe quest(Http Connection .java:610)
at com.ibm.ws.http.HttpConnec tion.run(H ttpConnect ion.java:4 31)
at com.ibm.ws.util.ThreadPool $Worker.ru n(ThreadPo ol.java:59 3)
Thanks,
Ashwin
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.ac
<action
path = "/xyz"
type="com.infosys.vru.acti
</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<
########## 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(reque
ActionConfig aConf = modConfig.findActionConfig
AtionMapping map = new ActionMapping();
map.setForward(aConf.getNa
ForwardAction fAction = new ForwardAction();
ActionForward forward = fAction.execute(map,(Actio
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.we
at com.ibm.ws.webcontainer.sr
at com.ibm.ws.webcontainer.sr
at org.apache.struts.actions.
at Controller.process(Control
at org.apache.struts.action.A
at javax.servlet.http.HttpSer
at javax.servlet.http.HttpSer
at com.ibm.ws.webcontainer.se
at com.ibm.ws.webcontainer.se
at com.ibm.ws.webcontainer.se
at com.ibm.ws.webcontainer.se
at com.ibm.ws.webcontainer.se
at com.ibm.ws.webcontainer.se
at com.ibm.ws.webcontainer.se
at com.ibm.ws.webcontainer.we
at com.ibm.ws.webcontainer.we
at com.ibm.ws.webcontainer.we
at com.ibm.ws.webcontainer.sr
at com.ibm.ws.webcontainer.sr
at com.ibm.ws.webcontainer.ca
at com.ibm.ws.webcontainer.sr
at com.ibm.ws.webcontainer.os
at com.ibm.ws.webcontainer.ht
at com.ibm.ws.http.HttpConnec
at com.ibm.ws.http.HttpConnec
at com.ibm.ws.util.ThreadPool
Thanks,
Ashwin
ASKER
The following is my servlet definition is web.xml:-
<servlet>
<servlet-name>action</serv let-name>
<!-- <servlet-class>org.apache. struts.act ion.Action Servlet</s ervlet-cla ss> -->
<servlet-class>Controller< /servlet-c lass>
<init-param>
<param-name>config</param- name>
<param-value>WEB-INF/strut s-config.x ml</param- value>
</init-param>
<init-param>
<param-name>debug</param-n ame>
<param-value>2</param-valu e>
</init-param>
<init-param>
<param-name>detail</param- name>
<param-value>2</param-valu e>
</init-param>
<init-param>
<param-name>validate</para m-name>
<param-value>true</param-v alue>
</init-param>
<load-on-startup>2</load-o n-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</serv let-name>
<url-pattern>*.do</url-pat tern>
</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
<servlet>
<servlet-name>action</serv
<!-- <servlet-class>org.apache.
<servlet-class>Controller<
<init-param>
<param-name>config</param-
<param-value>WEB-INF/strut
</init-param>
<init-param>
<param-name>debug</param-n
<param-value>2</param-valu
</init-param>
<init-param>
<param-name>detail</param-
<param-value>2</param-valu
</init-param>
<init-param>
<param-name>validate</para
<param-value>true</param-v
</init-param>
<load-on-startup>2</load-o
</servlet>
<servlet-mapping>
<servlet-name>action</serv
<url-pattern>*.do</url-pat
</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
<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
ASKER
import org.apache.struts.action.A ctionServl et;
import org.apache.struts.config.M oduleConfi g;
import org.apache.struts.config.A ctionConfi g;
import org.apache.struts.action.A ctionForm;
import org.apache.struts.action.A ctionMappi ng;
import org.apache.struts.action.A ctionForwa rd;
import org.apache.struts.action.R equestProc essor;
import org.apache.struts.actions. ForwardAct ion;
import javax.servlet.ServletInput Stream;
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.ByteArrayInputStre am;
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 .HttpServl etRequest request,
javax.servlet.http.HttpSer vletRespon se response)
throws java.io.IOException,
javax.servlet.ServletExcep tion{
//retrieve the input
String inXML = request.getParameter("inXm l");
System.out.println("reques t XML:- "+inXML);
//domify this xml
//create the SAXBuilder object
SAXBuilder saxBuilder = new SAXBuilder();
Document jdomDocument = new Document();
try{
//create the jdom object
saxBuilder.setIgnoringElem entContent Whitespace (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(jdomDocum ent.getRoo tElement() );
Iterator it = list.listIterator();
Element e = jdomDocument.getRootElemen t();
while (it.hasNext()) {
e = (Element) it.next();
}
String requestType = e.getText();
System.out.println("Reques t Type:- "+ requestType);
/* ModuleConfig modConfig = this.getModuleConfig(reque st);
ActionConfig aConf = modConfig.findActionConfig ("/"+reque stType);
ActionMapping map = new ActionMapping();
map.setForward(aConf.getNa me());
ForwardAction fAction = new ForwardAction();
ActionForward forward = fAction.execute(map,(Actio nForm)null ,request,r esponse);
*/
request.getRequestDispatch er("/"+req uestType). forward(re quest,resp onse);
System.out.println(request .getServle tPath());
}
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
import org.apache.struts.config.M
import org.apache.struts.config.A
import org.apache.struts.action.A
import org.apache.struts.action.A
import org.apache.struts.action.A
import org.apache.struts.action.R
import org.apache.struts.actions.
import javax.servlet.ServletInput
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.ByteArrayInputStre
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
javax.servlet.http.HttpSer
throws java.io.IOException,
javax.servlet.ServletExcep
//retrieve the input
String inXML = request.getParameter("inXm
System.out.println("reques
//domify this xml
//create the SAXBuilder object
SAXBuilder saxBuilder = new SAXBuilder();
Document jdomDocument = new Document();
try{
//create the jdom object
saxBuilder.setIgnoringElem
//build the stream and pass this stream to jdomDocument
ByteArrayInputStream stream = new ByteArrayInputStream(inXML
jdomDocument = saxBuilder.build(stream);
//identify the request type
//find the request type field from the input xml
XPath path = XPath.newInstance("Request
List list = path.selectNodes(jdomDocum
Iterator it = list.listIterator();
Element e = jdomDocument.getRootElemen
while (it.hasNext()) {
e = (Element) it.next();
}
String requestType = e.getText();
System.out.println("Reques
/* ModuleConfig modConfig = this.getModuleConfig(reque
ActionConfig aConf = modConfig.findActionConfig
ActionMapping map = new ActionMapping();
map.setForward(aConf.getNa
ForwardAction fAction = new ForwardAction();
ActionForward forward = fAction.execute(map,(Actio
*/
request.getRequestDispatch
System.out.println(request
}
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?
What was ur need to overwrite this function? Why did u parsed the struts config ur self?
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?
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.acti ons.LoginA ction">
</action>
2- and then the other application will just call:
URL url = new URL("http://host/myapp/xyz.do?caller=Otherapplication");
1-suppose u used the default Struts ActionServlet and in ur strutsConfig:
<action
path = "/xyz"
type="com.infosys.vru.acti
</action>
2- and then the other application will just call:
URL url = new URL("http://host/myapp/xyz.do?caller=Otherapplication");
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.acti ons.LoginA ction">
</action>
<action
path = "/otherapplication/xyz"
type="com.infosys.vru.acti ons.LoginA ction">
</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
}
}
1- in ur strutsconfig do something like this:
<action
path = "/web/xyz"
type="com.infosys.vru.acti
</action>
<action
path = "/otherapplication/xyz"
type="com.infosys.vru.acti
</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??
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??
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.R equestProc essor
1- u r going to Create a class for Example MyRequestProcessor
2- in ur struts config put this line:
<controller processorClass="MyPackage. MyRequestP rocessor" />
3- in MyRequestProcessor u will extend RequestProcessor and overwrite the method processMapping(...) like this:
protected ActionMapping processMapping(HttpServlet Request 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("/x yz");
return defaultMapping;
}
U r overwriting the wrong Class, u shouldn't overwride Action Servlet, u should overwrite org.apache.struts.action.R
1- u r going to Create a class for Example MyRequestProcessor
2- in ur struts config put this line:
<controller processorClass="MyPackage.
3- in MyRequestProcessor u will extend RequestProcessor and overwrite the method processMapping(...) like this:
protected ActionMapping processMapping(HttpServlet
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("/x
return defaultMapping;
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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