我没怎么细读源码,等下次详细看的时候将这句话去掉。
import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import javax.swing.*; import javax.swing.border.*; /** Panel for selecting the format of the query text, either as * name/value pairs or raw text (for example, sending a * serialized object. * <P> * Also, provides the ability to encode a String in the * application/x-www-form-urlencoded format. * <P> * Taken from Core Servlets and JavaServer Pages Volume II * from Prentice Hall and Sun Microsystems Press, * http://volume2.coreservlets.com/. * (C) 2007 Marty Hall, Larry Brown, and Yaakov Chaikin; * may be freely used or adapted. */ public class EncodeQueryPanel extends JPanel implements ActionListener { private Font labelFont, textFont; private JButton okButton, cancelButton; private JRadioButton optionPair, optionRaw; private int value; private Window window; public EncodeQueryPanel(Window window) { this.window = window; labelFont = new Font("Serif", Font.BOLD, 14); textFont = new Font("Monospaced", Font.BOLD, 12); setLayout(new BorderLayout()); add(getOptionPanel(), BorderLayout.CENTER); add(getButtonPanel(), BorderLayout.SOUTH); value = JOptionPane.CANCEL_OPTION; } private JPanel getOptionPanel() { JPanel optionPanel = new JPanel(); Border border = BorderFactory.createEtchedBorder(); optionPanel.setBorder( BorderFactory.createTitledBorder(border, "Encode data as ... ", TitledBorder.LEFT, TitledBorder.CENTER, labelFont)); optionPanel.setLayout( new BoxLayout(optionPanel, BoxLayout.Y_AXIS)); optionPair = new JRadioButton("name/value pairs"); optionPair.setFont(labelFont); optionPair.setSelected(true); optionRaw = new JRadioButton("raw text"); optionRaw.setFont(labelFont); ButtonGroup group = new ButtonGroup(); group.add(optionPair); group.add(optionRaw); optionPanel.add(optionPair); optionPanel.add(optionRaw); return(optionPanel); } private JPanel getButtonPanel() { JPanel buttonPanel = new JPanel(); okButton = new JButton("OK"); okButton.setFont(labelFont); okButton.addActionListener(this); cancelButton = new JButton("Cancel"); cancelButton.setFont(labelFont); cancelButton.addActionListener(this); buttonPanel.add(okButton); buttonPanel.add(cancelButton); return(buttonPanel); } public void actionPerformed(ActionEvent event) { if (event.getSource() == okButton) { value = JOptionPane.OK_OPTION; } window.dispose(); } public int getValue() { return(value); } /** Based on option selected (name/value pairs, raw text), * encode the data (assume UTF-8 charset). */ public String encode(String queryData) throws UnsupportedEncodingException { if(queryData == null || queryData.length() == 0) { return(queryData); } if (optionRaw.isSelected()) { queryData = URLEncoder.encode(queryData, "UTF-8"); } else { // Fit each name/value pair and rebuild with // the value encoded. StringBuffer encodedData = new StringBuffer(); String[] pairs = queryData.split("&"); for(int i=0; i<pairs.length; i++) { encodedData.append(encodePair(pairs[i])); if (i<pairs.length-1) { encodedData.append("&"); } } queryData = encodedData.toString(); } return(queryData); } // Process name/value pair, returning pair with // value encoded. private String encodePair(String nameValuePair) throws UnsupportedEncodingException { String encodedPair = ""; String[] pair = nameValuePair.split("="); if (pair[0].trim().length() == 0) { throw new UnsupportedEncodingException("Name missing"); } encodedPair = pair[0].trim() + "="; if (pair.length > 1) { encodedPair += URLEncoder.encode(pair[1], "UTF-8"); } return(encodedPair); } }
import java.net.*; import java.io.*; import java.util.*; import javax.net.*; import javax.net.ssl.*; import javax.swing.*; /** The underlying network client used by WebClient. Sends an * HTTP request in the following format:<P> * * GET / HTTP/1.0 * <P> * Request can be GET or POST, and the HTTP version can be 1.0 * or 1.1 (a Host: header is required for HTTP 1.1). * Supports both HTTP and HTTPS (SSL). * <P> * Taken from Core Servlets and JavaServer Pages Volume II * from Prentice Hall and Sun Microsystems Press, * http://volume2.coreservlets.com/. * (C) 2007 Marty Hall, Larry Brown, and Yaakov Chaikin; * may be freely used or adapted. */ public class HttpClient { protected URL url; protected String requestMethod; protected String httpVersion; protected List requestHeaders; protected String queryData; protected JTextArea outputArea; protected boolean interrupted; public HttpClient(URL url, String requestMethod, String httpVersion, List requestHeaders, String queryData, JTextArea outputArea) { this.url = url; this.requestMethod = requestMethod; this.httpVersion = httpVersion; this.requestHeaders = requestHeaders; this.queryData = queryData; this.outputArea = outputArea; } /** Establish the connection, then pass the socket * to handleConnection. */ public void connect() { if(!isValidURL()) { return; } String host = url.getHost(); int port = url.getPort(); if (port == -1) { port = url.getDefaultPort(); } connect(host, port); } /** Open a TCP connection to host on specified port and * then call handleConnection to process the request. * For an https request, use a SSL socket. */ protected void connect(String host, int port) { try { Socket client = null; if (isSecure()) { SocketFactory factory = SSLSocketFactory.getDefault(); client = factory.createSocket(host, port); } else { client = new Socket(host, port); } handleConnection(client); client.close(); } catch(UnknownHostException uhe) { report("Unknown host: " + host); uhe.printStackTrace(); } catch(ConnectException ce) { report("Connection problem: " + ce.getMessage()); ce.printStackTrace(); } catch(IOException ioe) { report("IOException: " + ioe.getMessage()); ioe.printStackTrace(); } } /** Send request to server, providing all specified headers * and query data. If a POST request, add a header for the * Content-Length. */ public void handleConnection(Socket socket) { try { // Make a PrintWriter to send outgoing data. // Second argument of true means autoflush. PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // Make a BufferedReader to get incoming data. BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream())); StringBuffer buffer = new StringBuffer(); outputArea.setText(""); buffer.append(getRequestLine() + " "); for(int i=0; i<requestHeaders.size(); i++) { buffer.append(requestHeaders.get(i) + " "); } // Add Content-Length header for POST data. if ("POST".equalsIgnoreCase(requestMethod)) { buffer.append("Content-Length: " + queryData.length() + " "); buffer.append(" "); buffer.append(queryData); } else { buffer.append(" "); } System.out.println("Request: " + buffer.toString()); out.println(buffer.toString()); out.flush(); String line; while ((line = in.readLine()) != null && !interrupted) { outputArea.append(line + " "); } if (interrupted) { outputArea.append("---- Download Interrupted ----"); } out.close(); in.close(); } catch(Exception e) { outputArea.setText("Error: " + e); } } /** Create HTTP request line, i.e., GET URI HTTP/1.0 */ protected String getRequestLine() { String method = "GET"; String uri = url.getPath(); String version = "HTTP/1.0"; // Determine if POST request. If not, then GET request. // Add query data after ? for GET request. if ("POST".equalsIgnoreCase(requestMethod)) { method = "POST"; } else { if (queryData.length() > 0) { uri += "?" + queryData; } } if ("HTTP/1.1".equalsIgnoreCase(httpVersion)) { version = "HTTP/1.1"; } String request = method + " " + uri + " " + version; return(request); } protected void report(String str) { outputArea.setText(str); } /* Check protocol for https (SSL). */ protected boolean isSecure() { return("https".equalsIgnoreCase(url.getProtocol())); } public void setInterrupted(boolean interrupted) { this.interrupted = interrupted; } /** Determine if host evaluates to an Internet address. */ protected boolean isValidURL() { if (url == null) { return(false); } try { InetAddress.getByName(url.getHost()); return(true); } catch(UnknownHostException uhe) { report("Bogus Host: " + url.getHost()); return(false); } } }
import java.net.*; import java.io.*; import java.util.*; import javax.net.*; import javax.net.ssl.*; import javax.swing.*; /** The underlying proxy client used by WebClient. Proxy * requests are sent in the following format:<P> * * GET URL HTTP/1.0 * * <P>where the URL is the WebClient URL, for example, * http://www.google.com/. * <P> * Taken from Core Servlets and JavaServer Pages Volume II * from Prentice Hall and Sun Microsystems Press, * http://volume2.coreservlets.com/. * (C) 2007 Marty Hall, Larry Brown, and Yaakov Chaikin; * may be freely used or adapted. */ public class HttpProxyClient extends HttpClient { private URL proxyURL; public HttpProxyClient(URL url, URL proxyURL, String requestMethod, String httpVersion, List requestHeaders, String queryData, JTextArea outputArea) { super(url, requestMethod, httpVersion, requestHeaders, queryData, outputArea); this.proxyURL = proxyURL; } /** Open TCP connection to Proxy host. */ public void connect() { if(!isValidURL() || !isValidProxyURL()) { return; } String host = proxyURL.getHost(); int port = proxyURL.getPort(); if (port == -1) { port = proxyURL.getDefaultPort(); } connect(host, port); } /** Create HTTP request line for proxy server. Instead of * stating a URI, the GET or POST request states the full * URL for the original page request. For example, <P> * * GET http://www.google.com/ HTTP/1.0 */ protected String getRequestLine() { String method = "GET"; String url = this.url.toString(); String version = "HTTP/1.0"; // Determine if POST request. If not, then GET request. // Add query data after ? for GET request. if ("POST".equalsIgnoreCase(requestMethod)) { method = "POST"; } else { if (queryData.length() > 0) { url += "?" + queryData; } } if ("HTTP/1.1".equalsIgnoreCase(httpVersion)) { version = "HTTP/1.1"; } String request = method + " " + url + " " + version; return(request); } /** Determine if proxy server is a valid host address. */ protected boolean isValidProxyURL() { if (proxyURL == null) { return(false); } try { InetAddress.getByName(proxyURL.getHost()); return(true); } catch(UnknownHostException uhe) { report("Bogus Proxy: " + url.getHost()); return(false); } } }
import java.awt.*; // For FlowLayout, Font. import javax.swing.*; /** A TextField with an associated Label. * <P> * Taken from Core Servlets and JavaServer Pages Volume II * from Prentice Hall and Sun Microsystems Press, * http://volume2.coreservlets.com/. * (C) 2007 Marty Hall, Larry Brown, and Yaakov Chaikin; * may be freely used or adapted. */ public class LabeledTextField extends JPanel { private JLabel label; private JTextField textField; public LabeledTextField(String labelString, Font labelFont, int textFieldSize, Font textFont) { setLayout(new FlowLayout(FlowLayout.LEFT)); label = new JLabel(labelString, JLabel.RIGHT); if (labelFont != null) { label.setFont(labelFont); } add(label); textField = new JTextField(textFieldSize); if (textFont != null) { textField.setFont(textFont); } add(textField); } public LabeledTextField(String labelString, String textFieldString) { this(labelString, null, textFieldString, textFieldString.length(), null); } public LabeledTextField(String labelString, int textFieldSize) { this(labelString, null, textFieldSize, null); } public LabeledTextField(String labelString, Font labelFont, String textFieldString, int textFieldSize, Font textFont) { this(labelString, labelFont, textFieldSize, textFont); textField.setText(textFieldString); } /** The Label at the left side of the LabeledTextField. * To manipulate the Label, do: * <PRE> * LabeledTextField ltf = new LabeledTextField(...); * ltf.getLabel().someLabelMethod(...); * </PRE> */ public JLabel getLabel() { return(label); } /** The TextField at the right side of the * LabeledTextField. */ public JTextField getTextField() { return(textField); } public void setText(String textFieldString) { textField.setText(textFieldString); } }
main程序:
import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.*; import javax.swing.*; /** A graphical client that lets you interactively connect to * Web servers and send custom URLs, request headers, and * query data. The user can optionally select a GET or POST * request and HTTP version 1.0 or 1.1. * <P> * For an HTTPS connection, you can specify a nondefault * keystore through system properties on the command line, * i.e., * <P> * java -Djavax.net.ssl.trustStore=server.ks * -Djavax.net.ssl.trustStoreType=JKS * <P> * Taken from Core Servlets and JavaServer Pages Volume II * from Prentice Hall and Sun Microsystems Press, * http://volume2.coreservlets.com/. * (C) 2007 Marty Hall, Larry Brown, and Yaakov Chaikin; * may be freely used or adapted. */ public class WebClient extends JPanel implements Runnable { public static void main(String[] args) { if (args.length > 0) { usage(); } else { try { UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); } catch(Exception e) { System.out.println("Error setting native LAF: " + e); } Container content = new WebClient(); content.setBackground(SystemColor.control); JFrame frame = new JFrame("Web Client"); frame.setContentPane(content); frame.setBackground(SystemColor.control); frame.setSize(600, 700); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE); frame.setVisible(true); } } private static JFrame frame; private LabeledTextField urlField; private JComboBox methodCombo, versionCombo; private LabeledTextField proxyHostField, proxyPortField; private JTextArea requestHeadersArea, queryDataArea; private JTextArea resultArea; private JButton encodeButton, submitButton, interruptButton; private Font labelFont, headingFont, textFont; private HttpClient client; public WebClient() { int fontSize = 14; labelFont = new Font("Serif", Font.BOLD, fontSize); headingFont = new Font("SansSerif", Font.BOLD, fontSize+4); textFont = new Font("Monospaced", Font.BOLD, fontSize-2); setLayout(new BorderLayout(5, 30)); // Set up URL, Request Method, and Proxy. JPanel topPanel = new JPanel(new GridLayout(3,1)); topPanel.add(getURLPanel()); topPanel.add(getRequestMethodPanel()); topPanel.add(getProxyPanel()); // Set up Request Header and Query Data. JPanel inputPanel = new JPanel(new GridLayout(3,1)); inputPanel.add(topPanel); inputPanel.add(getRequestHeaderPanel()); inputPanel.add(getQueryDataPanel()); add(inputPanel, BorderLayout.NORTH); add(getResultPanel(), BorderLayout.CENTER); } private JPanel getURLPanel() { JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); urlField = new LabeledTextField("URL:", labelFont, 75, textFont); panel.add(urlField); return(panel); } private JPanel getRequestMethodPanel() { JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); JLabel methodLabel = new JLabel(" Request Method:"); methodLabel.setFont(labelFont); panel.add(methodLabel); methodCombo = new JComboBox(); methodCombo.addItem("GET"); methodCombo.addItem("POST"); panel.add(methodCombo); JLabel versionlabel = new JLabel(" HTTP Version:"); versionlabel.setFont(labelFont); panel.add(versionlabel); versionCombo = new JComboBox(); versionCombo.addItem("HTTP/1.0"); versionCombo.addItem("HTTP/1.1"); panel.add(versionCombo); return(panel); } private JPanel getProxyPanel() { JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); proxyHostField = new LabeledTextField("Proxy Host:", labelFont, 35, textFont); proxyPortField = new LabeledTextField("Proxy Port:", labelFont, 5, textFont); panel.add(proxyHostField); panel.add(proxyPortField); // Check to see if command-line system properties are set // for proxy. String proxyHost = System.getProperty("http.proxyHost"); String sslProxyHost = System.getProperty("https.proxyHost"); String proxyPort = System.getProperty("http.proxyPort"); String sslProxyPort = System.getProperty("https.proxyPort"); if (proxyHost != null) { proxyHostField.setText(proxyHost); if (proxyPort != null) { proxyPortField.setText(proxyPort); } } else if (sslProxyHost != null) { proxyHostField.setText(sslProxyHost); if (sslProxyPort != null) { proxyPortField.setText(sslProxyPort); } } return(panel); } private JPanel getRequestHeaderPanel() { JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); JLabel requestLabel = new JLabel("Request Headers:"); requestLabel.setFont(labelFont); panel.add(requestLabel, BorderLayout.NORTH); requestHeadersArea = new JTextArea(5, 80); requestHeadersArea.setFont(textFont); JScrollPane headerScrollArea = new JScrollPane(requestHeadersArea); panel.add(headerScrollArea, BorderLayout.CENTER); return(panel); } private JPanel getQueryDataPanel() { JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); JLabel formLabel = new JLabel("Query Data:"); formLabel.setFont(labelFont); panel.add(formLabel, BorderLayout.NORTH); queryDataArea = new JTextArea(3, 80); queryDataArea.setFont(textFont); JScrollPane formScrollArea = new JScrollPane(queryDataArea); panel.add(formScrollArea, BorderLayout.CENTER); panel.add(getButtonPanel(), BorderLayout.SOUTH); return(panel); } private JPanel getButtonPanel() { JPanel panel = new JPanel(); encodeButton = new JButton("Encode Data"); encodeButton.addActionListener(new EncodeListener()); encodeButton.setFont(labelFont); panel.add(encodeButton); submitButton = new JButton("Submit Request"); submitButton.addActionListener(new SubmitListener()); submitButton.setFont(labelFont); panel.add(submitButton); return(panel); } private JPanel getResultPanel() { JPanel resultPanel = new JPanel(); resultPanel.setLayout(new BorderLayout()); JLabel resultLabel = new JLabel("Results", JLabel.CENTER); resultLabel.setFont(headingFont); resultPanel.add(resultLabel, BorderLayout.NORTH); resultArea = new JTextArea(); resultArea.setFont(textFont); JScrollPane resultScrollArea = new JScrollPane(resultArea); resultPanel.add(resultScrollArea, BorderLayout.CENTER); JPanel interruptPanel = new JPanel(); interruptButton = new JButton("Interrupt Download"); interruptButton.setFont(labelFont); interruptButton.addActionListener(new InterruptListener()); interruptPanel.add(interruptButton); resultPanel.add(interruptPanel, BorderLayout.SOUTH); return(resultPanel); } /** Create all inputs and then process the request either * directly (HttpClient) or through a proxy server * (HttpProxyClient). */ public void run() { if (hasLegalValues()) { URL url = getRequestURL(); String requestMethod = getRequestMethod(); String httpVersion = getHttpVersion(); ArrayList requestHeaders = getRequestHeaders(); String queryData = getQueryData(); resultArea.setText(""); if (usingProxy()) { URL proxyURL = getProxyURL(); client = new HttpProxyClient(url, proxyURL, requestMethod, httpVersion, requestHeaders, queryData, resultArea); } else { client = new HttpClient(url, requestMethod, httpVersion, requestHeaders, queryData, resultArea); } client.connect(); } } public boolean usingProxy() { String proxyHost = getProxyHost(); return(proxyHost != null && proxyHost.length() > 0); } private boolean hasLegalValues() { if (getRequestURL() == null) { report("Malformed URL"); return(false); } if (usingProxy() && getProxyURL() == null) { report("Proxy invalid"); return(false); } return(true); } // Turn proxy host and port into a URL. private URL getProxyURL() { URL requestURL = getRequestURL(); if (requestURL == null) { return(null); } String proxyURLStr = requestURL.getProtocol() + "://" + getProxyHost(); String proxyPort = getProxyPort(); if (proxyPort != null && proxyPort.length() > 0) { proxyURLStr += ":" + proxyPort + "/"; } return(getURL(proxyURLStr)); } public URL getRequestURL() { return(getURL(urlField.getTextField().getText().trim())); } public URL getURL(String str) { try { URL url = new URL(str); return(url); } catch(MalformedURLException mue) { return(null); } } private String getRequestMethod() { return((String)methodCombo.getSelectedItem()); } private String getHttpVersion() { return((String)versionCombo.getSelectedItem()); } private String getProxyHost() { return(proxyHostField.getTextField().getText().trim()); } private String getProxyPort() { return(proxyPortField.getTextField().getText().trim()); } private ArrayList getRequestHeaders() { ArrayList requestHeaders = new ArrayList(); int headerNum = 0; String header = requestHeadersArea.getText().trim(); StringTokenizer tok = new StringTokenizer(header, " "); while (tok.hasMoreTokens()) { requestHeaders.add(tok.nextToken()); } return(requestHeaders); } private String getQueryData() { return(queryDataArea.getText()); } private void report(String s) { resultArea.setText(s); } private static void usage() { System.out.println( "Usage: java [-Djavax.net.ssl.trustStore=value] " + " [-Djavax.net.ssl.trustStoreType=value] " + " [-Dhttp.proxyHost=value] " + " [-Dhttp.proxyPort=value] " + " [-Dhttps.proxyHost=value] " + " [-Dhttps.proxyPort=value] WebClient"); } /** Listener for Submit button. Performs HTTP request on * separate thread. */ class SubmitListener implements ActionListener { public void actionPerformed(ActionEvent event) { Thread downloader = new Thread(WebClient.this); downloader.start(); } } /** Listener for Encode Data button. Open dialog to * determine how to encode the data (name/value pairs * or raw text). */ class EncodeListener implements ActionListener { public void actionPerformed(ActionEvent event) { String queryData = getQueryData(); if (queryData.length() == 0) { return; } JDialog dialog = new JDialog(frame, "Encode", true); dialog.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE); dialog.setLocationRelativeTo(frame); EncodeQueryPanel panel = new EncodeQueryPanel(dialog); dialog.getContentPane().add(panel); dialog.pack(); dialog.setVisible(true); switch(panel.getValue()) { case JOptionPane.OK_OPTION: try { queryData = panel.encode(queryData); queryDataArea.setText(queryData); } catch(UnsupportedEncodingException uee) { report("Encoding problem: " + uee.getMessage()); } break; case JOptionPane.CANCEL_OPTION: ; default: ; } } } /** Listener for Interrupt button. Stops download of * Web page. */ class InterruptListener implements ActionListener { public void actionPerformed(ActionEvent event) { client.setInterrupted(true); } } }
效果图: