org.sandev.tools.HTTP
Class ServletInput

java.lang.Object
  extended by org.sandev.tools.HTTP.ServletInput
All Implemented Interfaces:
org.sandev.basics.util.UIRenderInput, org.sandev.basics.util.UIRenderOperand

public class ServletInput
extends java.lang.Object
implements org.sandev.basics.util.UIRenderInput

Provides access to the HttpServletRequest parameter map.

Under standard form submission, the content type of the request is

and HttpServletRequest.getParameterMap works just fine. However in the case where file upload is desired, the standard form encoding is overridden (by including enctype="multipart/form-data" in the form declaration) which changes the content type to and HttpServletRequest.getParameterMap provides nothing. What we want is for:

Here's how this works:

  1. The user is editing a form generated from a struct with a field called "filename". This becomes a filename prompt because the field is metatype uploadedimage, or because the form definition was manually transformed to type="file". The user selects a file to upload, and the contents are submitted back triggered by the enctype="multipart/form-data". The default rendering sets the encoding type if it finds a containing span of type uploadedimage/file.
  2. XHTMLSandUIServlet sets the SANDUploadDirectory request attribute to the value of UIFormAdaptorCallback.getInboundFilesDir(). In a typical approach, this is set to a relative path off the default runtime directory. In a production environment, this directory would be symlinked to a networked area with backup.
  3. XHTMLSandUIServlet also calls UIFormAdaptorCallback.setInboundFilesDir() so that uploaded filenames can be trapped and converted into their corresponding href in UIFormAdaptorCallback.filterDisplayText.

Files are uploaded without any type or size checking. Since this is for authorized users only, it didn't seem worth the extra work necessary on this pass. The next step would be to provide a setFileTypes(String[]) method to set the allowed MIME file types. That means extending the UIRenderInput interface with this declaration, and sourcing the values from the SandUI definition at runtime.


Field Summary
protected  java.util.Map paramMap
          Our map of the form parameters.
 
Constructor Summary
ServletInput()
           
 
Method Summary
protected  void addExistingParamsToMap(javax.servlet.http.HttpServletRequest req)
          The standard HttpServletRequest map is immutable, so we typically make a copy to pass additional useful information.
protected  void echoRequest(javax.servlet.http.HttpServletRequest req)
          Dump a copy of the incoming request.
protected  java.lang.String getAttributeValue(java.lang.String attrName, java.lang.String text)
          Given a string with an html attribute value in it, and the attribute name, return the value or null if not found.
protected  java.lang.String getBoundary(java.lang.String line)
          Given a content text type specification, return the boundary text.
 java.util.Map getInputParameters()
           
 void init(java.lang.Object req)
          The initialization object in this case is an HttpServletRequest
protected  java.lang.String readFileContents(javax.servlet.ServletInputStream in, java.lang.String boundary, java.lang.String filename, java.lang.String path)
          Read the contents into a new file, returning the new file name.
protected  java.lang.String readLine(javax.servlet.ServletInputStream in)
          Read a line of input from the input stream and return it minus the terminating CRLF.
protected  java.lang.String readParameterValue(javax.servlet.ServletInputStream in, java.lang.String boundary)
          Read a parameter value from the input stream.
protected  void readToContents(javax.servlet.ServletInputStream in)
          Read lines until we hit an empty line.
protected  java.lang.String readToLine(javax.servlet.ServletInputStream in, java.lang.String linePrefix)
          Read lines until reading one starting with the specified prefix.
protected  void uploadAndBuildMap(java.lang.String boundary, javax.servlet.http.HttpServletRequest req)
          Given a multipart form request, upload the file and reconstruct the parameter map.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

paramMap

protected java.util.Map paramMap
Our map of the form parameters.

Constructor Detail

ServletInput

public ServletInput()
Method Detail

init

public void init(java.lang.Object req)
The initialization object in this case is an HttpServletRequest

Specified by:
init in interface org.sandev.basics.util.UIRenderOperand

getInputParameters

public java.util.Map getInputParameters()
Specified by:
getInputParameters in interface org.sandev.basics.util.UIRenderInput

addExistingParamsToMap

protected void addExistingParamsToMap(javax.servlet.http.HttpServletRequest req)
The standard HttpServletRequest map is immutable, so we typically make a copy to pass additional useful information. This method adds the additional fields, and all of the fields originally in the request. Assumes paramMap is initialized.


echoRequest

protected void echoRequest(javax.servlet.http.HttpServletRequest req)
Dump a copy of the incoming request. The input gets copied on a byte-by-byte basis to ServletInputTest.out for use in debugging or other analysis.


getBoundary

protected java.lang.String getBoundary(java.lang.String line)
Given a content text type specification, return the boundary text. The given text looks something like:


readLine

protected java.lang.String readLine(javax.servlet.ServletInputStream in)
                             throws java.io.IOException
Read a line of input from the input stream and return it minus the terminating CRLF. Return null if nothing was read.

Throws:
java.io.IOException

readToLine

protected java.lang.String readToLine(javax.servlet.ServletInputStream in,
                                      java.lang.String linePrefix)
                               throws java.io.IOException
Read lines until reading one starting with the specified prefix. Return the prefixed line or null if end of stream.

Throws:
java.io.IOException

getAttributeValue

protected java.lang.String getAttributeValue(java.lang.String attrName,
                                             java.lang.String text)
Given a string with an html attribute value in it, and the attribute name, return the value or null if not found. So if asked for "name" from the text this method returns MyForm.form_action. If asked for "foo" from the same text, then this method returns null.

If the attribute is found, this method returns the interned string value, so the result can be safely used as a hash key.


readToContents

protected void readToContents(javax.servlet.ServletInputStream in)
                       throws java.io.IOException
Read lines until we hit an empty line. That empty line signals the start of contents.

Throws:
java.io.IOException

uploadAndBuildMap

protected void uploadAndBuildMap(java.lang.String boundary,
                                 javax.servlet.http.HttpServletRequest req)
Given a multipart form request, upload the file and reconstruct the parameter map.


readFileContents

protected java.lang.String readFileContents(javax.servlet.ServletInputStream in,
                                            java.lang.String boundary,
                                            java.lang.String filename,
                                            java.lang.String path)
                                     throws java.io.IOException
Read the contents into a new file, returning the new file name.

Throws:
java.io.IOException

readParameterValue

protected java.lang.String readParameterValue(javax.servlet.ServletInputStream in,
                                              java.lang.String boundary)
                                       throws java.io.IOException
Read a parameter value from the input stream. Leave the stream after reading the closing boundary.

Throws:
java.io.IOException