HOWTO: stream response with struts 2 that works in IE6

Web browser
Image via Wikipedia

Sometimes I had to display a dinamically generated file to the browser without save it locally on the server where I produce it.

HTTP allows you all of this, but browsers implemented the feature in different ways, so here I will report a method for sending a stream of binary data to a browser that works for every browser, in particular IE6.

The environment I use for this example is:

The struts.xml fragment for the action that rertieves the bytes and send them to the browser is as follows:

<action name="getFile" class="my.app.ExportFileAction" method="getFile">
    <result type="stream" name="success">
        <param name="contentType">${mimeType}</param>
        <param name="inputName">exportStream</param>
        <param name="contentDisposition">attachment; filename=${fileName}</param>
    </result>
</action>

The getFile() method of the my.app.ExportFileAction class is as follows:

public String getFile() {
  try {
    exportStream = new ByteArrayInputStream(getFileContent());
    mimeType = "application/pdf"; // in this example I use PDF mime
    fileName = "ExportedFile.pdf"; // the name we want to be proposed in the Save as... dialog
  } catch (Exception e) {
    return ERROR;
  }
  return SUCCESS;
}

exportStream, mimeType and fileName are members of my JavaBean Action class, each of which must have its getter and setter:

 protected String mimeType;
 protected String fileName;
 protected InputStream exportStream;

getFileContent() will be the method that retrieves the bytes of your file to send to the browser; here I will report only the method signature:

 private byte[] getFileContent() {}

HOWTO: using multi column keys in MyBatis Sql maps

When you have to deal with a Third normal form (3NF) relational database, you almost always fall in two scenarios:

  • a DB with natural keys as the primary keys of your data
  • a DB with surrogate keys with auto generated integer identities or GUIDs
Said that I prefer to model with the “more normalized” first approach, this results in a more complicated way to query the DB with multiple condition ON clauses in Joins, more and best designed indexes to have good performance, higher skill to develop, maintain and query the DB.
With this approach you can however manage historical data (with the change of the date part of a composite key), you can easily implement inheritance and extension and so on.
Another issue to be aware of,  is that when you opt for the first approach you may have to deal with Object Relational libraries such as MyBatis(Net) I’m talking about here.
When you use MyBatis you can express your relation through the SELECT attribute in the RESULT tag of the RESULTMAP definition.
Suppose we have the following master/detail table definition:
MASTER(M_KEY1, M_KEY2, M_ATTR1, M_ATTR2)
DETAIL(D_KEY1, D_ATTR1, D_FK_M_KEY1, D_FK_M_KEY2)
And you have the following two mapping Classes:
class Master {
    string key1;
    string key2;
    string attr1;
    string attr2;
    List<Detail> details;
}
class Detail {
    string key1;
    string atttr1;
    Master master;
}
Then you can define two result maps:
<resultMaps>
  <resultMap id="masterResult" class="Master">
    <result property="key1" column="M_KEY1" />
    <result property="key2" column="M_KEY2" />
    <result property="attr1" column="M_ATTR1" />
    <result property="attr2" column="M_ATTR2" />
  </resultMap>
  <resultMap id="detailResult" class="Detail">
    <result property="key1" column="D_KEY1" />
    <result property="attr1" column="D_ATTR1" />
  </resultMap>
</resultMaps>
Now you should use the SELECT attribute of the RESULT tag to make MyBatis automatically load the detail list related to a master or a master related to a details and eventually use the LAZYLOAD attribute to defer the execution of the subquery.
The SELECT attribute is used in conjunction with a COLUMN attribute in which you can specify the column to use as the parameter for selection; in our case we have TWO columns, so how this affect the use of SELECT, COLUMN and PARAMETERCLASS?
The multi column mapping of SELECT subqueries is based on Maps/Dictionaries so the mechanism is to build a Map/Dictionary from more than one column to use as a parameter for another query; to the masterResult map we can add:
<result property="details" column="MAP_KEY1=M_KEY1,MAP_KEY2=M_KEY2" select="details.byMaster" />
And in the detailResult map we can similarly add:
<result property="master" column="MAP_KEY1=D_FK_M_KEY1,MAP_KEY2=D_FK_M_KEY2" select="master.byKey" />
The two select statements master.byKey and details.byMaster should be something like this:
<select id="master.byKey" resultMap="masterRes" { parameterClass="System.Collections.IDictionary" (for .NET) OR parameterClass="java.util.Map" (for Java) } >
  SELECT *
  FROM MASTER
  WHERE M_KEY1=#MAP_KEY1# AND M_KEY2=#MAP_KEY2#
