JAVA SERVLET - Requested URI

{ Posted on 5:00 PM by Coveted }
I recently had an issue dealing with a Java Servlet. The Java Servlet was configured to handle errors via the web.xml file using the Error Pages configuration XML elements. This worked just fine as I've been able to handle a variety of errors. From 404 errors to 503, allowing me to serve up any message i want as the response to the request. Weather it be a web browser or server application.
But the one problem i had was trying to obtain the correct value of the URI that was requested. You would think that calling the method "getRequestURI()" of the HttpServletRequest would do the trick... But not so....

//Using the full class name for reference only,
//the parameter name should be used instead
String uri = HttpServletRequest.getRequestURI();
System.out.println("URI: " + uri);

Since the Java Servlet was set to deploy to the context root of the server. The above code resulted in this output: URI: /myServletExceptionHandler

This would be great if i made a request to "http://www.mydomain.com/myServletExceptionHandler"
But my test request was made to "http://www.mydomain.com/build/table" and that's what i was expecting to see once i printed the value of "getRequestURI()" But that wasn't the case.
So after some heavy digging around, i stumbled apon a solution that was embedded within the attributes of the request.
String uri = null;
uri = HttpServletRequest.getAttribute("javax.servlet.error.request_uri");
System.out.println("URI: " + uri);


The above code resulted in this output: URI: /build/table


This was great, since i had made my request to "http://www.mydomain.com/build/table" the code was outputting the correct results. But there's a catch here.... This only worked when there was an error thrown and handled by the Servlet, but if no error was thrown, the output was: URI: (blank no output shown). The value remained null, and would throw an error if processed further. So here comes an if statement and the use of the "getRequestedURI()" method.

String uri = null;
uri = HttpServletRequest.getAttribute("javax.servlet.error.request_uri");
if (uri == null) {
//in case there's no URI given
uri = HttpServletRequest.getRequestURI();
}
System.out.println("URI: " + uri);

This did the trick, if an error was thrown the Original requested URI would be pulled from the attributes of the HttpServletRequest class, extracting the "javax.servlet.error.request_uri" value. If the String Object remains null, and attempt is made to retrive a value from the "getRequestedURI()" method of the HttpServletRequest class... And were done....

JAVA SERVLET - Getting the SOAPACTION from a SOAPMESSAGE posted to a Java servlet.

{ Posted on 12:55 PM by Coveted }

I've been working on a project that utilizes a Java servlet to accept POST via the doPost method of a class that extends the HttpServlet class.


In order to get the SOAPACTION from a SOAPMESSAGE POST, you will need to parse the MimeHeaders of the request (HttpServletRequest).


NOTE: I purposely left out some imports and other methods not need for this post to shorten the content length. Error handling and such forth is being left out for simplicity of the post.
First you will need a MimeHeaders Object to store the Request.



import saaj.SaajUtils
import javax.xml.soap.MimeHeader;
import import javax.xml.soap.MimeHeaders;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

protected void
doPost(HttpServletRequest req,
HttpServletResponse resp) throws ServletException, IOException {
try
MimeHeader mh = SaajUtils.getHeaders(req);

}catch (Exception ex) {
Logger.getLogger("Exception").log(Level.SEVERE, null, ex);
//Return a server error if things go wrong to simplify things for the post
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}

I used the SaajUtils class, which included methods to parse MimeHeaders, i will include that class later in this post.


Next we will use a method to parse the MimeHeader returned and extract the SOAPACTION from the MimeHeaders. This method will accept an Iterator Object to loop over. In order to get the Iterator Object, you will need to call the "getAllHeaders()" of the MimeHeader returned by the SaajUtils class method call.




private String getSoapAction(Iterator allHeaders) {
String soapAction = null;
while (allHeaders.hasNext()) {
MimeHeader header = (MimeHeader) allHeaders.next();
if (header.getName().equalsIgnoreCase("soapaction")) {
soapAction = header.getValue().replaceAll("\"", "");
}
}
return soapAction;
}




//Now add these lines
Iterator iterator = mh.getAllHeaders();
String soapAction = getSoapAction(iterator);




//Here's our SaajUtils class used

package saaj;

import java.io.ByteArrayInputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.StringTokenizer;
import javax.activation.DataHandler;
import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MimeHeader;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

/**
*
* @author Aalford
*/
public class SaajUtils {

/**
* extract the MIME header information from within the HTTP Request
* @param req the http request
* @return MimeHeaders as defined within the SAAJ API
*/
public static MimeHeaders getHeaders(HttpServletRequest req) {
Enumeration enumeration = req.getHeaderNames();
MimeHeaders headers = new MimeHeaders();

while( enumeration.hasMoreElements() ) {
String headerName = (String) enumeration.nextElement();
String headerValue = req.getHeader( headerName );

StringTokenizer values = new StringTokenizer( headerValue, ",");
while (values.hasMoreTokens()) {
headers.addHeader(headerName, values.nextToken().trim());
}
}
return headers;
}

/**
* stuff the MIME headers into the HTTP response
* @param headers the SAAJ MIME headers
* @param res the Http servlet response
*/
public static void putHeaders(MimeHeaders headers, HttpServletResponse res) {
for (Iterator it = headers.getAllHeaders(); it.hasNext();) {
MimeHeader header = (MimeHeader) it.next();
String[] values = headers.getHeader(header.getName());
if (values.length == 1) {
res.setHeader(header.getName(), header.getValue());
} else {
StringBuffer concat = new StringBuffer();
for (int i = 0; i < values.length; i++) { if (i != 0) { concat.append(','); } concat.append(values[i]); } res.setHeader(header.getName(), concat.toString()); } } } public static void attachBytes(SOAPMessage soapMessage, byte[] theBytes, String contentType) throws SOAPException { AttachmentPart attachment = soapMessage.createAttachmentPart(); attachment.setContent(new ByteArrayInputStream(theBytes), contentType); soapMessage.addAttachmentPart(attachment); } public static void attachUrlContents(SOAPMessage soapMessage, String urlLocation, String contentType) throws SOAPException, MalformedURLException { URL url = new URL(urlLocation); AttachmentPart attachment = soapMessage.createAttachmentPart(new DataHandler(url)); attachment.setContentType(contentType); soapMessage.addAttachmentPart(attachment); } public static String getAttachmentReport(SOAPMessage soapMessage) throws SOAPException { int numOfAttachments = soapMessage.countAttachments(); Iterator attachments = soapMessage.getAttachments(); StringBuffer buf = new StringBuffer("Number of attachments: "); buf.append(numOfAttachments); while (attachments.hasNext()) { buf.append("\n--------------------------------------------\n"); AttachmentPart attachment = (AttachmentPart) attachments.next(); buf.append("\nContent Location: " + attachment.getContentLocation()); buf.append("\nContent Id: " + attachment.getContentId()); buf.append("\nContent Size: " + attachment.getSize()); buf.append("\nContent Type: " + attachment.getContentType()); } return buf.toString(); } }


And that sum's it up



import saaj.SaajUtils
import javax.xml.soap.MimeHeader;
import import javax.xml.soap.MimeHeaders;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {

MimeHeader mh = SaajUtils.getHeaders(req);
Iterator iterator = mh.getAllHeaders();
String soapAction = getSoapAction(iterator);
String message = "SOAPACTION: " + soapAction;
//Set the return status to SuccessFul HTTP/1.1 200 OK
resp.setContentType("text/xml");

//Using a method of the "HttpServletResponse" class
resp.setStatus(resp.SC_OK);


//Finally output the information to the browser

out.println("");
out.println(message);
out.println("");


}catch (Exception ex) {
Logger.getLogger("Exception").log(Level.SEVERE, null, ex);
//Return a server error if things go wrong to simplify things for the post
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}

private String getSoapAction(Iterator allHeaders) {
String soapAction = null;
while (allHeaders.hasNext()) {
MimeHeader header = (MimeHeader) allHeaders.next();
if (header.getName().equalsIgnoreCase("soapaction")) {
soapAction = header.getValue().replaceAll("\"", "");
}

}
return soapAction;
}

JAVA SERVLET - Getting the Client Requestor IP Address and or Host name

{ Posted on 12:25 PM by Coveted }


This is fairly simple to do, yet few know how easy it is.

The "HttpServletRequest" class has two methods that work to your advantage, as they do exactly what they specify by name.

1. getRemoteAddr() - Returns a String Object of the requesting server IP Address
2. getRemoteHost() - Returns a String Object of the requesting server HOST NAME

for example, the method below responds to POST made against the HOST server. If i wanted to print the IP Address and Host name of the requester. The code would be such.



protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {

//We will need a PrintWriter in-order to print information back to the browser without flushing an OutputStream.
PrintWriter out = resp.getWriter();


//Let's set the message String object variable with information to output.
String message = "The Requestor IP: " + req.getRemoteAddr() + " Requestor Host name: " + req.getRemoteHost();


//Set the return status to SuccessFul HTTP/1.1 200 OK

resp.setContentType("text/xml");

//Using a method of the "HttpServletResponse" class
resp.setStatus(resp.SC_OK);


//Finally output the information to the browser
out.println("");
out.println(message);
out.println("");


}

Simple and Clean