package com.myjavatools.web;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
/**
* <p>Title: Client HTTP Request class</p>
* <p>Description: this class helps to send POST HTTP requests with various form data,
* including files. Cookies can be added to be included in the request.</p>
*
* @author Vlad Patryshev
* @version 1.0
*/
public class ClientHttpRequest
{
URLConnection connection;
OutputStream os = null;
Map cookies = new HashMap();
protected void connect() throws IOException
{
if( os == null )
os = connection.getOutputStream();
}
protected void write(char c) throws IOException
{
connect();
os.write( c );
}
protected void write(String s) throws IOException
{
connect();
os.write( s.getBytes() );
}
protected void newline() throws IOException
{
connect();
write( "\r\n" );
}
protected void writeln(String s) throws IOException
{
connect();
write( s );
newline();
}
private static Random random = new Random();
protected static String randomString()
{
return Long.toString( random.nextLong(), 36 );
}
String boundary = "---------------------------" + randomString() + randomString()
+ randomString();
private void boundary() throws IOException
{
write( "--" );
write( boundary );
}
/**
* Creates a new multipart POST HTTP request on a freshly opened URLConnection
*
* @param connection an already open URL connection
* @throws IOException
*/
public ClientHttpRequest(URLConnection connection) throws IOException
{
this.connection = connection;
connection.setDoOutput( true );
connection.setRequestProperty( "Content-Type", "multipart/form-data; boundary=" + boundary );
}
/**
* Creates a new multipart POST HTTP request for a specified URL
*
* @param url the URL to send request to
* @throws IOException
*/
public ClientHttpRequest(URL url) throws IOException
{
this( url.openConnection() );
}
/**
* Creates a new multipart POST HTTP request for a specified URL string
*
* @param urlString the string representation of the URL to send request to
* @throws IOException
*/
public ClientHttpRequest(String urlString) throws IOException
{
this( new URL( urlString ) );
}
private void postCookies()
{
StringBuffer cookieList = new StringBuffer();
for( Iterator i = cookies.entrySet().iterator(); i.hasNext(); )
{
Map.Entry entry = (Map.Entry)(i.next());
cookieList.append( entry.getKey().toString() + "=" + entry.getValue() );
if( i.hasNext() )
{
cookieList.append( "; " );
}
}
if( cookieList.length() > 0 )
{
connection.setRequestProperty( "Cookie", cookieList.toString() );
}
}
/**
* adds a cookie to the requst
* @param name cookie name
* @param value cookie value
* @throws IOException
*/
public void setCookie(String name, String value) throws IOException
{
cookies.put( name, value );
}
/**
* adds cookies to the request
* @param cookies the cookie "name-to-value" map
* @throws IOException
*/
public void setCookies(Map cookies) throws IOException
{
if( cookies == null )
return;
this.cookies.putAll( cookies );
}
/**
* adds cookies to the request
* @param cookies array of cookie names and values (cookies[2*i] is a name, cookies[2*i + 1] is a value)
* @throws IOException
*/
public void setCookies(String[] cookies) throws IOException
{
if( cookies == null )
return;
for( int i = 0; i < cookies.length - 1; i += 2 )
{
setCookie( cookies[i], cookies[i + 1] );
}
}
private void writeName(String name) throws IOException
{
newline();
write( "Content-Disposition: form-data; name=\"" );
write( name );
write( '"' );
}
/**
* adds a string parameter to the request
* @param name parameter name
* @param value parameter value
* @throws IOException
*/
public void setParameter(String name, String value) throws IOException
{
boundary();
writeName( name );
newline();
newline();
writeln( value );
}
private static void pipe(InputStream in, OutputStream out) throws IOException
{
byte[] buf = new byte[500000];
int nread;
int navailable;
int total = 0;
synchronized( in )
{
while( (nread = in.read( buf, 0, buf.length )) >= 0 )
{
out.write( buf, 0, nread );
total += nread;
}
}
out.flush();
buf = null;
}
/**
* adds a file parameter to the request
* @param name parameter name
* @param filename the name of the file
* @param is input stream to read the contents of the file from
* @throws IOException
*/
public void setParameter(String name, String filename, InputStream is) throws IOException
{
boundary();
writeName( name );
write( "; filename=\"" );
write( filename );
write( '"' );
newline();
write( "Content-Type: " );
String type = connection.guessContentTypeFromName( filename );
if( type == null )
type = "application/octet-stream";
writeln( type );
newline();
pipe( is, os );
newline();
}
/**
* adds a file parameter to the request
* @param name parameter name
* @param file the file to upload
* @throws IOException
*/
public void setParameter(String name, File file) throws IOException
{
setParameter( name, file.getPath(), new FileInputStream( file ) );
}
/**
* adds a parameter to the request; if the parameter is a File, the file is uploaded, otherwise the string value of the parameter is passed in the request
* @param name parameter name
* @param object parameter value, a File or anything else that can be stringified
* @throws IOException
*/
public void setParameter(String name, Object object) throws IOException
{
if( object instanceof File )
{
setParameter( name, (File)object );
}
else
{
setParameter( name, object.toString() );
}
}
/**
* adds parameters to the request
* @param parameters "name-to-value" map of parameters; if a value is a file, the file is uploaded, otherwise it is stringified and sent in the request
* @throws IOException
*/
public void setParameters(Map parameters) throws IOException
{
if( parameters == null )
return;
for( Iterator i = parameters.entrySet().iterator(); i.hasNext(); )
{
Map.Entry entry = (Map.Entry)i.next();
setParameter( entry.getKey().toString(), entry.getValue() );
}
}
/**
* adds parameters to the request
* @param parameters array of parameter names and values (parameters[2*i] is a name, parameters[2*i + 1] is a value); if a value is a file, the file is uploaded, otherwise it is stringified and sent in the request
* @throws IOException
*/
public void setParameters(Object[] parameters) throws IOException
{
if( parameters == null )
return;
for( int i = 0; i < parameters.length - 1; i += 2 )
{
setParameter( parameters[i].toString(), parameters[i + 1] );
}
}
/**
* posts the requests to the server, with all the cookies and parameters that were added
* @return input stream with the server response
* @throws IOException
*/
public InputStream post() throws IOException
{
boundary();
writeln( "--" );
os.close();
return connection.getInputStream();
}
/**
* posts the requests to the server, with all the cookies and parameters that were added before (if any), and with parameters that are passed in the argument
* @param parameters request parameters
* @return input stream with the server response
* @throws IOException
* @see setParameters
*/
public InputStream post(Map parameters) throws IOException
{
setParameters( parameters );
return post();
}
/**
* posts the requests to the server, with all the cookies and parameters that were added before (if any), and with parameters that are passed in the argument
* @param parameters request parameters
* @return input stream with the server response
* @throws IOException
* @see setParameters
*/
public InputStream post(Object[] parameters) throws IOException
{
setParameters( parameters );
return post();
}
/**
* posts the requests to the server, with all the cookies and parameters that were added before (if any), and with cookies and parameters that are passed in the arguments
* @param cookies request cookies
* @param parameters request parameters
* @return input stream with the server response
* @throws IOException
* @see setParameters
* @see setCookies
*/
public InputStream post(Map cookies, Map parameters) throws IOException
{
setCookies( cookies );
setParameters( parameters );
return post();
}
/**
* posts the requests to the server, with all the cookies and parameters that were added before (if any), and with cookies and parameters that are passed in the arguments
* @param cookies request cookies
* @param parameters request parameters
* @return input stream with the server response
* @throws IOException
* @see setParameters
* @see setCookies
*/
public InputStream post(String[] cookies, Object[] parameters) throws IOException
{
setCookies( cookies );
setParameters( parameters );
return post();
}
/**
* post the POST request to the server, with the specified parameter
* @param name parameter name
* @param value parameter value
* @return input stream with the server response
* @throws IOException
* @see setParameter
*/
public InputStream post(String name, Object value) throws IOException
{
setParameter( name, value );
return post();
}
/**
* post the POST request to the server, with the specified parameters
* @param name1 first parameter name
* @param value1 first parameter value
* @param name2 second parameter name
* @param value2 second parameter value
* @return input stream with the server response
* @throws IOException
* @see setParameter
*/
public InputStream post(String name1, Object value1, String name2, Object value2)
throws IOException
{
setParameter( name1, value1 );
return post( name2, value2 );
}
/**
* post the POST request to the server, with the specified parameters
* @param name1 first parameter name
* @param value1 first parameter value
* @param name2 second parameter name
* @param value2 second parameter value
* @param name3 third parameter name
* @param value3 third parameter value
* @return input stream with the server response
* @throws IOException
* @see setParameter
*/
public InputStream post(String name1, Object value1, String name2, Object value2, String name3,
Object value3) throws IOException
{
setParameter( name1, value1 );
return post( name2, value2, name3, value3 );
}
/**
* post the POST request to the server, with the specified parameters
* @param name1 first parameter name
* @param value1 first parameter value
* @param name2 second parameter name
* @param value2 second parameter value
* @param name3 third parameter name
* @param value3 third parameter value
* @param name4 fourth parameter name
* @param value4 fourth parameter value
* @return input stream with the server response
* @throws IOException
* @see setParameter
*/
public InputStream post(String name1, Object value1, String name2, Object value2, String name3,
Object value3, String name4, Object value4) throws IOException
{
setParameter( name1, value1 );
return post( name2, value2, name3, value3, name4, value4 );
}
/**
* posts a new request to specified URL, with parameters that are passed in the argument
* @param parameters request parameters
* @return input stream with the server response
* @throws IOException
* @see setParameters
*/
public static InputStream post(URL url, Map parameters) throws IOException
{
return new ClientHttpRequest( url ).post( parameters );
}
/**
* posts a new request to specified URL, with parameters that are passed in the argument
* @param parameters request parameters
* @return input stream with the server response
* @throws IOException
* @see setParameters
*/
public static InputStream post(URL url, Object[] parameters) throws IOException
{
return new ClientHttpRequest( url ).post( parameters );
}
/**
* posts a new request to specified URL, with cookies and parameters that are passed in the argument
* @param cookies request cookies
* @param parameters request parameters
* @return input stream with the server response
* @throws IOException
* @see setCookies
* @see setParameters
*/
public static InputStream post(URL url, Map cookies, Map parameters) throws IOException
{
return new ClientHttpRequest( url ).post( cookies, parameters );
}
/**
* posts a new request to specified URL, with cookies and parameters that are passed in the argument
* @param cookies request cookies
* @param parameters request parameters
* @return input stream with the server response
* @throws IOException
* @see setCookies
* @see setParameters
*/
public static InputStream post(URL url, String[] cookies, Object[] parameters) throws IOException
{
return new ClientHttpRequest( url ).post( cookies, parameters );
}
/**
* post the POST request specified URL, with the specified parameter
* @param name parameter name
* @param value parameter value
* @return input stream with the server response
* @throws IOException
* @see setParameter
*/
public static InputStream post(URL url, String name1, Object value1) throws IOException
{
return new ClientHttpRequest( url ).post( name1, value1 );
}
/**
* post the POST request to specified URL, with the specified parameters
* @param name1 first parameter name
* @param value1 first parameter value
* @param name2 second parameter name
* @param value2 second parameter value
* @return input stream with the server response
* @throws IOException
* @see setParameter
*/
public static InputStream post(URL url, String name1, Object value1, String name2, Object value2)
throws IOException
{
return new ClientHttpRequest( url ).post( name1, value1, name2, value2 );
}
/**
* post the POST request to specified URL, with the specified parameters
* @param name1 first parameter name
* @param value1 first parameter value
* @param name2 second parameter name
* @param value2 second parameter value
* @param name3 third parameter name
* @param value3 third parameter value
* @return input stream with the server response
* @throws IOException
* @see setParameter
*/
public static InputStream post(URL url, String name1, Object value1, String name2, Object value2,
String name3, Object value3) throws IOException
{
return new ClientHttpRequest( url ).post( name1, value1, name2, value2, name3, value3 );
}
/**
* post the POST request to specified URL, with the specified parameters
* @param name1 first parameter name
* @param value1 first parameter value
* @param name2 second parameter name
* @param value2 second parameter value
* @param name3 third parameter name
* @param value3 third parameter value
* @param name4 fourth parameter name
* @param value4 fourth parameter value
* @return input stream with the server response
* @throws IOException
* @see setParameter
*/
public static InputStream post(URL url, String name1, Object value1, String name2, Object value2,
String name3, Object value3, String name4, Object value4) throws IOException
{
return new ClientHttpRequest( url ).post( name1, value1, name2, value2, name3, value3, name4,
value4 );
}
}
|