Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Thursday, December 27, 2012

Hibernate CLOB to String Conversion AliasToEntityMapResultTransformer not working

Hibernate Clob conversion is little tricky especially when we use with JPA. There is no predefined Transformer for this in Hibernate due to some reason.
Code to retirive records as List of map
org.hibernate.Query query=((Session) em.getDelegate() )
  .createSQLQuery(sql);
query
  .setResultTransformer( AliasToEntityMapResultTransformer.INSTANCE);
List<Map<String,Object>> aliasToValueMapList=query.list();
return aliasToValueMapList; 
which will return non-blob and non clob type columns as it is. those are readable in the viewing end. but for Clob types it will store the object notation like org.hibernate.type.ClobType@2311
reason is AliasToEntityMapResultTransformer class does not have mechanism to convert clob to string as it may lead memory issue.
AliasToEntityMapResultTransformer.java
..{
.........
...

public Object transformTuple(Object[] tuple, String[] aliases) {
  Map result = new HashMap(tuple.length);
  for ( int i=0; i<tuple.length; i++ ) {
   String alias = aliases[i];
   if ( alias!=null ) {
    result.put( alias, tuple[i] );
   }
  }
  return result;
 } 
...
.........
..} 

Solution is we can write our own result transformer.
MyResultTransformer.java
package com.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.Clob;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.hibernate.transform.BasicTransformerAdapter;

public class MyResultTransformer extends BasicTransformerAdapter {

 public final static MyResultTransformer INSTANCE;
 static {
  INSTANCE = new MyResultTransformer();
 }

 private MyResultTransformer() {

 }
 private static final long serialVersionUID = 1L;

