Hi Bill,
Looking at your web.xml excerpt, there seems to be one
error. Instead of this:
<context-param>
<param-name>org.restlet.target.init.contextPath</param-name>
<param-value>/clientholding</param-value>
</context-param>
First, you should really replace "/clientholding" with an
initialization parameter *name* ("contextPath" suggested). The actual value with
be dynamically set at run-time by the
ServerServlet.
The problem when you use Restlets within a Servlet
container is that we don't have full control on the URI delegation. Part of this
URI delegation is done at the Servlet container level and the rest inside the
Restlet container.
You ServerServlet will typically be deployed within Tomcat
as a J2EE Web Application and given a specific URI name (it seems to be
"clientholding" in you case).
As we want to keep the portability of a Restlet application
from the emmbedded mode (Tomcat) to the standalone mode (Jetty or Simple), we
thought about a way to dynamically pass the URI part that was already handled by
the Tomcat engine. We called this the context path, which is equivalent
to:
ServletContextPath = result of
servletRequest.getContextPath()
ServletPath = result of servletRequest.getServletPath()
From within your RestletContainer subclass, you can
retrieve this context path using this code:
getInitParameters().get("contextPath")
Just replace "contextPath" with the parameter name
configured in your web.xml file under the "org.restlet.target.init.contextPath" Servlet context parameter.
Now that you have your Restlet context path in hand, you
can use it to attach your top Restlet (or Maplet or Chainlet) to your
target Restlet (or RestletContainer). If your target Restlet is a subclass of
RestletContainer, you will typically do something like this in you
constructor:
attach(contextPath,
myTopRestlet);
Starting from the myTopRestlet, the coding is strictly
similar to standalone Restlet applications.
---
Concerning your Question #2, the "delegateMaplet" or
"delegate" properties, they are automatically instantiated by the
RestletContainer or DefaultMaplet constructors and you shouldn't have to worry
about them or even directly rely on them.
I apologize for the lack of documentation on this
Servlet integration mode. I've just added parts of this answer to the
ServerServlet Javadocs for the next release. We would also benefit from a
specific tutorial...
Best,
Jerome
De : Morone, Bill
[mailto:Morone.Bill <at> pennmutual.com]
Envoyé : mardi 6 juin 2006
01:10
À : discuss <at> restlet.tigris.org
Objet :
Having a difficult time deploying RootContainer on Apache
Gentlemen:
I am having a bit of difficulty getting a test
client I have written to out my call output.
I have had various problems -- probably as a result of not setting up
my root container up properly or something, maybe you can help.
I've been a little bit crazed trying all kinds of
things going and now I am at the very end of my impl and I am having problems
setting up the Connector to actually "serve" the HTML.
I am using revision 10 andTomcat 5.5.
Here is my web.xml(just servlet mapping):
...
<display-name>Server Servlet</display-name>
<description>Servlet acting as a Restlet server
connector</description>
<!-- Parameter indicating
the target Restlet that will handle the call -->
<context-param>
<param-name>org.restlet.target.class</param-name>
<param-value>com.pennmutual.shared.webservices.clientholding.rest.RootContainer</param-value>
</context-param>
<!-- Parameter indicating
the Servlet attribute to use to store the target Restlet reference
-->
<context-param>
<param-name>org.restlet.target.attribute</param-name>
<param-value>org.restlet.target</param-value>
</context-param>
<!-- Parameter indicating
the name of an initialization parameter that should be set with the
ServerServlet context path -->
<context-param>
<param-name>org.restlet.target.init.contextPath</param-name>
<param-value>/clientholding</param-value>
</context-param>
<!-- Definition of the
ServerServlet class or a subclass -->
<servlet>
<servlet-name>ServerServlet</servlet-name>
<servlet-class>com.noelios.restlet.ext.servlet.ServerServlet</servlet-class>
</servlet>
<!-- Mapping of requests to the ServerServlet -->
<servlet-mapping>
<servlet-name>ServerServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
...
Here is my RootContainer no-args Const(where I set
up the Map, etc.):
public RootContainer()
{
super("The
Client Holding Restlet Container");
// 1. First
attach the permissions Chainlet -- if
// permissionsare not met -- it will return a
// standard error XML
PermissionChainlet permissionChainlet
= new
PermissionChainlet(this);
this.attach(permissionChainlet);
// 2. Then
attach the host maplet which will handle all
// the uri translations
Maplet
rootMaplet = new HostMaplet(this, 8080);
//
this.attach(rootMaplet);
permissionChainlet.attach(rootMaplet);
//=========================================
// thought this was resolved
by ServerServlet config param but it is not so, I guess
DefaultMaplet
bogusRestlet = new DefaultMaplet(this);
// attach
the accountList below the root
rootMaplet.attach("/clientholding", bogusRestlet);
//========================================================
// account list
DefaultMaplet
accountListRestlet = new AccountListRestlet(this);
// attach
the accountList below the root
bogusRestlet.attach("/policy", accountListRestlet);
I am trying to get to ".../policy" with this test
method:
public void testServiceWithURI()
{
try
{
// Prepare the REST
call.
Call call = new
DefaultCall();
// Identify
oursevles.
call.setReferrerRef("http://www.pml.com/");
// Target
resource.
call.setResourceRef("http://127.0.0.1:8080/clientholding/policy");
call.setMethod(Methods.GET);
// Prepare HTTP client
connector.
Client
client = new DefaultClient(Protocols.HTTP, "tester");
// Make the
call.
client.handle(call);
if(call.getStatus().isSuccess())
{
//
Output the result representation on the JVM console
Representation output = call.getOutput();
output.write(System.out);
System.out.println("client: success!");
}
else
{
System.out.println("client: failure!");
System.out.println(call.getStatus().getDescription());
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
I am always failing!!!!!
Question #1 (stuff I kinda worked around) -- It
seemed like when i do delegate(arg0) from the RootContainer.handle() nothing
worked. I had to call super.handle(). Also, to get the "engine" to select my
maplet I had to create a BaseMaplet and do this, handling specific business
logic in the _handle() of the children:
if( ( resourcePath.equals(BaseMaplet.EMPTY_STRING))
)
o = _handle(arg0);
-- using this system I was able to address the
correct "child" maplet but I then I could not output correctly.
so, I attempted to output directly from
RootContainer using this:
StringBuffer sb = new StringBuffer("Testing the
server functionality");
arg0.setOutput(new
StringRepresentation(sb.toString(), MediaTypes.TEXT_PLAIN));
and was successful but I was not able to so moving
the code into my BaseMaplet.
Question #2 -- It seems like in my
RootContainer the delegateMaplet is always null -- I guess this might be one
of my problems -- maybe addressed by my work arounds.
Can you please tell me what I need to do to fix
this? I'll try anything.
Can I leave what I have done with the Root
Container alone and somehow configure it or the ServerServlet to serve the
xml? Is there a way to set the delegateMaplet -- is that my
problem?
I can really use some advice -- I want to use the
product but am getting in a bit of trouble because I can't get it to work
correctly. I have tried so many variations of what yopu show in your
examples.
Bill Morone
This message, including any attachments, is intended only for the recipient(s)
named above. It may contain confidential and privileged information. If you have
received this communication in error, please notify the sender immediately and
destroy or delete the original message. Also, please be aware that if you are not
the intended recipient, any review, disclosure, copying, distribution or any
action or reliance based on this message is prohibited by law.