</select>
<select id="details.byMaster" resultMap="detailRes" { parameterClass="System.Collections.IDictionary" (for .NET) OR parameterClass="java.util.Map" (for Java) } >
  SELECT *
  FROM DETAIL
  WHERE D_FK_M_KEY1=#MAP_KEY1# AND D_FK_M_KEY2=#MAP_KEY2#
</select>
And that’s it!
Hope some of you may find this helpful.

HOWTO: using ServingXML in a Maven project

ServingXML is a powerful library to transform data from one format to another format by using a XML resource to define the transformation.

ServingXML comes with a console app, and also documents an API for embedding the software in a standard Java or J2EE application.

Apache Maven logo.
Image via Wikipedia

So, I decided to use this library in an enterprise integration application where normally I use Apache Maven for the Lifecycle Management. In the public Maven repos I couldn’t find the ServingXML dependency so I built a POM by myself tring to find which dependencies of ServingXML are present on public Maven repos and which are not.

Firstly I downloaded the latest version of ServingXML and extracted it on a local directory.

I adjusted the build-extensions.xml file as follows to obtain a minimal version of the library:

<project basedir="." default="build.extensions">
  <target name="build.extensions">
    <ant antfile="build.xml" dir="servingxml-msv" target="${ext.target}"/>
    <ant antfile="build.xml" dir="servingxml-saxon" target="${ext.target}"/>
    <ant antfile="build.xml" dir="servingxmlx" target="${ext.target}"/>
  </target>
</project>

So I had in my target/servingxml directory the built binary with dependenies in the lib folder. I figured out that some jar was the result of a transitive dependency so I decided to add progressively the libraries to my project using the install goal and then build and run tests to see if it worked.

Finally I obtained this POM:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.servingxml</groupId>
  <artifactId>servingxml</artifactId>
  <version>1.1.2</version>
  <description>Artifactory auto generated POM</description>
<dependencies>
        <dependency>
           <groupId>net.sourceforge.saxon</groupId>
           <artifactId>saxon</artifactId>
           <version>9.1.0.8</version>
        </dependency>
        <dependency>
            <groupId>isorelax</groupId>
            <artifactId>isorelax</artifactId>
            <version>20030108</version>
        </dependency>
        <dependency>
            <groupId>com.sun.msv.datatype.xsd</groupId>
            <artifactId>xsdlib</artifactId>
            <version>2011.1</version>
        </dependency>
        <dependency>
            <groupId>com.servingxml</groupId>
            <artifactId>msv</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.servingxml</groupId>
            <artifactId>saxon</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.servingxml</groupId>
            <artifactId>x</artifactId>
            <version>1.1.2</version>
        </dependency>
    </dependencies>
</project>

This, properly uploaded in my Artifactory toghether with the deployment of all Ant generated jars, gave me the opportunity to build with Maven “minimal embedded ServingXML” applications within my organization.

HOWTO: using a java regex to match XML processing instructions

Some days ago, searching for a regex pattern to match a XML processing instruction, I found a nice tool that helped me to build one (increasingly often I’m so lazy that I don’t want to open a regex reference and build & test it myself, but I want to be spoon-fed…).

So, the nice tool is Regex Magic; nice interface to build and test regural expression strings…

Uh, and finally, the Java regex to match the XML PI I used is as follows:


"<\\?xml[^>?]+\\?>"

Cheers!