精彩专题推荐:建站之入门课 建站之必修课 建站之关键课 网站价值所在 流量提高专题 css+div 标准 个人网站打造全过程
  • 让你的网站产生收益赚钱,有博客和网站的绝对不能错过
  • 将指定的流量带到你的网站,为你站增加有效的访客,为你提升业绩
  • 在Ajax 应用程序中实现数据之间交换

    来源:网络 时间:07-12-27 点击: 点击这里收藏本文

      出于安全和可靠性的考虑,应当在服务器端对数据进行重新验证,而不应想当然地认为 XML 请求格式设置正确。XML 模式是在服务器端验证复杂请求的有用工具。示例代码下载中包含了一个名为 XMLUtil 的类,它提供用于加载和使用模式文档的方法。以下代码段显示了如何初始化 SchemaFactory:

    import javax.xml.*;
    import javax.xml.validation.*;
    ...
    protected static SchemaFactory schemaFactory;
    static {
    schemaFactory = SchemaFactory.newInstance(
    XMLConstants.W3C_XML_SCHEMA_NS_URI);
    schemaFactory.setErrorHandler(newErrorHandler());
    }

    The newErrorHandler() method returns a SAX error handler:

    import org.xml.sax.*;
    ...
    public static ErrorHandler newErrorHandler() {
    return new ErrorHandler() {
    public void warning(SAXParseException e)
    throws SAXException {
    Logger.global.warning(e.getMessage());
            }

    public void error(SAXParseException e)
    throws SAXException {
    throw e;
            }

    public void fatalError(SAXParseException e)
    throws SAXException {
    throw e;
            }
        };
    }
     


      可以使用 getResourceAsStream() 查找并加载某个目录中的 XSD 文件或 CLASSPATH 中指定的 JAR:

    public static InputStream getResourceAsStream(String name)
    throws IOException {
    InputStream in = XMLUtil.class.getResourceAsStream(name);
    if (in == null)
    throw new FileNotFoundException(name);
    return in;
    }


      然后,使用 SchemaFactory 实例通过 newSchema() 方法获取 Schema 对象:

    import javax.xml.validation.*;
    ...
    public static Schema newSchema(String name)
    throws IOException, SAXException {
    Schema schema;
    InputStream in = getResourceAsStream(name);
    try{
    schema = schemaFactory.newSchema(new StreamSource(in));
    }finally{
    in.close();
        }
    return schema;
    }

    您还可以使用以下方法创建 Oracle XMLSchema 对象:

    import oracle.xml.parser.schema.XMLSchema;
    import oracle.xml.parser.schema.XSDBuilder;
    ...
    public static XMLSchema newOracleSchema(String name)
    throws IOException, SAXException {
    XMLSchema schema;
    InputStream in = getResourceAsStream(name);
    try{
    XSDBuilder builder = new XSDBuilder();
    schema = builder.build(new InputSource(in));
    } catch (Exception e){
    throw new SAXException(e);
    }finally{
    in.close();
        }
    return schema;
    }


      接下来,您需要创建一个 DocumentBuilderFactory。如果在 CLASSPATH 中找到的是 JAXP 1.1 实现,则由 JAXP 1.2 定义的 setSchema() 方法可能会抛出 UnsupportedOperationException,此时需要将 JAXP 1.1 实现替换为 Java SE 5.0 的 JAXP 1.2 实现。在这种情况下,您仍可使用 newOracleSchema() 创建模式对象,并通过 setAttribute()方法对其进行设置:

    import javax.xml.parsers.*;
    import oracle.xml.jaxp.JXDocumentBuilderFactory;
    ...
    public static DocumentBuilderFactory newParserFactory(
    String schemaName) throws IOException, SAXException {
    DocumentBuilderFactory parserFactory
    = DocumentBuilderFactory.newInstance();
    try{
    parserFactory.setSchema(newSchema(schemaName));
    } catch (UnsupportedOperationException e) {
    if (parserFactory instanceof JXDocumentBuilderFactory) {
    parserFactory.setAttribute(
    JXDocumentBuilderFactory.SCHEMA_OBJECT,
    newOracleSchema(schemaName));
            }
        }
    return parserFactory;
    }


      然后,创建一个 DocumentBuilder 对象,并使用该对象验证和分析 XML 文档:

    import javax.xml.parsers.*;
    ...
    public static DocumentBuilder newParser(
    DocumentBuilderFactory parserFactory)
    throws ParserConfigurationException {
    DocumentBuilder parser = parserFactory.newDocumentBuilder();
    parser.setErrorHandler(newErrorHandler());
    return parser;
    };


      假设您要根据 portfolio.xsd 模式示例验证 XML 文档:

    < xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    < xsd:element name="portfolio" type="portfolioType"

    < xsd:complexType name="portfolioType">
    < xsd:sequence>
    < xsd:element name="stock"
    minOccurs="0" maxOccurs="unbounded">
    < xsd:complexType>
    < xsd:attribute name="symbol"
    type="xsd:string" use="required"/>
    < xsd:attribute name="shares"
    type="xsd:positiveInteger" use="required"/>
    < xsd:attribute name="paidPrice"
    type="xsd:decimal" use="required"/>
    < /xsd:complexType>
    < /xsd:element>
    < /xsd:sequence>
    < /xsd:complexType>

    < /xsd:schema>
     

     DataModel 类的 parsePortfolioDoc() 方法使用 XMLUtil 验证和分析 xml 参数,并返回一个 DOM 文档:

    private static final String SCHEMA_NAME
    = "/ajaxapp/model/portfolio.xsd";
    private static DocumentBuilderFactory parserFactory;
       
    private static Document parsePortfolioDoc(String xml)
    throws IOException, SAXException,
    ParserConfigurationException {
    synchronized (DataModel.class) {
    if (parserFactory == null)
    parserFactory = XMLUtil.newParserFactory(SCHEMA_NAME);
        }
    DocumentBuilder parser = XMLUtil.newParser(parserFactory);
    InputSource in = new InputSource(new StringReader(xml));
    return parser.parse(in);
    }


      现在,您拥有了一个 DOM 树,接下来要获取形成 DOM 节点所需的数据。

      提取所需信息。您可以使用 DOM API 或查询语言(如 XQuery 或 XPath)来浏览 DOM 树。Java 为 XPath 提供了标准的 API,后面会用到。XMLUtil 类创建一个具有 newXPath() 方法的 XPathFactory:

    import javax.xml.xpath.*;
    ...
    protected static XPathFactory xpathFactory;
    static {
    xpathFactory = XPathFactory.newInstance();
    }
       
    public static XPath newXPath() {
    return xpathFactory.newXPath();
    }


      以下方法在给定的上下文中求解 XPath 表达式,返回结果值:

    import javax.xml.xpath.*;
    import org.w3c.dom.*;
    ...
    public static String evalToString(String expression,
    Object context) throws XPathExpressionException {
    return (String) newXPath().evaluate(expression, context,
    XPathConstants.STRING);
    }
       
    public static boolean evalToBoolean(String expression,
    Object context) throws XPathExpressionException {
    return ((Boolean) newXPath().evaluate(expression, context,
    XPathConstants.BOOLEAN)).booleanValue();
    }
       
    public static double evalToNumber(String expression,
    Object context) throws XPathExpressionException {
    return ((Double) newXPath().evaluate(expression, context,
    XPathConstants.NUMBER)).doubleValue();
    }
       
    public static Node evalToNode(String expression,
    Object context) throws XPathExpressionException {
    return (Node) newXPath().evaluate(expression, context,
    XPathConstants.NODE);
    }
       
    public static NodeList evalToNodeList(String expression,
    Object context) throws XPathExpressionException {
    return (NodeList) newXPath().evaluate(expression, context,
    XPathConstants.NODESET);
    }

     DataModel 的 setData() 方法使用 XPath 求解方法从组合 XML 文档提取信息:

    public synchronized void setData(String xml)
    throws IOException, SAXException,
    ParserConfigurationException,
    XPathExpressionException {
    try{
    ArrayList stockList
    = new ArrayList();
    Document doc = parsePortfolioDoc(xml);
    NodeList nodeList = XMLUtil.evalToNodeList(
    "/portfolio/stock", doc);
    for (int i = 0; i <  nodeList.getLength(); i++) {
    Node node = nodeList.item(i);
    StockBean stock = new StockBean();
    stock.setSymbol(
    XMLUtil.evalToString("@symbol", node));
    stock.setShares(
    (int) XMLUtil.evalToNumber("@shares", node));
    stock.setPaidPrice(
    XMLUtil.evalToNumber("@paidPrice", node));
    stockList.add(stock);
            }
    this.stockList = stockList;
    } catch (Exception e){
    Logger.global.logp(Level.SEVERE, "DataModel", "setData",
    e.getMessage(), e);
        }
    }


      一旦服务器端的数据模型中具备了数据,就可根据应用程序的要求对其进行处理了。然后,您必须响应 Ajax 请求。

      在服务器端生成响应

      将 HTML 作为 Ajax 请求的响应而返回是一种最简单的解决方案,这是因为您可以使用 JSP 语法构建标记,而 Ajax 客户端只需使用 < div> 或 < span> 元素的 innerHTML 属性在页面某处插入 HTML。但是,向 Ajax 客户端返回不带任何表示标记的数据则更为有效。您可以使用 XML 格式或 JSON。

    9 7 3 1 2 3 4 4 8 :

    用户评论

    广而告之