Sending SOAP message by Proxy in Java

2019-04-09 11:26发布

问题:

I need to know how to set a Proxy and confirm that it is working.

I have made a test program looking like this:

Where you can specify a proxy address and port number.

(I found the address and port on: http://www.freeproxylists.net/)

The SOAP call is looking like this when "Use Proxy" is checked:

        Socket socket = new Socket();
        SocketAddress sockaddr = new InetSocketAddress(PROXY_ADDRESS, PROXY_PORT);
        socket.connect(sockaddr, 10000);
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(socket.getInetAddress(), PROXY_PORT));
        URL url = new URL(urlStr);
        HttpURLConnection uc = (HttpURLConnection) url.openConnection(proxy);
        return connection.call(message, uc);

Problem here is that the last row SOAPConnection.call(..) dose not allow HttpURLConnection as input and thereby gives:

Bad endPoint type

Any idea how to add a proxy address to a SOAP call and verify that the proxy is in use?

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URL;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

public class TestProxy implements ActionListener {

    public JTextField proxyField;
    public JTextField portField;
    public JCheckBox useProxy;

    // GUI
    public TestProxy() {
        JFrame f = new JFrame("Proxy tester");
        f.getContentPane().setLayout(new BoxLayout(f.getContentPane(), BoxLayout.Y_AXIS));

        proxyField = new JTextField("103.247.43.218");
        portField = new JTextField("8081");
        useProxy = new JCheckBox("Use Proxy");

        JButton b = new JButton("Connect!");
        b.addActionListener(this);

        f.getContentPane().add(proxyField);
        f.getContentPane().add(portField);
        f.getContentPane().add(useProxy);
        f.getContentPane().add(b);

        f.pack();
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

    // ACTION
    @Override
    public void actionPerformed(ActionEvent e) {

        SOAPMessage response = null;
        try {
            SOAPMessage msg = createSOAPRequest();
            String urlStr = "http://www.webservicex.net/CurrencyConvertor.asmx?WSDL";
            response = sendSOAPMessage(msg, urlStr);
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
        } catch (SOAPException e1) {
            e1.printStackTrace();
        } catch (Exception e2) {
            e2.printStackTrace();
        }
        if (response == null)
            JOptionPane.showMessageDialog(null, "Null returned...");
        else
            JOptionPane.showMessageDialog(null, "Returned response!!!");
    }

    // SOAP CALL
    public SOAPMessage sendSOAPMessage(SOAPMessage message, String urlStr) throws SOAPException, MalformedURLException {

        String PROXY_ADDRESS = proxyField.getText();
        int PROXY_PORT = Integer.parseInt(portField.getText());
        try {
            SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
            SOAPConnection connection = factory.createConnection();
            if (useProxy.isSelected()) {
                Socket socket = new Socket();
                SocketAddress sockaddr = new InetSocketAddress(PROXY_ADDRESS, PROXY_PORT);
                socket.connect(sockaddr, 10000);
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(socket.getInetAddress(), PROXY_PORT));
                URL url = new URL(urlStr);
                HttpURLConnection uc = (HttpURLConnection) url.openConnection(proxy);
                // This "call" is not allowed!!
                return connection.call(message, uc);
            } else {
                return connection.call(message, urlStr);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    // SOAP MESSAGE
    private static SOAPMessage createSOAPRequest() throws Exception {
        MessageFactory messageFactory = MessageFactory.newInstance();
        SOAPMessage soapMessage = messageFactory.createMessage();
        return soapMessage;
    }

    public static void main(String[] args) {
        new TestProxy();
    }
}

回答1:

Working sendSOAPMessage method that use proxy:

public static SOAPMessage sendSOAPMessage(SOAPMessage message, String url, final Proxy p) throws SOAPException, MalformedURLException {
    SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
    SOAPConnection connection = factory.createConnection();

    URL endpoint = new URL(null, url, new URLStreamHandler() {
        protected URLConnection openConnection(URL url) throws IOException {
            // The url is the parent of this stream handler, so must
            // create clone
            URL clone = new URL(url.toString());

            URLConnection connection = null;
            if (p.address().toString().equals("0.0.0.0/0.0.0.0:80")) {
                connection = clone.openConnection();
            } else
                connection = clone.openConnection(p);
            connection.setConnectTimeout(5 * 1000); // 5 sec
            connection.setReadTimeout(5 * 1000); // 5 sec
            // Custom header
            connection.addRequestProperty("Developer-Mood", "Happy");
            return connection;
        }
    });

    try {
        SOAPMessage response = connection.call(message, endpoint);
        connection.close();
        return response;
    } catch (Exception e) {
        // Re-try if the connection failed
        SOAPMessage response = connection.call(message, endpoint);
        connection.close();
        return response;
    }
}


回答2:

You can use Java Proxy class - more details here. In essence, you can try whether your specified Proxy address is reachable or not. In case it is you can establish a URL connection (HTTP connection as shown below or your own protocol - like SOAP) EDIT:

Using SocketAddress to try using the port value

   Socket socket = null;
        try {
            SocketAddress sockaddr = new InetSocketAddress(PROXY_ADDRESS,
                    PROXY_PORT);

            socket = new Socket();

            socket.connect(sockaddr, 10000);
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
                    socket.getInetAddress(), PROXY_PORT));

            if (socket.getInetAddress().isReachable(10000)) {
                URL url = new URL("http://www.popofibo.com");
                HttpURLConnection uc = (HttpURLConnection) url
                        .openConnection(proxy);
                System.out.println("Content: " + uc.getContentType());
                uc.connect();
            }

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

In the above example, you establish a proxy connection and check if the InetAddress is reachable or not. If yes, you go forth and use your proxy to establish an http connection.

EDIT: Since isReachable()'s credibility is questionable, you can try catching the exceptions and buidling your own boolean flag, working example below.

Here you try the connection of the proxy using its address and port through Socket connection and catch the exceptions. I tested both the examples with my own proxy server and it works, it definitely fails for the IP mentioned by you in the example.

public static void main(String[] args) {
        Socket socket = new Socket();
        boolean proxyReachable = false;

        SocketAddress sockaddr = new InetSocketAddress(PROXY_ADDRESS,
                PROXY_PORT);

        try {
            socket.connect(sockaddr, 10000);
            proxyReachable = true;
        } catch (SocketTimeoutException e) {
            proxyReachable = false;

        } catch (IOException e) {
            proxyReachable = false;
        }

        if (proxyReachable) {
            try {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
                        socket.getInetAddress(), PROXY_PORT));

                URL url = new URL("http://www.popofibo.com");

                HttpURLConnection uc = (HttpURLConnection) url
                        .openConnection(proxy);
                System.out.println("Content: " + uc.getContentType());
                uc.connect();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Output (with a valid proxy address/port):

Content: text/html; charset=UTF-8


标签: java soap proxy