开发者

How can I clean up the following POST JAVA method

开发者 https://www.devze.com 2023-03-13 11:48 出处:网络
I have the following method which calls a POST service and it returns XML which I want to put the attributes of the element into a HashMap

I have the following method which calls a POST service and it returns XML which I want to put the attributes of the element into a HashMap

The XML format is:

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

The method I want to tidy up is:

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(lin开发者_StackOverflow中文版e);
            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();
        }
    }

Thanks in advance guys.


There are two ways to simplify XML parsing.

  1. If you have the XML schema then, JAXB can do the XML to Java conversion.

  2. You can create a utility class to parse the name value pairs by passing it the XML in a constructor.

Slightly unrelated to your original question but, if you are using myMethod() to connect to multiple URLs then, I would make parallel calls to speed up the response. Check out java.util.concurrent.ScheduledExecutorService


First of all, your method is way too long. This probably more fits to Code Review, but you have to learn how to use Extract method refactoring. Here is what I got after few mindless clicks:

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;
}

Other changes:

  • IOUtils class is used to simplify I/O tedious tasks
  • slightly simplified exception handling (well, actually, removed)
0

精彩评论

暂无评论...
验证码 换一张
取 消