 @Override
 public Object transformTuple(Object[] tuple, String[] aliases) {
  Map<String, Object> map = new HashMap<String, Object>();
  for (int i = 0; i < aliases.length; i++) {
   Object t = tuple[i];
   if (t != null && t instanceof Clob) {
    Clob c = (Clob) tuple[i];
    try {
     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     IOUtils.copy(c.getAsciiStream(), bos);
     t = new String(bos.toByteArray());
    } catch (SQLException e) {
     e.printStackTrace();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
   map.put(aliases[i], t);
  }
  return map;
 }
}


now,

...
query
  .setResultTransformer( MyResultTransformer.INSTANCE);
...
will return list of maps with Clob types as Converted String.

Note: Considerable thing here is memory. ex. for 100 records if each record has 1mb of data in a clob type attribute, the total size is >100 mb

Thursday, October 20, 2011

Simple Reverse Geo-coding in Java using Google Map

The Java Class

package geo;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class MyGeo {
public static void main(String ar[]) throws Exception {
System.out.println(new MyGeo().getAddress("13.031067,80.239656"));
}
public String getAddress(String latlong){
String address = null;
String gURL = "http://maps.google.com/maps/api/geocode/xml?latlng=" + latlong + "&sensor=true";
try {
DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
DocumentBuilder db = df.newDocumentBuilder();
Document dom = db.parse(gURL);
Element docEl = dom.getDocumentElement();
NodeList nl = docEl.getElementsByTagName("result");
if (nl != null && nl.getLength() > 0){
address=((Element)nl.item(0)).getElementsByTagName("formatted_address").item(0).getTextContent();
for(int i=0;i<nl.getLength();i++){
String temp=((Element)nl.item(i)).getElementsByTagName("formatted_address").item(0).getTextContent();
}
}
} catch (Exception ex) {
address = "Err";
}
return address;
}
public String getAddress(String lat, String lon) {
return getAddress(lat+ "," + lon);
}
public String getAddress(double lat, double lon) {
return getAddress("" + lat, "" + lon);
}
}

Run
>java geo.MyGeo
Venkatanarayana Rd, CIT Nagar, Chennai, Tamil Nadu, India


Note: Google has some restriction in this web-service call like number of requests per day from one IP.
Ref: http://code.google.com/apis/maps/documentation/geocoding/#ReverseGeocoding

Friday, February 4, 2011

J2EE Web Application - Simple Single SignOn (SSO)

To have a common account (username-password) for various applications of an umbrella and to have authentication at a place to access all of the applications without the need to enter password for each is called Single Sing-on (SSO).


Here is a simple SSO implementation of web applications using JSP (would run any java web server).
Steps as follows:
  1. Create views for login and success login.jsp & success.jsp respectively for example.
  2. Write the action (as a servlet) login.do for example to handle and authenticate the request if the credentials are valid.
  3. Set a session attribute on success of login, username for example.
    session.setAttribute("username", userName);
  4. Create a jsp isLivingSession.jsp for example, which is going to act as javascript source and is the key part of our SSO.
login.jsp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Login</title>
</head>
<body>
<form action="login.do?c=<%=request.getParameter("c")%>">
<input name="username" type="text" />
<input name="password" type="text" />
<input type="submit" value="submit" />
</form>
</body>
</html>

login.do
.....
if(loginSuccess){
 session.setAttribute("username", userName);
 c=request.getParameter("c");
 if(c!=null && !c.trim().equals("")){

   response.sendRedirect(c);
   //user will 
be automatically redirected to the calling application or page.
  }
 else{
response.sendRedirect("success.jsp");}
}
.......

isLivingSession.jsp

<%=session.getAttribute("username")==null?"window.location.href='http://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"login.jsp?c='+unescape(window.location.href);":""%>

Add the following line in all web pages or a file which is included by all pages header of the application which should use SSO. This could be used in any server or application or platform.

<script type="text/javascript" src="yoursite.com/isLivingSession.jsp?ignore=currtimeinmilliseconds"></script> 

one more thing should be noted is the web application should support javascript, so add noscript tag in all web pages.

and thats it.. go and play.

Friday, July 16, 2010

Java/J2ee - Servlet Listener & Quartz Scheduler

Here the concepts of Servlet Listeners & schedulers are shown with example.

Brief Description:
  1. Servlet Listeners are loaded at the time of application deployment in web server.
  2. contextInitialized() & contextDestroyed() are the overloaded functions which are called at the time of application load and unload respectively.
  3. Schedulers are the threads which could be scheduled to run at a particular time.
  4. Job class is actually having the duty of the job in the
    execute() method
    .
  5. Defined Job could be assigned to a scheduler.
  6. CronExpression is an interesting one which is used to define the schedule interval for a particular scheduler.

I used this scheduler for scheduling some alerts in my First real time project "Telematics - ACRM" in my First company Defiance.
Code:
Note: We need to add quarts jars in the class path.

Servlet Listener Class

import java.text.ParseException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.log4j.Logger;
import org.quartz.CronExpression;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;

public class AlertServletListener implements ServletContextListener {
private SchedulerFactory sf = null;
private Scheduler sched = null;
private static transient Logger logger = Logger.getLogger(AlertServletListener.class);

@Override
public void contextDestroyed(final ServletContextEvent sce) {
try {
sched.shutdown(true); logger.info("AlertServer Shut Down");
} catch (final SchedulerException e) {
logger.info("Err @ AlertServer Shut Down " + e.getMessage());
}
}

@Override
public void contextInitialized(final ServletContextEvent sce) {
logger.info("AlertServer Starting");
try {
sf = new StdSchedulerFactory(); sched = sf.getScheduler(); final JobDetail job3 = new JobDetail("myJob3", "myJobGroup3", MessageProcessJob.class); final CronTrigger ct3 = new CronTrigger("myTrigger3", "myTriggerGroup3"); final CronExpression cexp3 = new CronExpression("1/35 * * * * ?"); ct3.setCronExpression(cexp3); sched.scheduleJob(job3, ct3); sched.start(); logger.info("AlertServer Started Up"); Thread.sleep(10000L);
} catch (final ParseException e) {
e.printStackTrace();
} catch (final SchedulerException e) {
e.printStackTrace();
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
}




Job Class


import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class DistanceAlertsJob implements Job {

/**
* logger logger
*/
private static transient Logger logger = Logger.getLogger(DistanceAlertsJob.class);

@Override
public void execute(final JobExecutionContext arg0) throws JobExecutionException {
logger.info("Distance Alert Job");
Sysytem.out.println("Hello");
}
}

web.xml (Add the listener entry in web.xml)
..... <listener>
<listener-class>
com.boss.pageflows.schedular.AlertServletListener
</listener-class>
</listener>
.....