我没怎么细读源码,等下次详细看的时候将这句话去掉。
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);
}
}
EncodeQueryPanel
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() + "\r\n");
for(int i=0; i<requestHeaders.size(); i++) {
buffer.append(requestHeaders.get(i) + "\r\n");
}
// Add Content-Length header for POST data.
if ("POST".equalsIgnoreCase(requestMethod)) {
buffer.append("Content-Length: " +
queryData.length() + "\r\n");
buffer.append("\r\n");
buffer.append(queryData);
} else {
buffer.append("\r\n");
}
System.out.println("Request:\n\n" + buffer.toString());
out.println(buffer.toString());
out.flush();
String line;
while ((line = in.readLine()) != null &&
!interrupted) {
outputArea.append(line + "\n");
}
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);
}
}
}
HttpClient
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);
}
}
}
HttpProxyClient
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);
}
}
LabelTestField
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, "\r\n");
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] \n" +
" [-Djavax.net.ssl.trustStoreType=value] \n" +
" [-Dhttp.proxyHost=value] \n" +
" [-Dhttp.proxyPort=value] \n" +
" [-Dhttps.proxyHost=value] \n" +
" [-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);
}
}
}
WebClient
效果图: