I have some json I'm trying to return as part of a BasicHttpResponse.
A code snippit is below and I've annotated the resulting printouts.
I can print out the json in A and it looks good in 1. But when I print the entity at B I don't get any body in 2, though it does have the length. If I go into the debugger I see the data there.
If I change the content type and print the entity I can see that this change is reflected in 3 but again no actual String data.
I'm trying to push this data through a pipe and not getting the json body on a write is a bit of a problem.
My expectation is that when I add data to an entity and then print or write the entity using a HttpMessageWriter that the json would be shown/transferred. What am I missing? Is it unreasonable to expect the json to be printed on a toString?
BasicHttpResponse resp;
StringEntity entity = new StringEntity(json.toString(), "UTF-8");
A) logger.info("to str: " + json.toString());
B) logger.info("Entity: " + entity);
entity.setContentType("application/json; charset=UTF-8");
resp.setEntity(entity);
C) logger.info("set entity " + resp.getEntity());
1) to str: [{"id":"12","revision":"12","group":"12",
"remote":"12"}]
2) Entity: [Content-Type: text/plain;
charset=UTF-8,Content-Length: 81,Chunked: false]
3) set entity [Content-Type: application/json;
charset=UTF-8,Content-Length: 81,Chunked: false]
The toString() method from StringEntity will only print the data that you are getting, that is the correct behaviour.
The String given to StringEntity is saved as a byte array in the object.
This is the constructor for StringEntity:
/**
* Creates a StringEntity with the specified content and content type.
*
* #param string content to be used. Not {#code null}.
* #param contentType content type to be used. May be {#code null}, in which case the default
* MIME type {#link ContentType#TEXT_PLAIN} is assumed.
*
* #throws IllegalArgumentException if the string parameter is null
* #throws UnsupportedCharsetException Thrown when the named charset is not available in
* this instance of the Java virtual machine
* #since 4.2
*/
public StringEntity(final String string, final ContentType contentType) throws UnsupportedCharsetException {
super();
Args.notNull(string, "Source string");
Charset charset = contentType != null ? contentType.getCharset() : null;
if (charset == null) {
charset = HTTP.DEF_CONTENT_CHARSET;
}
this.content = string.getBytes(charset);
if (contentType != null) {
setContentType(contentType.toString());
}
}
If you want to print your entity as json again (for logging for example, since it's already being set in the response) you have to do something like:
logger.info("Entity: " + IOUtils.toString(entity.getContent()));
Using IOUtils.toString since entity.getContent() brings an InputStream object, you can use it as you wish.
Related
I want send a rest service call from Java using "GET" request.But i am getting the following error.I am able to use it in the postman but i am unable to send java application.
Exception in thread "main" java.lang.IllegalArgumentException: Key length not 128/192/256 bits.
at org.bouncycastle.crypto.engines.AESFastEngine.generateWorkingKey(Unknown Source)
at org.bouncycastle.crypto.engines.AESFastEngine.init(Unknown Source)
at org.bouncycastle.crypto.modes.CBCBlockCipher.init(Unknown Source)
at org.bouncycastle.crypto.macs.CMac.init(Unknown Source)
at com.rest.OAuth1.generateCmac(OAuth1.java:262)
at com.rest.OAuth1.generateSignature(OAuth1.java:180)
at com.rest.OAuth1.main(OAuth1.java:61)
This the my sample code
package com.rest;
// Java Libraries
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import javax.net.ssl.HttpsURLConnection;
// Apache Commons Libraries used for the Nonce & Base64
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.codec.binary.Base64;
// Bouncy Castle Libraries used for CMAC encryption
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.macs.CMac;
import org.bouncycastle.crypto.params.KeyParameter;
/**
* Very basic sample code that demonstrates how to make an OAuth 1.0 System-to-System
* request to the LearningStudio API
*/
public class OAuth1 {
public static void main(final String[] args) throws Exception
{
// Setup the variables necessary to create the OAuth 1.0 signature and make the request
String httpMethod = "GET";
String URI = "example.com/one/oauth1/userManagement/v5/users";
//String appID = "{applicationId}";
String consumerKey = "1234567-1234-4186-1234-1234567891011!mailid#example.com";
String secret = "12345678-1234-1234-1234-12345678";
String body = "{var:val}";
String signatureMethod = "HMAC-SHA1";
byte[] requestBody = null;
HttpsURLConnection request = null;
BufferedReader in = null;
URL url = new URL(String.format("https://api.example.com%s", URI));
// Set the Nonce and Timestamp parameters
String nonce = getNonce();
String timestamp = getTimestamp();
// Set the request body if making a POST or PUT request
if ("POST".equals(httpMethod) || "PUT".equals(httpMethod))
{
requestBody = body.getBytes("UTF-8");
}
// Create the OAuth parameter name/value pair
Map<String, String> oauthParams = new LinkedHashMap<String, String>();
oauthParams.put("oauth_consumer_key", consumerKey);
//oauthParams.put("application_id", appID);
oauthParams.put("oauth_signature_method", signatureMethod);
oauthParams.put("oauth_timestamp", timestamp);
oauthParams.put("oauth_nonce", nonce);
// Get the OAuth 1.0 Signature
String signature = generateSignature(httpMethod, url, oauthParams, requestBody, secret);
System.out.println(String.format("OAuth 1.0 Signature = %s", signature));
// Add the oauth_signature parameter to the set of OAuth Parameters
oauthParams.put("oauth_signature", signature);
// Generate a string of comma delimited: keyName="URL-encoded(value)" pairs
StringBuilder sb = new StringBuilder();
String delimiter = "";
for (String keyName : oauthParams.keySet()) {
sb.append(delimiter);
String value = oauthParams.get((String) keyName);
sb.append(keyName).append("=\"").append(URLEncoder.encode(value, "UTF-8")).append("\"");
delimiter=",";
}
String urlString = url.toString();
// omit the queryString from the url
int startOfQueryString = urlString.indexOf('?');
if(startOfQueryString != -1) {
urlString = urlString.substring(0,startOfQueryString);
}
// Build the X-Authorization request header
String xauth = String.format("OAuth realm=\"%s\",%s", urlString, sb.toString());
System.out.println(String.format("X-Authorization request header = %s", xauth));
try
{
// Setup the Request
request = (HttpsURLConnection)url.openConnection();
request.setRequestMethod(httpMethod);
request.addRequestProperty("X-Authorization", xauth);
// Set the request body if making a POST or PUT request
if ("POST".equals(httpMethod) || "PUT".equals(httpMethod))
{
request.setRequestProperty("Content-Length", "" + requestBody.length);
request.setDoOutput(true);
OutputStream postStream = request.getOutputStream();
postStream.write(requestBody, 0, requestBody.length);
postStream.close();
}
// Send Request & Get Response
InputStreamReader reader = new InputStreamReader(request.getInputStream());
in = new BufferedReader(reader);
// Get the response stream
String response = in.readLine();
System.out.println(String.format("Successful Response: \r\n%s", response));
} catch (IOException e )
{
// This exception will be raised if the serve didn't return 200 - OK
System.out.print(e.getMessage());
} finally
{
if (in != null) in.close();
if (request != null) request.disconnect();
}
}
/**
* Generates a random nonce
*
* #return A unique identifier for the request
*/
private static String getNonce()
{
return RandomStringUtils.randomAlphanumeric(32);
}
/**
* Generates an integer representing the number of seconds since the unix epoch using the
* date/time the request is issued
*
* #return A timestamp for the request
*/
private static String getTimestamp()
{
return Long.toString((System.currentTimeMillis() / 1000));
}
/**
* Generates an OAuth 1.0 signature
*
* #param httpMethod The HTTP method of the request
* #param URL The request URL
* #param oauthParams The associative set of signable oAuth parameters
* #param requestBody The serialized POST/PUT message body
* #param secret Alphanumeric string used to validate the identity of the education partner (Private Key)
*
* #return A string containing the Base64-encoded signature digest
*
* #throws UnsupportedEncodingException
*/
private static String generateSignature(
String httpMethod,
URL url,
Map<String, String> oauthParams,
byte[] requestBody,
String secret
) throws UnsupportedEncodingException
{
// Ensure the HTTP Method is upper-cased
httpMethod = httpMethod.toUpperCase();
// Construct the URL-encoded OAuth parameter portion of the signature base string
String encodedParams = normalizeParams(httpMethod, url, oauthParams, requestBody);
// URL-encode the relative URL
String encodedUri = URLEncoder.encode(url.getPath(), "UTF-8");
// Build the signature base string to be signed with the Consumer Secret
String baseString = String.format("%s&%s&%s", httpMethod, encodedUri, encodedParams);
return generateCmac(secret, baseString);
}
/**
* Normalizes all OAuth signable parameters and url query parameters according to OAuth 1.0
*
* #param httpMethod The upper-cased HTTP method
* #param URL The request URL
* #param oauthParams The associative set of signable oAuth parameters
* #param requstBody The serialized POST/PUT message body
*
* #return A string containing normalized and encoded oAuth parameters
*
* #throws UnsupportedEncodingException
*/
private static String normalizeParams(
String httpMethod,
URL url,
Map<String, String> oauthParams,
byte[] requestBody
) throws UnsupportedEncodingException
{
// Sort the parameters in lexicographical order, 1st by Key then by Value
Map<String, String> kvpParams = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
kvpParams.putAll(oauthParams);
// Place any query string parameters into a key value pair using equals ("=") to mark
// the key/value relationship and join each parameter with an ampersand ("&")
if (url.getQuery() != null)
{
for(String keyValue : url.getQuery().split("&"))
{
String[] p = keyValue.split("=");
kvpParams.put(p[0],p[1]);
}
}
// Include the body parameter if dealing with a POST or PUT request
if ("POST".equals(httpMethod) || "PUT".equals(httpMethod))
{
String body = Base64.encodeBase64String(requestBody).replaceAll("\r\n", "");
// url encode the body 2 times now before combining other params
body = URLEncoder.encode(body, "UTF-8");
body = URLEncoder.encode(body, "UTF-8");
kvpParams.put("body", body);
}
// separate the key and values with a "="
// separate the kvp with a "&"
StringBuilder combinedParams = new StringBuilder();
String delimiter="";
for(String key : kvpParams.keySet()) {
combinedParams.append(delimiter);
combinedParams.append(key);
combinedParams.append("=");
combinedParams.append(kvpParams.get(key));
delimiter="&";
}
// url encode the entire string again before returning
return URLEncoder.encode(combinedParams.toString(), "UTF-8");
}
/**
* Generates a Base64-encoded CMAC-AES digest
*
* #param key The secret key used to sign the data
* #param msg The data to be signed
*
* #return A CMAC-AES hash
*
* #throws UnsupportedEncodingException
*/
private static String generateCmac(String key, String msg)
throws UnsupportedEncodingException
{
byte[] keyBytes = key.getBytes("UTF-8");
byte[] data = msg.getBytes("UTF-8");
CMac macProvider = new CMac(new AESFastEngine());
macProvider.init(new KeyParameter(keyBytes));
macProvider.reset();
macProvider.update(data, 0, data.length);
byte[] output = new byte[macProvider.getMacSize()];
macProvider.doFinal(output, 0);
// Convert the CMAC to a Base64 string and remove the new line the Base64 library adds
String cmac = Base64.encodeBase64String(output).replaceAll("\r\n", "");
return cmac;
}
}
Is there any thing else which i am missing.
Also if i need to do POST request i need to add json data in the body tag directly?
EDIT: Is this really your key? maybe you changed the secret key to another size for not posting the original key here. If so check if keyBytes.length really gives you 16,24 or 32
I really digged deep now... I can't find any error in any of your code.
Your key is 256 bits long:
byte[] keyBytes = "12345678-1234-1234-1234-12345678".getBytes("UTF-8");
int bits = keyBytes.length*8;
System.out.println(bits); //gives 256
So i checked the CMac.java and they basically just copy the key with System.arraycopyso there is no error there.
They check the key in https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java with
int keyLen = key.length;
if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0)
{
throw new IllegalArgumentException("Key length not 128/192/256 bits.");
}
And since key.length is equal to 32 and 100000 & 111 is obviously 0 I really don't see anything wrong.
Please try to use a key with only 16 characters and tell us if the error still applies. Maybe you should also check if you really use the latest version of org.bouncycastle.crypto
If this doesn't help try just key.getBytes() without the charset UTF-8 for once.
I have a string
"To=\"+911234567899\"&From=\"+9987654321\"&Body=\"Hen\""
which I need to convert into x-www-form-urlencoded format.
If I use URLEncoder.encode() in Java, the function is converting the string as
To%3D%22%2B911234567899%22%26From%3D%22%2B9987654321%22%26Body%3D%22Hen%22
but when I send the request from postman as x-www-form-urlencoded the request that gets send is
To=%22%2B911234567899%22&From=%22%2B9987654321%22&Body=%22Hen%22
Why this difference? Also I need to send the request as it's exactly the same in postman (the second encoded string) then only I'm getting the response back. How can I encode my string in second format?
You probably double encoded your strings. Perhaps you shouldn't encode your query string yourself, and let URLEncoder do the work for you.
Here is an example, assume I have keys and values in a hashmap this.params.
this.params.put(key, URLEncoder.encode(value.toString(), "UTF-8")); // set the key/value
StringBuilder param = new StringBuilder("");
for (Map.Entry<String, Object> item : this.params.entrySet()) {
if (param.toString().length() != 0) {
param.append('&');
}
param.append(item.getKey());
param.append('=');
param.append(item.getValue().toString());
}
Now param.toString() will be properly encoded. Use it with url + "?" + param.toString()
How do I pass json as a query parameter on Rest Post web service in java
For example:
https://testvpa.net/WebService/ViALoggingRestWS/ViALoggingService.svc/StartCall?parameter={"machineName":"KK-IVR01","appName":"KKApp","startTime":"2018-02-06T21:38:32","portID":"01","ani":"9189280000","dnis":"8559281111","ctiCallID":"01"}
I am trying something like this:
....
try{
JSONObject obj = new JSONObject();
obj.put("machineName",machineName);
obj.put("appName", appName);
obj.put("startTime", formattedCurrentDate);
obj.put("portID",portID);
obj.put("ani",ani);
obj.put("dnis", dnis);
obj.put("ctiCallID", ctiCallID);
String strobj = obj.toString();
String uri = wsUri+"/StartCall?";
HttpClient client = new HttpClient();
client.getParams().setConnectionManagerTimeout(1300);
client.getParams().setSoTimeout(13000);
PostMethod method = new PostMethod(uri);
method.addRequestHeader("Content-Type", "application/x-www-form-urlencoded");
method.setQueryString("parameter="+strobj );
int statusCode = client.executeMethod(method);
byte[] responseBody = method.getResponseBody();
output = new String(responseBody);
}
....
But I am getting an "Invalid URI" at runtime. It doesn't seem to like the query parameter being a json string. I read somewhere about encoding the json string ... Do I somehow need to encode the json string?
If you are using POST request, you should pass the json object in the body of the request and not in the query params.
You can check this question for more details: Which characters make a URL invalid?
Generally speaking, the accepted characters in a URI are: [A-Z][a-z][0-9]-._~
The following characters are also allowed, but have special meaning in some parts of the URI: :/?#[]#!$&'()*+,;=
Every other character is not allowed and must be percent-encoded. The second set of characters should also be percent-encoded to avoid any parsing problems.
To percent encode a character you take its hex value (e.g. for the space character the hex value is 20) and prefix it with the % character. So John Doe becomes John%20Doe.
I'm reading the messages from an email account by using JavaMail 1.4.1 (I've upgraded to 1.4.5 version but with the same problem), but I'm having issues with the encoding of the content:
POP3Message pop3message;
...
Object contentObject = pop3message.getContent();
...
String contentType = pop3message.getContentType();
String content = contentObject.toString();
Some messages are read properly, but others have strange characters because of a not suitable encoding. I have realized it doesn't work for a specific content type.
It works well if the contentType is any of these:
text/plain; charset=ISO-8859-1
text/plain;
charset="iso-8859-1"
text/plain;
charset="ISO-8859-1";
format="flowed"
text/plain; charset=windows-1252
but it doesn't if it is:
text/plain;
charset="utf-8"
for this contentType (UTF-8 one) if I try to get the encoding (pop3message.getEncoding()) I get
quoted-printable
For the latter encoding I get for example in the debugger in the String value (in the same way as I see it in the database after persisting the object):
Ubicación (instead of Ubicación)
But if I open the email with the email client in a browser it can be read without any problem, and it's a normal message (no attachments, just text), so the message seems to be OK.
Any idea about how to solve this issue?
Thanks.
UPDATE
This is the piece of code I've added to try the function getUTF8Content() given by jlordo
POP3Message pop3message = (POP3Message) message;
String uid = pop3folder.getUID(message);
//START JUST FOR TESTING PURPOSES
if(uid.trim().equals("1401")){
Object utfContent = pop3message.getContent();
System.out.println(utfContent.getClass().getName()); // it is of type String
//System.out.println(utfContent); // if not commmented it prints the content of one of the emails I'm having problems with.
System.out.println(pop3message.getEncoding()); //prints: quoted-printable
System.out.println(pop3message.getContentType()); //prints: text/plain; charset="utf-8"
String utfContentString = getUTF8Content(utfContent); // throws java.lang.ClassCastException: java.lang.String cannot be cast to javax.mail.util.SharedByteArrayInputStream
System.out.println(utfContentString);
}
//END TEST CODE
How are you detecting that these messages have "strange characters"? Are you displaying the data somewhere? It's possible that whatever method you're using to display the data isn't handling Unicode characters properly.
The first step is to determine whether the problem is that you're getting the wrong characters, or that the correct characters are being displayed incorrectly. You can examine the Unicode values of each character in the data (e.g., in the String returned from the getContent method) to make sure each character has the correct Unicode value. If it does, the problem is with the method you're using to display the characters.
try this and let me know if it works:
if ( *check if utf 8 here* ) {
content = getUTF8Content(contentObject);
}
// TODO take care of UnsupportedEncodingException,
// IOException and ClassCastException
public static String getUTF8Content(Object contentObject) {
// possible ClassCastException
SharedByteArrayInputStream sbais = (SharedByteArrayInputStream) contentObject;
// possible UnsupportedEncodingException
InputStreamReader isr = new InputStreamReader(sbais, Charset.forName("UTF-8"));
int charsRead = 0;
StringBuilder content = new StringBuilder();
int bufferSize = 1024;
char[] buffer = new char[bufferSize];
// possible IOException
while ((charsRead = isr.read(buffer)) != -1) {
content.append(Arrays.copyOf(buffer, charsRead));
}
return content.toString();
}
BTW, is JavaMail 1.4.1 a requirement? Up to date version is 1.4.5.
What worked for me was that I called getContentType() and I would check if the String contains a "utf" in it (defining the charset used as one of UTF).
If yes, I would treat the content differently in this case.
private String encodeCorrectly(InputStream is) {
java.util.Scanner s = new java.util.Scanner(is, StandardCharsets.UTF_8.toString()).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
(a modification of a IS to String converter from this answer on SO)
The important part here is using the correct Charset. This solved the issue for me.
First of all you must add headers according to UTF-8 encoding this way:
...
MimeMessage msg = new MimeMessage(session);
msg.setHeader("Content-Type", "text/html; charset=UTF-8");
msg.setHeader("Content-Transfer-Encoding", "8bit");
msg.setFrom(new InternetAddress(doConversion(from)));
msg.setRecipients(javax.mail.Message.RecipientType.TO, address);
msg.setSubject(asunto, "UTF-8");
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setContent(text, "text/html; charset=UTF-8");
Multipart mp = new MimeMultipart();
mp.addBodyPart(mbp1);
...
But for 'from' header, i use the following method to convert characters:
public String doConversion(String original) {
if(original == null) return null;
String converted = original.replaceAll("á", "\u00c3\u00a1");
converted = converted.replaceAll("Á", "\u00c3\u0081");
converted = converted.replaceAll("é", "\u00c3\u00a9");
converted = converted.replaceAll("É", "\u00c3\u0089");
converted = converted.replaceAll("í", "\u00c3\u00ad");
converted = converted.replaceAll("Í", "\u00c3\u008d");
converted = converted.replaceAll("ó", "\u00c3\u00b3");
converted = converted.replaceAll("Ó", "\u00c3\u0093");
converted = converted.replaceAll("ú", "\u00c3\u00ba");
converted = converted.replaceAll("Ú", "\u00c3\u009a");
converted = converted.replaceAll("ñ", "\u00c3\u00b1");
converted = converted.replaceAll("Ñ", "\u00c3\u0091");
converted = converted.replaceAll("€", "\u00c2\u0080");
converted = converted.replaceAll("¿", "\u00c2\u00bf");
converted = converted.replaceAll("ª", "\u00c2\u00aa");
converted = converted.replaceAll("º", "\u00c2\u00b0");
return converted;
}
You can see the corresponding UTF-8 hex encoding in UTF at http://www.fileformat.info/info/charset/UTF-8/list.htm if you need to include some other characters.
I working on HTTP Traffic Data set which is composed of complete POST and GET request Like given below. I have written code in java that has separated each of these request and saved it as string element in array list. Now i am confused how to parse these raw HTTP request in java is there any method better than manual parsing?
GET http://localhost:8080/tienda1/imagenes/3.gif/ HTTP/1.1
User-Agent: Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.8 (like Gecko)
Pragma: no-cache
Cache-control: no-cache
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Encoding: x-gzip, x-deflate, gzip, deflate
Accept-Charset: utf-8, utf-8;q=0.5, *;q=0.5
Accept-Language: en
Host: localhost:8080
Cookie: JSESSIONID=FB018FFB06011CFABD60D8E8AD58CA21
Connection: close
Here is a General Http Request Parser For all Method types (GET, POST, etc.) for your convinience:
package util.dpi.capture;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Hashtable;
/**
* Class for HTTP request parsing as defined by RFC 2612:
*
* Request = Request-Line ; Section 5.1 (( general-header ; Section 4.5 |
* request-header ; Section 5.3 | entity-header ) CRLF) ; Section 7.1 CRLF [
* message-body ] ; Section 4.3
*
* #author izelaya
*
*/
public class HttpRequestParser {
private String _requestLine;
private Hashtable<String, String> _requestHeaders;
private StringBuffer _messagetBody;
public HttpRequestParser() {
_requestHeaders = new Hashtable<String, String>();
_messagetBody = new StringBuffer();
}
/**
* Parse and HTTP request.
*
* #param request
* String holding http request.
* #throws IOException
* If an I/O error occurs reading the input stream.
* #throws HttpFormatException
* If HTTP Request is malformed
*/
public void parseRequest(String request) throws IOException, HttpFormatException {
BufferedReader reader = new BufferedReader(new StringReader(request));
setRequestLine(reader.readLine()); // Request-Line ; Section 5.1
String header = reader.readLine();
while (header.length() > 0) {
appendHeaderParameter(header);
header = reader.readLine();
}
String bodyLine = reader.readLine();
while (bodyLine != null) {
appendMessageBody(bodyLine);
bodyLine = reader.readLine();
}
}
/**
*
* 5.1 Request-Line The Request-Line begins with a method token, followed by
* the Request-URI and the protocol version, and ending with CRLF. The
* elements are separated by SP characters. No CR or LF is allowed except in
* the final CRLF sequence.
*
* #return String with Request-Line
*/
public String getRequestLine() {
return _requestLine;
}
private void setRequestLine(String requestLine) throws HttpFormatException {
if (requestLine == null || requestLine.length() == 0) {
throw new HttpFormatException("Invalid Request-Line: " + requestLine);
}
_requestLine = requestLine;
}
private void appendHeaderParameter(String header) throws HttpFormatException {
int idx = header.indexOf(":");
if (idx == -1) {
throw new HttpFormatException("Invalid Header Parameter: " + header);
}
_requestHeaders.put(header.substring(0, idx), header.substring(idx + 1, header.length()));
}
/**
* The message-body (if any) of an HTTP message is used to carry the
* entity-body associated with the request or response. The message-body
* differs from the entity-body only when a transfer-coding has been
* applied, as indicated by the Transfer-Encoding header field (section
* 14.41).
* #return String with message-body
*/
public String getMessageBody() {
return _messagetBody.toString();
}
private void appendMessageBody(String bodyLine) {
_messagetBody.append(bodyLine).append("\r\n");
}
/**
* For list of available headers refer to sections: 4.5, 5.3, 7.1 of RFC 2616
* #param headerName Name of header
* #return String with the value of the header or null if not found.
*/
public String getHeaderParam(String headerName){
return _requestHeaders.get(headerName);
}
}
I [am] working on [an] HTTP Traffic Data set which is composed of complete POST and GET request[s]
So you want to parse a file or list that contains multiple HTTP requests. What data do you want to extract? Anyway here is a Java HTTP parsing class, which can read the method, version and URI used in the request-line, and that reads all headers into a Hashtable.
You can use that one or write one yourself if you feel like reinventing the wheel. Take a look at the RFC to see what a request looks like in order to parse it correctly:
Request = Request-Line ; Section 5.1
*(( general-header ; Section 4.5
| request-header ; Section 5.3
| entity-header ) CRLF) ; Section 7.1
CRLF
[ message-body ] ; Section 4.3
If you just want to send the raw request as it is, it's very easy, just send the actual String using a TCP socket!
Something like this:
Socket socket = new Socket(host, port);
BufferedWriter out = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream(), "UTF8"));
for (String line : getContents(request)) {
System.out.println(line);
out.write(line + "\r\n");
}
out.write("\r\n");
out.flush();
See this blog post by JoeJag for the full code.
UPDATE
I started a project, RawHTTP to provide HTTP parsers for request, responses, headers etc... it turned out so good that it makes it quite easy to write HTTP servers and clients on top of it. Check it out if you're looking for something lowl level.