Wednesday, January 20, 2010

How to pass jsp:param in jsp:include and access from struts 2 tag

1. Include a jsp file in the first page by passing the parameters like "text" as follows:

first.jspx:
..
..
<jsp:include page="/WEB-INF/jsp/middle.jspx">
<jsp:param name="text" value="Good Morning!!!" />
</jsp:include>
..
..

2. middle.jspx
..
..
<jsp:include page="/WEB-INF/jsp/last.jspx">
<jsp:param name="text" value="${param.text}" />
</jsp:include>
..
..

3. last.jspx

..
..
<c:set var="text" value="${param.text}"/>

Your Passed Text is == <s:property value="%{#attr.text}"/>
..
..

Note:Unfortunately you can't use JSTL in Struts 2 tags anymore. The above solution is a work around by using JSTL to set the parameter into page scope.

Thursday, January 14, 2010

How to handle Clob type in iBatis

1. Create a type handler:

package com.demo.sqlmap.typehandler;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.SQLException;
import java.text.DateFormat;
import java.util.Date;

import com.demo.domain.BlobBean;
import com.ibatis.sqlmap.client.extensions.ParameterSetter;
import com.ibatis.sqlmap.client.extensions.ResultGetter;
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;


public class BlobTypeHandlerCallback implements TypeHandlerCallback {

private static final int BUFFER_SIZE = 3000;

/**
* @throws
* @see com.ibatis.sqlmap.client.extensions.TypeHandlerCallback#getResult(com.ibatis.sqlmap.client.extensions.ResultGetter)
*/
public Object getResult(ResultGetter getter) throws SQLException {
Blob blob = null;
String fileName = null;
InputStream inStream = null;
FileOutputStream outStream = null;
try {
blob = getter.getBlob();
File blobFile= File.createTempFile("mytmp", ".tmp", getTmpFileDirectory());
outStream = new FileOutputStream(blobFile);
inStream = blob.getBinaryStream();

int length = -1;
byte[] buffer = new byte[BUFFER_SIZE];

// Write to file
while ((length = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, length);
outStream.flush();
}
if (inStream != null)
inStream.close();
if (outStream != null)
outStream.close();

return new BlobBean(new FileInputStream(blobFile));
}

catch (Exception ex) {
throw new SQLException("Unable to export to file: " + fileName);
} finally {
inStream = null;
outStream = null;
}

}

/**
* @see com.ibatis.sqlmap.client.extensions.TypeHandlerCallback#setParameter(com.ibatis.sqlmap.client.extensions.ParameterSetter,
* java.lang.Object)
*/
public void setParameter(ParameterSetter setter, Object parameter) throws SQLException {
try {
if (parameter != null && parameter instanceof ChobBlob) {
InputStream is = ((BlobBean) parameter).getInputStream();
File file = ((BlobBean) parameter).getUploadedFile();
if (is != null)
setter.setBinaryStream(is, (int) file.length());
}
} catch (Exception ex) {
ex.printStackTrace();
throw new SQLException("Error in passing the inputstream " + ex.getMessage());
}
}

/**
* @see com.ibatis.sqlmap.client.extensions.TypeHandlerCallback#valueOf(java.lang.String)
*/
public Object valueOf(String s) {
return s;

}

/**
* Generate a random FileName
*/
public static synchronized final String constructFileName() {
Date date = new Date();
return "BLOB_T" + date.getTime() + "T-"+DateFormat.getTimeInstance().format(date).replace(":", "-")
+ Math.random();
}

/**
* Method to get tmp file Directory.
*
* @return
*/
protected File getTmpFileDirectory() {
String tempDir = System.getProperty("java.io.tmpdir");
File fileUploadDir = new File(tempDir + File.separator + "fileupload");
if (!fileUploadDir.exists())
fileUploadDir.mkdirs();
return fileUploadDir;
}

}

2. Create a Blob Class to hold the binary data:
package com.demo.domain;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class BlobBean{

/** Reference to the underlying Input stream. */
private InputStream inputStream;

/** Reference to the file */
private File uploadedFile;

/**
* @return the uploadedFile
*/
public File getUploadedFile() {
return uploadedFile;
}

/**
* @param uploadedFile
* the uploadedFile to set
*/
public void setUploadedFile(File uploadedFile) {
this.uploadedFile = uploadedFile;
}

/** No Args Constructor. */
public BlobBean() {

}

/**
* Constructor.
*
* @param inputStream
*/
public BlobBean(InputStream inputStream) {
this.inputStream = inputStream;
}

/**
* Constructor. Initialize inputStream instance variable from the given
* Path.
*
* @param inputStream
*/
public BlobBean(String path) throws IOException {
File f = new File(path);
initalize(f);

}

/**
* Constructor. Initialize inputStream instance variable from the given
* Path.
*
* @param inputStream
*/
public BlobBean(File file) throws IOException {
initalize(file);

}

/**
* Initlalize file to contents
*
* @param f
* @throws IOException
*/
private void initalize(File f) throws IOException {
this.uploadedFile = f;
InputStream is = null;
is = new FileInputStream(f);
this.inputStream = is;
}

/**
* @return the inputStream
*/
public final InputStream getInputStream() {
return inputStream;
}

/**
* @param inputStream
* the inputStream to set
*/
public final void setInputStream(final InputStream inputStream) {
this.inputStream = inputStream;
}
}

3. Create a Bean to hold the binary data:

package com.demo.domain;

import java.util.Date;

import com.demo.domain.BlobBean;

public class FileUpload {

private Long id = ApprovableExtendedBusinessObject.UNSAVED_VALUE;

private BlobBean binaryData;

private Date fileUploadDate;

/**
* @return the fileUploadDate
*/
public Date getFileUploadDate() {
return fileUploadDate;
}


/**
* @param fileUploadDate the fileUploadDate to set
*/
public void setFileUploadDate(Date fileUploadDate) {
this.fileUploadDate = fileUploadDate;
}

/**
* @return the id
*/
public Long getId() {
return id;
}

/**
* @param id
* the id to set
*/
public void setId(Long id) {
this.id = id;
}

/**
* @return the binaryData
*/
public BlobBean getBinaryData() {
return binaryData;
}

/**
* @param binaryData
* the binaryData to set
*/
public void setBinaryData(BlobBean binaryData) {
this.binaryData = binaryData;
}
}

4. Create a DAO implementation class to deal with database


package com.demo.fileupload.dao.impl;


import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.demo.domain.FileUpload;
import com.demo.fileupload.dao.FileUploadDao;

// Note FileUploadDao must be defined with the necessary methods

public class FileUploadDaoImpl extends SqlMapClientDaoSupport implements FileUploadDao {

public FileUpload download(Long id) throws PersistenceLayerException {
FileUpload fileUpload = (FileUpload) getSqlMapClientTemplate().queryForObject(
"commons.fileupload.download", id.longValue());
return fileUpload;

}

public Long upload(FileUpload fileUpload) throws PersistenceLayerException {
getSqlMapClientTemplate().insert("commons.fileupload.upload", fileUpload);
return fileUpload.getId();

}
}

5. Create a SQL-MAP file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="commons.fileupload">

<typeAlias alias="blobTypeHandlerCallback" type="com.demo.sqlmap.typehandler.BlobTypeHandlerCallback"/>

<resultMap class="com.demo.domain.FileUpload" id="FileUploadMap">
<result property="id" column="ID"/>
<result property="binaryData" column="FILECONTENT"
typeHandler="blobTypeHandlerCallback"/>
<result property="fileUploadDate" column="FILEUPLOADDATE"/>
</resultMap>

<insert id="upload" parameterClass="com.demo.domain.FileUpload">
<![CDATA[
insert into FILEUPLOAD (ID, FILECONTENT, FILEUPLOADDATE)
values(#id#, #binaryData,handler=blobTypeHandlerCallback#,sysdate)
]]>
</insert>

<select id="download" resultMap="FileUploadMap">
<![CDATA[
select ID, FILECONTENT, FILEUPLOADDATE
from FILEUPLOAD
where ID = #id#
]]>
</select>

</sqlMap>


6. Table Structure
Column Name ID Pk Null? Data Type

ID 1 1 N NUMBER (19)
FILECONTENT 2 Y BLOB
FILEUPLOADDATE3 Y TIMESTAMP(6)