2012-10-31

JAVA] RSS Reader 만들기


** java]Http 통신 의 예제 파일 참조

javascript를 이용한 초간단 Rss Reader 구현하기 : javascript 를 이용한 초간단 Rss Reader 구현하기
참조사이트 : http://blog.naver.com/sullim75?Redirect=Log&logNo=140028752352


춣처 : http://poolpiri.egloos.com/7021118


간단한 Rss Reader 만들기...


블로그를 만들어보다가 Rss를 읽어서 웹상에서 보여주는 RssReader가 필요할꺼 같아서...
간단하게 만들어봅니다.
자카르타 오픈 컴포넌트중에 하나인 commons.digester를 이용한겁니다...그래서 간단허져...
일단 아래와 같이 간단한 메서드를 만들어봅니다.
/**
* RSSDigester를 이용해서 링크의 스트림(xml)을 파싱해서 Channel객체를 리턴한다.
*
* @param xmlLink
* @param response
* @return org.apache.commons.digester.rss.Channel
* @throws Exception
*/


private Channel getChannel(String xmlLink)
      throws Exception {
    Channel chan = null;
    try {
       RSSDigester digester = new RSSDigester();
      // 방법 1. Rss Link를 이용한 파싱...
       //chan = (Channel) digester.parse(xmlLink);
       // 방법 2. Rss Link를 URL로 연결해서 얻은 스트림으로 파싱...
       //chan = (Channel) digester.parse(new URL(xmlLink).openStream());
       // 방법 3. 국내 사이트 Character Encoding문제 때문에...추가...

       chan = (Channel) digester.parse(getEncodedReader(xmlLink));
    } catch (java.io.IOException ioe) {
       chan = new Channel();
       chan.setTitle("ERROR");
       StringBuffer sb = new StringBuffer("<span class="error">");
       sb.append("IOException parsing RSS XML LINK : " + xmlLink);
       sb.append("</span>n<p>");
       sb.append(ioe.toString());
       chan.setDescription(sb.toString());
    } catch (org.xml.sax.SAXException se) {
       chan = new Channel();
       chan.setTitle("ERROR");
       StringBuffer sb = new StringBuffer("<span class="error">");
       sb.append("SAXException parsing RSS XML LINK : " + xmlLink);
       sb.append("</span>n<p>");
       sb.append(se.toString());
       chan.setDescription(sb.toString());
    }
return chan;
}
파라미터로 와야하는 String xmlLink은 본 엠파스 블로그에 있는거같은 RSS링크 유알엘을 넣어주심 됩니다. 제 블로그를 예를 들면..."http://blog.empas.com/poolpiri3/rss.xml" 이게 들어오면 되는겁니다.
여기 예제는 엠파스에서 제공하는 rss.2.0 버전에만 잘돌아갑니당...이 버전은 웬만한 국내 RSS가 지원하는 버전입니다...

소스 중간에 있는 주석을 보시면 몇가지 방법이 있습니다만...국내 사이트의 경우 한글 인코딩 문제로 파싱이 제대로 안됩니다. 여기 엠파스도 마찬가지구여... 이럴줄 알았으면 굳이 digester를 쓰지 않고 방법을 생각했으면 더 쉬워질 수 도 있었습니다만...제가 무지한지라...하여 아래와 같은 메서드를 무식하게 추가했습니다.
/**
* xml파일의 encoding타입을 읽어서 그 타입대로 컨버전후 InputStreamReader를 리턴한다.
*
* @param xmlLink
* @return InputStreamReader
*/


