Ok so this is mostly about me playing with the Google syntax highlighter. Its basically some code I rattled up to post data from a | seperated list of post_variable|post_value pairs. Read the code to find out more. Its not a real solution to anything if you want to run tests or batch stuff use Junit, Maven or Ant. But you can have fun with my limited toy if you like – but remember as always the code is GPL and will probably kill you so watch out!
/*
* Batch processor that takes | delimitied lines of fields in a file and posts
* them to an HTTP server printing out the message and response to std out.
*/
/*
* TODO:
* Could be extended to use a configuration file for inputs, logging and could
* bennefit from SSL and proxy configuration options.
*/
package batchpost;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author mc
*/
public class batchpost {
/**
* General output device
*/
static private Logger log = Logger.getLogger(batchpost.class.getName());
/**
* main
*
* Main entry point.
*
* @param args the command line arguments
* args[0] - is the fully qualified name of the batch file to read
* args[1] - is the URL to post the transactions to
*/
public static void main(String[] args) {
/*
* TODO:
* I should validate arguments and do other things but I am skipping doing
* them because of time.
*/
processFile(args[0], args[1]);
}
/**
* processFile
*
* Takes a file apart one line at a time and hands processing off to a
* message processing method. Logs errors if the file is not found or there
* is an IO error while reading the file. Assumes that each line contains a
* complete message.
*
* @param url - path to the web server to send the messages to
* @param file - file to retrieve the message lines from
*/
static private void processFile(String url, String file) {
try {
String line;
BufferedReader br =
new BufferedReader(
new InputStreamReader(
new DataInputStream(
new FileInputStream(file))));
try {
while ((line = br.readLine()) != null) {
processMessage(url, line);
}
} catch (UnsupportedEncodingException ex) {
log.log(Level.SEVERE, "processFile - processing halted because it is " +
"not possible to encode the post string in UTF-8.", ex);
} catch (IOException ex) {
log.log(Level.SEVERE, "processFile - IO exception has halted " +
"processing of the file \"" + file + "\".", ex);
}
try {
br.close();
} catch (IOException ex) {
log.log(Level.SEVERE, "processFile - IO exception has interrupted " +
"closing of the file \"" + file + "\".", ex);
}
} catch (FileNotFoundException ex) {
log.log(Level.SEVERE, "processFile - unable to locate the file \"" +
file + "\".", ex);
}
}
/**
* processMessage
*
* Takes a line of | delimited message fields and posts them to a web server.
* Each line is composed of a list of field_name|field_value pairs such that
* the line looks like:
*
* name_1|value_1|name_2|value_2|...
*
* or
*
* name|bob charles|age|62|occupation|pro golfer
*
* The total number of | delimited fields must be a multiple of 2. The
* message fields must not contain a |.
*
* @param url - address of the web server to post this message to
* @param line - string containing a | delimited set of fields
* @throws java.io.UnsupportedEncodingException when the platform does not
* support utf-8
*/
static private void processMessage(String url, String line)
throws UnsupportedEncodingException {
String[] fields = line.split("\\|");
if (fields.length % 2 == 1) {
log.log(Level.SEVERE, "processMessage - unable to process the following" +
" message as it did not contain a multiple of 2 fields: message = " +
"\"" + line + "\"");
return;
}
String postData = createPostData(fields);
log.log(Level.INFO, "START OF DATA TO BE POSTED");
log.log(Level.INFO, postData);
log.log(Level.INFO, "END OF DATA TO BE POSTED");
String responseData;
responseData = doHTTPPost(url, postData);
log.log(Level.INFO, "START OF DATA RECEIVED FROM POST");
log.log(Level.INFO, responseData);
log.log(Level.INFO, "END OF DATA RECEIVED FROM POST");
}
/**
* createPostData
*
* Takes an array of field names and their values such that each two
* consecutive strings are a field name then value pair and prepares a POST
* data string for sending to a web server. Throws the encoding error as it
* is pointless to continue processing as this error is going to reccur for
* all post attempts if it takes place for one.
*
* @param fields - a string array of field name and value pairs.
* @return string containing the post data.
* @throws java.io.UnsupportedEncodingException
*/
static private String createPostData(String[] fields)
throws UnsupportedEncodingException {
StringBuffer buf = new StringBuffer();
String charEnc = "UTF-8";
try {
buf.append(URLEncoder.encode(fields[0], charEnc));
buf.append('=');
buf.append(URLEncoder.encode(fields[1], charEnc));
for (int i = 2; i < fields.length; i = i + 2) {
buf.append('&');
buf.append(URLEncoder.encode(fields[i], charEnc));
buf.append('=');
buf.append(URLEncoder.encode(fields[i + 1], charEnc));
}
return buf.toString();
} catch (UnsupportedEncodingException ex) {
log.log(Level.SEVERE, "createPostData - unable to encode the post data " +
"as " + charEnc + " is not available on this platform.", ex);
throw ex;
}
}
/**
* readAll
*
* Reads all of the input from the given stream and returns it in a byte array
* output stream, the stream contents can then be retrieved as a byte array or
* a string using either toByteArray or toString respectively.
*
* @param is - an open input stream to read the data from
*
* @return a byte array output stream that contains the data read from the is
* @throws IOException if there is an error reading from the input stream
*/
static private ByteArrayOutputStream readAll(InputStream is)
throws IOException {
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int len = is.read(buf);
while (!(len < 0)) {
result.write(buf, 0, len);
len = is.read(buf);
}
return result;
}
/**
* doHTTPPost
*
* performs the https post operation of the given data to the given url
* returning the result in a byte array output stream, throws an exception if
* an error takes place while performing io operations, does not deal with
* proxy servers
*
* @param data - a post formatted data stream for sending to the url server
* @param url - the target to send the post to
*
* @return a data stream of the response from the server at the url
* @throws IOException on failure of any io operation
*/
static private String doHTTPPost(String url, String data) {
String result = "";
HttpURLConnection conn = null;
try {
// set up the url connection
conn = (HttpURLConnection) (new URL(url)).openConnection();
try {
// write out the data to the server
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.getOutputStream().write(data.getBytes());
System.out.println(conn.getResponseMessage());
// disconnect and recycle the connection, return the response data
result = readAll(conn.getInputStream()).toString();
} catch (ProtocolException ex) {
log.log(Level.SEVERE, "doHTTPPost - unable to marshal the required " +
"protocol to establish a connection to \"" + url + "\"", ex);
} catch (IOException ex) {
log.log(Level.SEVERE, "doHTTPPost - IO error while attempting to " +
"perform the data post operation.", ex);
} finally {
conn.disconnect();
}
} catch (MalformedURLException ex) {
log.log(Level.SEVERE, "doHTTPPost - the URL currently being attempted " +
"to connect with is malformed \"" + url + "\"", ex);
} catch (IOException ex) {
log.log(Level.SEVERE, "doHTTPPost - IO error while attempting to set up" +
" the data post operation.", ex);
} finally {
conn = null;
}
return result;
}
}