google-app-enginewidgetrssrome

How to make rss feed into the java webapp on GAE?


I have prepared the servlet according to https://rometools.github.io/rome/ROMEReleases/ROME0.4Beta/RomeV0.4Tutorials/RomeV0.4TutorialUsingRomeWithinAServletToCreateAndReturnAFeed.html example. However, the rss is not validated on https://validator.w3.org/feed/check.cgi being created from scratch (and thus the feed not validated, for example, in Yandex widget policy), it misses the element in the channel tag.

There are several tips like Atom:link in RSS using Rome how to enable the atom:link, but they are based on rome.properties and it is impossible to use them on GAE - property file is not loaded to the webapp's classpath. So that is the easiest way to make atom:link to work?


Solution

  • It was realized, that the missed element can be added to the xml right in the servlet, so additional Module class for Rome are not needed for this particular purpose:

    public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
        try {
            SyndFeed feed = getFeed(req, dataEntries, streamGauge);
    
            String feedType = req.getParameter(FEED_TYPE);
            feedType = (feedType != null) ? feedType : _defaultFeedType;
            feed.setFeedType(feedType);
            res.setContentType(MIME_TYPE);
            SyndFeedOutput output = new SyndFeedOutput();
    
            Writer writer = new StringWriter();
            output.output(feed, writer);
    
            SAXBuilder db = null;
            Document doc = null;
            db = new SAXBuilder();
            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(writer.toString()));
            try {
                doc = db.build(is);
            } catch (JDOMException e) {
                e.printStackTrace();
            }
    
            Element root =
                    doc.getRootElement();
    
            Element channel = root.getChild("channel");
    
            FeedServlet.AtomNSModule atomNSModule = (FeedServlet.AtomNSModule) module;
            root.addNamespaceDeclaration(ATOM_NS);
    
            Element atomLink = new Element("link", ATOM_NS);
            atomNSModule.setLink("http://volgalevel.appspot.com/feed");
            atomLink.setAttribute("href", atomNSModule.getLink());
            atomLink.setAttribute("rel", "self");
            atomLink.setAttribute("type", "application/rss+xml");
    
            channel.addContent(0, atomLink);
            XMLOutputter outputter = new XMLOutputter();
            outputter.output(doc, res.getWriter());
        } catch (FeedException ex) {
            String msg = COULD_NOT_GENERATE_FEED_ERROR;
            log(msg, ex);
            res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg);
        }
    }
    

    note the imports:

    import org.jdom2.Element;
    import org.jdom2.Namespace;
    import org.jdom2.Document;
    import org.jdom2.*;
    import org.jdom2.input.SAXBuilder;
    import org.jdom2.output.XMLOutputter;
    import org.xml.sax.InputSource;
    import org.xml.sax.SAXException;
    

    actually a working GAE Servlet for RSS can be reached there: https://github.com/Eljah/volgalevel/blob/master/src/main/java/com/appspot/FeedServlet.java

    it also fixes duplicated pubDate problem