<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    一路拾遺
    Collect By Finding All The Way ......
    posts - 81,comments - 41,trackbacks - 0

    一、寫在所有之前:
    因為dom4j和jdom在這個問題上處理的方法是一模一樣的,只是一個是SAXBuilder 一個SAXReader,這里以jdom距離,至于dom4j只需要同理替換一下就可以了。
    二、問題發生的情況
    當你用jdom讀取一個有dtd驗證的xml文件,同時你的網絡是不通的情況下。會出現以下錯誤:
    1,代碼如下

    package dom;

    import java.io.File;

    import org.jdom.Document;
    import org.jdom.input.SAXBuilder;

    public class TestJdom {
        
    public static void main(String[] args) {
            File file 
    = new File("./src/dom/aiwf_aiService.xml");
            
    if (file.exists()) {
                SAXBuilder builder 
    = new SAXBuilder();
                
    try {
                    Document doc 
    = builder.build(file);
                    System.out.println(doc);
                }
     catch (Exception e) {
                    e.printStackTrace();
                }

            }
     else {
                System.out.println(
    "can not find xml file:"
                        
    + file.getAbsolutePath());
            }

        }

    }

    2,xml文件

    <?xml version="1.0" encoding="GBK"?>
    <!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.8//EN" "http://www.opensymphony.com/osworkflow/workflow_2_8.dtd">
    <workflow>
                    ...............
    </workflow>


    3,錯誤如下

    java.net.SocketException: Permission denied: connect
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:
    333)
        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:
    195)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:
    182)
        at java.net.Socket.connect(Socket.java:
    507)
        at java.net.Socket.connect(Socket.java:
    457)
        at sun.net.NetworkClient.doConnect(NetworkClient.java:
    157)
        at sun.net.www.http.HttpClient.openServer(HttpClient.java:
    365)
        at sun.net.www.http.HttpClient.openServer(HttpClient.java:
    477)
        at sun.net.www.http.HttpClient.
    <init>(HttpClient.java:214)
        at sun.net.www.http.HttpClient.New(HttpClient.java:
    287)
        at sun.net.www.http.HttpClient.New(HttpClient.java:
    299)
        at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:
    792)
        at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:
    744)
        at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:
    669)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:
    913)
        at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:
    973)
        at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:
    905)
        at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(XMLEntityManager.java:
    872)
        at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(XMLDTDScannerImpl.java:
    282)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDispatcher.dispatch(XMLDocumentScannerImpl.java:
    1021)
        at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:
    368)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:
    834)
        at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:
    764)
        at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:
    148)
        at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:
    1242)
        at org.jdom.input.SAXBuilder.build(SAXBuilder.java:
    453)
        at org.jdom.input.SAXBuilder.build(SAXBuilder.java:
    810)
        at org.jdom.input.SAXBuilder.build(SAXBuilder.java:
    789)
        at dom.TestJdom.main(TestJdom.java:
    26)

    三、分析原因
    當執行build的時候jdom分析到
    DOCTYPE workflow PUBLIC "-/OpenSymphony Group//DTD OSWorkflow 2.8//EN" "http://www.opensymphony.com/osworkflow/workflow_2_8.dtd
    就會去讀取http://www.opensymphony.com/osworkflow/workflow_2_8.dtd 這里的dtd文件來驗證,但是因為網絡是不通的所以就會報socket錯誤。

    四、解決辦法
    1,最開始查看jdom api發現了這樣一個方法
    builder.setValidation(false);
    這樣可以讓jdom不做驗證,但是結果依然出問題,查了一下原因,說雖然不驗證但是還是會下載
    2,參照jdom網站的FAQ  http://www.jdom.org/docs/faq.html#a0100
    這是原文內容
    How do I keep the DTD from loading? Even when I turn off validation the parser tries to load the DTD file.

    Even when validation is turned off, an XML parser will by default load the external DTD file in order to parse the DTD for external entity declarations. Xerces has a feature to turn off this behavior named "http://apache.org/xml/features/nonvalidating/load-external-dtd" and if you know you're using Xerces you can set this feature on the builder.

    builder.setFeature(
      "http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

    If you're using another parser like Crimson, your best bet is to set up an EntityResolver that resolves the DTD without actually reading the separate file.

    import org.xml.sax.*;
    import java.io.*;

    public class NoOpEntityResolver implements EntityResolver {
      public InputSource resolveEntity(String publicId, String systemId) {
        return new InputSource(new StringBufferInputStream(""));
      }
    }

    Then in the builder


    builder.setEntityResolver(new NoOpEntityResolver());

    There is a downside to this approach. Any entities in the document will be resolved to the empty string, and will effectively disappear. If your document has entities, you need to setExpandEntities(false) code and ensure the EntityResolver only suppresses the DocType.
    里邊教我們定義個類
    public class NoOpEntityResolver implements EntityResolver {
      
    public InputSource resolveEntity(String publicId, String systemId) {
                
    return new InputSource(new StringBufferInputStream(""));
      }

    }

    通過builder.setEntityResolver(new NoOpEntityResolver())方法來隱蔽起dtd驗證器。這樣就不會出錯了。試了一下確實沒問題了。但要知道xml沒有dtd驗證是不好的,我們是否能讓它使用本地dtd驗證呢。例如本文的oswork
    我把驗證文件workflow_2_8.dtd拷貝到本地,能否驗證的時候用本地的呢?
    3,用本地dtd驗證
    方法有兩種
    方法一、更改xml中的doctype聲明,但是一般情況下更改這個是不好的。更改后就不是標準的了。
    方法二、驗證期替換
    看到上邊FAQ講的方法你是否有什么靈感呢?
    看看下邊這段代碼

    package dom;

    import java.io.File;
    import java.io.IOException;

    import org.jdom.Document;
    import org.jdom.input.SAXBuilder;
    import org.xml.sax.EntityResolver;
    import org.xml.sax.InputSource;
    import org.xml.sax.SAXException;

    public class TestJdom {
        
    public static void main(String[] args) {
            File file 
    = new File("./src/dom/aiwf_aiService.xml");
            
    if (file.exists()) {
                SAXBuilder builder 
    = new SAXBuilder();
                builder.setValidation(
    false);
                builder.setEntityResolver(
    new EntityResolver() {
                    
    public InputSource resolveEntity(String publicId,
                            String systemId) 
    throws SAXException, IOException {
                        
    return new InputSource("./workflow_2_8.dtd");
                    }

                }
    );
                
    try {
                    Document doc 
    = builder.build(file);
                    System.out.println(doc);
                }
     catch (Exception e) {
                    e.printStackTrace();
                }

            }
     else {
                System.out.println(
    "can not find xml file:"
                        
    + file.getAbsolutePath());
            }

        }

    }

    對了,同樣是自己實現一個EntityResolver(這里用了匿名類),不同的是在里邊使用本地的dtd驗證
    另外,匿名類內部,似乎這樣寫起來更順眼些

    InputStream stream = new FileInputStream( "your dtd file path" );
                        InputSource is 
    = new InputSource(stream);
                        is.setPublicId(publicId);
                        is.setSystemId(systemId);
                        
    return is;

    轉自:http://m.tkk7.com/dreamstone/archive/2007/08/29/140993.html
    posted on 2009-06-22 18:16 胖胖泡泡 閱讀(278) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 暖暖免费中文在线日本| 亚洲综合色区中文字幕| 曰批全过程免费视频观看免费软件 | 亚洲人成色7777在线观看不卡| 亚洲av无码片vr一区二区三区| 欧洲美熟女乱又伦免费视频| 亚洲日韩看片无码电影| 午夜一级免费视频| 春暖花开亚洲性无区一区二区 | 国产乱辈通伦影片在线播放亚洲 | 久久九九AV免费精品| 亚洲精品国产福利片| 青青青国产在线观看免费 | 国产AV无码专区亚洲AVJULIA| 国产99视频精品免费专区| 亚洲视频小说图片| 成年女人男人免费视频播放| 日韩国产精品亚洲а∨天堂免| 国产片免费福利片永久| 免费国产va视频永久在线观看| 一本久久a久久精品亚洲| 人妻丰满熟妇无码区免费| 亚洲国产精品白丝在线观看| 蜜臀91精品国产免费观看| 国产成人自产拍免费视频| 亚洲av伊人久久综合密臀性色| 亚洲成人免费电影| 日韩国产精品亚洲а∨天堂免| 亚洲人精品午夜射精日韩| 大学生一级毛片免费看| 无忧传媒视频免费观看入口| 亚洲av无码专区在线播放| aa级一级天堂片免费观看| 边摸边吃奶边做爽免费视频99| 亚洲av无码一区二区三区乱子伦| 黄页网站免费在线观看| 伊人久久国产免费观看视频| 亚洲视频免费一区| 亚洲第一网站男人都懂| 日日麻批免费40分钟日本的| 色噜噜狠狠色综合免费视频|