private InputStreamReader getEncodedReader(String xmlLink) {
   URL url = null;
    InputStreamReader reader = null;
    BufferedReader br = null;
    try {
       url = new URL(xmlLink);
       reader = new InputStreamReader(url.openStream());
       byte b[] = new byte[1024];
       br = new BufferedReader(reader);
       String line = br.readLine();
       while (line != null) {
          if (!(line.trim().equals(""))) {
             int index = line.toLowerCase().indexOf("encoding");
             String prefix = """;
             String encoding = "";
             if (index != -1) {
                int start = line.indexOf(prefix, index) + 1;
                if (start == -1) {
                   prefix = "'";
                   start = line.indexOf(prefix, index) + 1;
                   if (start == -1) {
                     start = line.indexOf("=", index) + 1;
                     prefix = "?";
                   }
                }
             encoding = line.substring(start, line.indexOf(prefix, start));
             if (encoding != null && !("".equals(encoding))) {
                reader =  new InputStreamReader( url.openStream(),  encoding.trim());
             } else {
                reader = new InputStreamReader(url.openStream());
             }
       } else {
          reader = new InputStreamReader(url.openStream());
       }
    break;
   }
   line = br.readLine();
   }
   } catch (MalformedURLException e) {
       e.printStackTrace();
    } catch (IOException e) {
       e.printStackTrace();
    } finally {
       if (br != null) {
          try {
             br.close();
          } catch (IOException e1) {
             e1.printStackTrace();
          }
       }
    }
    return reader;
}
하여튼 이렇게 얻어진 channel를 객체를 통해서 아래와 같이 jsp에서 뿌려주심 됩니다.
<% int maxItems = 10;
if (channel != null) {
if ("ERROR".equals(channel.getTitle())) {%>

<tr bgcolor="#FFCCFF">
<td width="100" bgcolor="#CCCCFF">블로그 이름</td>
<td bgcolor="#CCFFCC"><%=channel.getDescription()%></td>
</tr>
<%return;
}%>
<% String divId = Utility.replace(channel.getTitle(), " ", "_");
divId = Utility.replace(channel.getTitle(), "'", "_");%>
<!--<%=channel.getLastBuildDate()%><%=channel.getCopyright()%><%=channel.getDocs()%><%=channel.getLanguage()%>-->

<tr bgcolor="#FFCCFF">
<td bgcolor="#CCFFCC" width="500" colspan="2" valign="bottom"><a href="<%=channel.getLink()%>" target="_blank"><h3><%=channel.getTitle()%></h3></a><br>
<%=channel.getDescription()%></td>
</tr>
<% Image image = channel.getImage();
if (image != null) {%>
<tr bgcolor="#FFFFFF">
<td colspan="2" height="50"><img src="<%=image.getURL()%>" alt="<%=image.getTitle()%>" > <!--width="<%=image.getWidth()%>" height="<%=image.getHeight()%>"-->
</td>
</tr>
<% }
Item[] items = channel.getItems();
for (int j = 0; j < items.length; j++) {
if (items[j].getTitle() != null && items[j].getLink() != null) {%>
<tr bgcolor="#FFFFFF">
<td colspan="2"><a href="<%=items[j].getLink()%>" target="_blank" class="RssLink"><%=items[j].getTitle()%></a></td>
</tr>
<% } else if (items[j].getTitle() != null) {%><tr bgcolor="#FFFFFF">
<td colspan="2"><div class="RssTitle"><%=items[j].getTitle()%></div></td>
</tr>
<% }
if (items[j].getDescription() != null) {%>
<tr bgcolor="#FFFFFF">
<td colspan="2"><div class="RssDesc"><%=items[j].getDescription()%>...</div></td>
</tr>
<% }
if (maxItems != -1 && j >= maxItems)
break;
}
} else {%>
<tr bgcolor="#FFFFFF">
<td colspan="2">블로그 리스트가 하나도 없습니다. -_-</td>
</tr>
<% }%>
흠흠...제가 봐도 어설프네여...
이렇게 하면 자기 홈페이지나 특정사이트에 기존에 IFRAME같은 방법으로 넣어줬던 다른 사이트의 특정 게시물 리스트를 RSS와 RSS Reader를 통해서 출력해줄 수 있습니다.
물론 항상 신규 리스트겠죠 또한 해당 사이트에서 RSS를 지원해야만 가능한거구여...요샌 상당수 사이트들이 지원을 하구여...
그럼...
위의 소스는 commons.digester 1.5/1.6 을 기준으로 작성 되어서 2.x에서는 RSSDigester()를 찾을 수 없었다...(2010.07.06 기준)
그래서 아래의 소스로 rss reader를 구현하게 되었다...



RssReader.java
=================================

package rss;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Scanner;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class RssReader {

    private static RssReader instance = null;
    private static String ENCODING = "UTF-8";
    static String NL = System.getProperty("line.separator");
  
    private RssReader() {
    }
  
    public static RssReader getInstance() {
        if(instance == null) {
            instance = new RssReader();  
        }
        return instance;
    }
  
    public void writeNews() {
        try {

            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
//            URL u = new URL("http://mutasyon.net/cs/blogs/hakkiocal/rss.aspx");
//            URL u = new URL("http://rss.joins.com/joins_news_list.xml");
//            URL u = new URL("http://feeds.feedburner.com/afriken");
            URL u = new URL("http://blog.rss.naver.com/jeffyang.xml");
          
            Document doc = builder.parse(u.openStream());
          
            NodeList nodes = doc.getElementsByTagName("item");
            NodeList nodeChannel = doc.getElementsByTagName("channel");
          
            for(int i=0;i<nodes.getLength();i++) {
              
                Element element = (Element)nodes.item(i);
              
                System.out.println("Title: " + getElementValue(element,"title"));
                System.out.println("Category: " + getElementValue(element,"category"));
                System.out.println("Link: " + getElementValue(element,"link"));
                System.out.println("Publish Date: " + getElementValue(element,"pubDate"));
                System.out.println("author: " + getElementValue(element,"author"));
                System.out.println("comment: " + getElementValue(element,"comments"));
                System.out.println("guid: " + getElementValue(element,"guid"));
                System.out.println("language: " + getElementValue(element,"language"));
                System.out.println("description: " + getElementValue(element,"description"));
                System.out.println();
            }//for          
        }//try
        catch(Exception ex) {
        ex.printStackTrace();  
        }
      
    }
  
    public void writeNews(String url) {
        try {
          
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

            URL u = new URL(url);
          
            Document doc = builder.parse(u.openStream());
          
            NodeList nodes = doc.getElementsByTagName("item");
          
            for(int i=0;i<nodes.getLength();i++) {
              
                Element element = (Element)nodes.item(i);
              
                System.out.println("Title: " + getElementValue(element,"title"));
                System.out.println("Category: " + getElementValue(element,"category"));
                System.out.println("Link: " + getElementValue(element,"link"));
                System.out.println("Publish Date: " + getElementValue(element,"pubDate"));
                System.out.println("author: " + getElementValue(element,"author"));
                System.out.println("comment: " + getElementValue(element,"comments"));
                System.out.println("guid: " + getElementValue(element,"guid"));
                System.out.println("language: " + getElementValue(element,"language"));
                System.out.println("description: " + getElementValue(element,"description"));
                System.out.println();
            }//for          
        }//try
        catch(Exception ex) {
            ex.printStackTrace();  
        }
      
    }
      
      
    private String getCharacterDataFromElement(Element e) {
        try {
            Node child = e.getFirstChild();
            if(child instanceof CharacterData) {
                CharacterData cd = (CharacterData) child;
                return cd.getData();
            }
        }
        catch(Exception ex) {
          
        }
        return "";          
    } //private String getCharacterDataFromElement
  
    protected float getFloat(String value) {
        if(value != null && !value.equals("")) {
            return Float.parseFloat(value);  
        }
        return 0;
    }
  
    protected String getElementValue(Element parent,String label) {
        return getCharacterDataFromElement((Element)parent.getElementsByTagName(label).item(0));  
    }
  
    /**
     * 파일 읽기
     * @param ctx
     * @param fileName
     * @return
     * @throws FileNotFoundException
     */
    public static StringBuffer readFile(String fileName, String fEncoding) throws FileNotFoundException {
        StringBuffer result = new StringBuffer();
//        Scanner scanner = new Scanner(new File(fileName), fEncoding);
        try {
            BufferedReader in = new BufferedReader(new FileReader(fileName));
            try {
                String line = null;
              
                while ((line=in.readLine()) != null) {
                    result.append(line+NL);
                }
            } finally {
                in.close();
            }
//            while (scanner.hasNextLine()) {
//                result.append(scanner.nextLine()+NL);
//            }
        }catch(IOException ex ) {
            ex.printStackTrace();
        }
      
        return result;
    }
  
    public static StringBuffer readFileScanner(String fileName, String fEncoding) throws FileNotFoundException {
        StringBuffer result = new StringBuffer();
        Scanner scanner = new Scanner(new File(fileName), fEncoding);
        try {
            while (scanner.hasNextLine()) {
                result.append(scanner.nextLine()+NL);
            }
        } finally {
                scanner.close();
        }
      
        return result;
    }
  
    public static void main(String[] args) {
        try {
//            StringBuffer strUrl = readFile(args[0],  ENCODING);
            StringBuffer strUrl = readFileScanner(args[0],  ENCODING);
            if(strUrl != null ){
                String[] urls = strUrl.toString().split(NL);
                for(int i=0; i < urls.length;i++) {
                    RssReader reader = RssReader.getInstance();
                    reader.writeNews(urls[i]);  
                }
            }

            RssReader reader = RssReader.getInstance();
            reader.writeNews();  
                      
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
//            e.printStackTrace();
            System.out.println("지정된 파일을 찾을 수 없습니다. 파일을 확인하시기 바랍니다.");
        }

    }
}

댓글 없음:

댓글 쓰기