如何清理以下POST JAVA方法

时间:2011-06-14 20:42:34

标签: java xml post

我有以下方法调用POST服务,它返回XML,我想将元素的属性放入HashMap

XML格式为:

<?xml version="1.0"?><paul><ncresponse
atA="14"
atB="10452775"
atC="0">
</ncresponse></paul>

我想整理的方法是:

private HashMap<String, String> myMethod(URL url) throws Exception{
    String dataToSend = createUrlParameters();
    HttpURLConnection connection = null;
    HashMap<String, String> keyValues = new HashMap<String, String>();

    try {
        //Create connection
        connection = (HttpURLConnection)url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setRequestProperty("Content-Length", "" + Integer.toString(dataToSend.getBytes().length));
        connection.setRequestProperty("Content-Language", "en-US");

        connection.setUseCaches(false);
        connection.setDoInput(true);
        connection.setDoOutput(true);

        //Send request
        DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
        wr.writeBytes(dataToSend);
        wr.flush();
        wr.close();

        //Get Response
        InputStream is = connection.getInputStream();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        String line;
        StringBuffer response = new StringBuffer();

        while((line = rd.readLine()) != null) {
            response.append(line);
            response.append('\r');
        }

        rd.close();

        System.out.println(response.toString());

        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        org.xml.sax.InputSource inStream = new org.xml.sax.InputSource();
        inStream.setCharacterStream(new java.io.StringReader(response.toString()));
        Document doc = dBuilder.parse(inStream);
        doc.getDocumentElement().normalize();

        NodeList nList = doc.getElementsByTagName("ncresponse");

        for (int temp = 0; temp < nList.getLength(); temp++) {
           Node nNode = nList.item(temp);
           if (nNode.getNodeType() == Node.ELEMENT_NODE) {
               Element eElement = (Element) nNode;
               NamedNodeMap attrs = eElement.getAttributes();
                int len = attrs.getLength();
                for (int i=0; i<len; i++) {
                    Attr attr = (Attr)attrs.item(i);
                    //System.out.println(" " + attr.getNodeName() + "=\"" + attr.getNodeValue() + "\"");
                    keyValues.put(attr.getNodeName(), attr.getNodeValue());
                }
            }
        }

        return keyValues;
    } catch (Exception e) {
        e.printStackTrace();

        return null;
    } finally {

        if(connection != null) {
            connection.disconnect();
        }
    }

先谢谢你们。

2 个答案:

答案 0 :(得分:0)

有两种方法可以简化XML解析。

  1. 如果您有XML模式,那么JAXB可以进行XML到Java的转换。

  2. 您可以创建一个实用程序类,通过在构造函数中传递XML来解析名称值对。

  3. 与您的原始问题略有不同,但是,如果您使用myMethod()连接到多个URL,那么我会进行并行调用以加快响应速度。查看java.util.concurrent.ScheduledExecutorService

答案 1 :(得分:0)

首先,你的方法太长了。这可能更适合Code Review,但您必须学习如何使用提取方法重构。这是我在几次无意识点击之后得到的:

private Map<String, String> myMethod(URL url) throws Exception {
    HttpURLConnection connection = null;

    try {
        String dataToSend = createUrlParameters();
        connection = createConnection(url, dataToSend);
        sendRequest(dataToSend, connection);
        return parseResponse(IOUtils.toString(connection.getInputStream()));
    } finally {
        if (connection != null) {
            connection.disconnect();
        }
    }
}

private Map<String, String> parseResponse(final String responseXml) throws IOException, ParserConfigurationException, SAXException {
    Document doc = parseXml(responseXml);
    return extractAttributes(doc);
}

private Map<String, String> extractAttributes(Document doc) {
    NodeList nList = doc.getElementsByTagName("ncresponse");
    Map<String, String> keyValues = new HashMap<String, String>();

    for (int temp = 0; temp < nList.getLength(); temp++) {
        Node nNode = nList.item(temp);
        if (nNode.getNodeType() == Node.ELEMENT_NODE) {
            Element eElement = (Element) nNode;
            NamedNodeMap attrs = eElement.getAttributes();
            int len = attrs.getLength();
            for (int i = 0; i < len; i++) {
                Attr attr = (Attr) attrs.item(i);
                keyValues.put(attr.getNodeName(), attr.getNodeValue());
            }
        }
    }

    return keyValues;
}

private Document parseXml(String responseXml) throws ParserConfigurationException, SAXException, IOException {
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    org.xml.sax.InputSource inStream = new org.xml.sax.InputSource();
    inStream.setCharacterStream(new StringReader(responseXml));
    Document doc = dBuilder.parse(inStream);
    doc.getDocumentElement().normalize();
    return doc;
}

private void sendRequest(String dataToSend, HttpURLConnection connection) throws IOException {
    IOUtils.copy(new StringReader(dataToSend), connection.getOutputStream());
}

private HttpURLConnection createConnection(URL url, String dataToSend) throws IOException {
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("POST");
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    connection.setRequestProperty("Content-Length", "" + Integer.toString(dataToSend.getBytes().length));
    connection.setRequestProperty("Content-Language", "en-US");

    connection.setUseCaches(false);
    connection.setDoInput(true);
    connection.setDoOutput(true);
    return connection;
}

其他变化:

  • IOUtils类用于简化I / O繁琐的任务
  • 略微简化的异常处理(实际上,已删除)