Hello.

I'm currently evaluating the Reslet API in order to implement web services for our site. However, I've encountered a frustrating hurdle from the very start. First of all, considering the vast majority of web services output XML, i find it surprising that i can't find ANY examples of the RESTlet api that use anything other than plain text. Perhaps this issue is the reason?

As you can see in the code below, I have made a simple xhtml document using JDom and RESTlets. It's pretty standard. The problem is, even with this simple example, the xml does not validate! There are two errors:

1. the doc type is rendered incorrectly - without a space between the public and system ids - so the xml is not well formed.

2. Somewhere along the path the mysterious <META http-equiv="Content- Type" content="text/html; charset=UTF-8"> got inserted - and it's not properly closed, which results in a mismatched tag parsing error.

Attempting to debug this I've printed out both the jdom Document and printed the elements of the org.w3c.dom.Document and neither has this mysterious meta line, so where does it get inserted? Is it some configuration parameter I've overlooked in Tomcat? A problem with JDom? Or is it a problem within RESTlet itself? The results seem to point to the latter.

Here's the code:


##### /api/RestApplication.java ###########################
package api;

import org.restlet.Application;
import org.restlet.Context;
import org.restlet.Router;
import org.restlet.Restlet;

public class RestApplication extends Application
{
        public RestApplication(Context context)
        {
                super(context);
        }

        @Override
    public synchronized Restlet createRoot()
        {
        Router router = new Router(getContext());
        // Defines only one route
        router.attachDefault(XmlResource.class);
                return router;
    }
}

##### /api/XmlResource.java ###########################

package api;

import org.restlet.Context;
import org.restlet.resource.*;
import org.restlet.data.*;
import org.jdom.Element;
import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.DocType;
import org.jdom.output.DOMOutputter;
import org.jdom.output.XMLOutputter;
import org.jdom.output.Format;
import org.apache.log4j.Logger;
import org.w3c.dom.*;

import java.io.IOException;

public class XmlResource extends Resource
{
        static Logger logger = Logger.getLogger(XmlResource.class);
        public XmlResource(Context context, Request request, Response response)
        {
                super(context, request, response);
                getVariants().add(new Variant(MediaType.APPLICATION_XHTML_XML));
        }

        @Override
    public Representation getRepresentation(Variant variant)
        {
                if 
(variant.getMediaType().equals(MediaType.APPLICATION_XHTML_XML))
                {
                        try
                        {
DomRepresentation rep = new DomRepresentation(MediaType.APPLICATION_XHTML_XML);
                                Element root = new Element("html");

                                Element head = new Element("head");
                                head.addContent(new Element("title").addContent("My 
Title"));
                                root.addContent(head);

                                Element body = new Element("body");
                                body.addContent("My text");
                                root.addContent(body);

                                Document doc = new Document(root);
                                doc.setDocType(new DocType(
                                        "html",
                                        "-//W3C//DTD XHTML 1.0 Strict//EN",
                                        
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";));

                                DOMOutputter out = new DOMOutputter();
                                rep.setDocument(out.output(doc));

                                System.out.println("jdom doc: ");
                                print(doc);

                                System.out.println("w3c doc: ");
                                print(rep.getDocument());

                                return rep;
                        }
                        catch (IOException e)
                        {
                                logger.error(e.getMessage(), e);
                        }
                        catch (JDOMException e)
                        {
                                logger.error(e.getMessage(), e);
                        }
                }
                else
                {
logger.error("Couldn't serve this: "+variant.getMediaType().getDescription());
                }
                return null;
    }

        protected static void print(Document doc)
        {
                try
                {
                        XMLOutputter xout;
                        Format f = Format.getPrettyFormat();
                        f.setEncoding("UTF-8");
                        xout = new XMLOutputter(f);
                        xout.output(doc, System.out);
                }
                catch (IOException e)
                {
                        logger.error(e.getMessage(), e);
                }
        }
        protected static void print(org.w3c.dom.Document doc)
        {
                System.out.println(print(doc.getDocumentElement()));
        }
        protected static String print(org.w3c.dom.Node elem)
        {
                if(elem.hasChildNodes())
                {
                        NodeList children = elem.getChildNodes();
                        StringBuffer result = new StringBuffer();
                        
result.append("<").append(elem.getNodeName()).append(">");
                        for (int i = 0; i < children.getLength(); i++)
                        {
                                Node node = children.item(i);
                                result.append(print(node));
                        }
                        
result.append("</").append(elem.getNodeName()).append(">\n");
                        return result.toString();
                }
                else
                        return elem.getTextContent();
        }
}


##### /WEB-INF/web.xml ###########################

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee";
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd";
           version="2.5">

        <display-name>rest app</display-name>

        <context-param>
                <param-name>org.restlet.application</param-name>
                <param-value>api.RestApplication</param-value>
        </context-param>

        <servlet>
      <servlet-name>RestletServlet</servlet-name>
      <servlet-class>
         com.noelios.restlet.ext.servlet.ServerServlet
      </servlet-class>
   </servlet>

        <servlet-mapping>
      <servlet-name>RestletServlet</servlet-name>
      <url-pattern>/*</url-pattern>
   </servlet-mapping>

</web-app>


##### System.out ###########################

jdom doc:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd ">

<html>
  <head>
    <title>My Title</title>
  </head>
  <body>My text</body>
</html>

w3c doc:
<html><head><title>My Title</title>
</head>
<body>My text</body>
</html>




##### Browser result ###########################

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd ">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>My Title</title>
</head>
<body>My text</body>
</html>

######################################


I'm using Tomcat/6.0.14 for the container and JDom1.1. I tried this with both the 1.08 and 1.1m2 RESTlet releases, and they both give exactly the same result!

Can anyone tell me how to get around this?! It seems like a good api. It would be a shame to be forced to abandon it for such a trivial issue.


--
-Elliot Long

email: [EMAIL PROTECTED]
www: http://www.hypnotoad.co.uk
skype: thehypnotoad





Reply via email to