import java.awt.*;
import java.io.*;
import javax.imageio.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ExternalImageServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ExternalImageServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
int read = 0;
byte[] bytes = new byte[1024];
FileInputStream fis = null;
OutputStream os = null;
try {
File image = new File("C:/sample.jpg");
response.setContentType("image/jpg");
// If I add this, the browser will prompt me to Open or Save the file
//response.setHeader("Content-Disposition", "attachment;image=\"" + image + "\"");
fis = new FileInputStream(image);
os = response.getOutputStream();
while((read = fis.read(bytes)) != -1){
os.write(bytes,0,read);
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally {
os.flush();
os.close();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
Friday, April 23, 2010
A Servlet which sends back an image file
This is a servlet which sends back a image read from a File or a Database.You can map the servlet to a suitable URL in Web.xml
Thursday, April 22, 2010
A simple AJAX call with a Progress bar
This is a simple code sample for a REST based service call from a Script using a XMLHttpRequest. This also shows a way of displaying a status progress GIF file while the Async call is happening and make it disappear when the work is done.
(*This is a simple implementation with XHR-wanted to show bare-bones implementation, You can do this much better and simpler with JQuery)
This will show some status progress as shown in the figure below and the XML returned from the REST service will be displayed on the Text Area.
(*This is a simple implementation with XHR-wanted to show bare-bones implementation, You can do this much better and simpler with JQuery)
This will show some status progress as shown in the figure below and the XML returned from the REST service will be displayed on the Text Area.
<body class="mystyle">
<form name="myform">
<center> <P class="special"> Hello - this is my Web application, Welcome </P></center>
<br><br>
<textarea name="RestResponse" rows="8" cols="100"></textarea>
<br><br>
<div id="progress"></div>
<br><br>
<button id="RestServiceButton" type="button" onclick="rest_button()">
Call Rest Service</button>
<button id="ClearTextButton" type="button" onclick="clear_button()">
Clear Data</button>
<br>
<br>
<script type="text/javascript">
//show the progress bar - make it visible - use any progress bar gif file
function show_progressbar(id) {
replace_html(id,
'<img src="bigrotation2.gif" border="0" alt="Loading, please wait..." />');
}
//hide the progress bar - make it visible
function hide_progressbar(id) {
replace_html(id, "");
}
//function to set the innerhtml.
function replace_html(id, content) {
document.getElementById(id).innerHTML = content;
}
function clear_button()
{
document.myform.RestResponse.value="";
}
// button function for REST call
function rest_button()
{
// Going to use XMLHTTPRequest to make an AJAX call to the Rest Service
var xmlhttp = null;
if (window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest();
if ( typeof xmlhttp.overrideMimeType != 'undefined') {
xmlhttp.overrideMimeType('text/xml');
}
}
else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} else {
alert('Does your browser support AJAX?');
}
// Open and send the Request to the REST service
xmlhttp.open('GET', "http://localhost:8080/MyRestWSProject/RestServlet", true);
xmlhttp.send(null);
show_progressbar("progress");
// The Ready state would change from 0,1,2, 3 and 4.
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//alert ("This is the response from the server: " + xmlhttp.responseText);
hide_progressbar("progress");
document.myform.RestResponse.value="";
document.myform.RestResponse.value+=xmlhttp.responseText;
} else {
// Nothing to do, Just wait !!!
}
};
}
</script>
</form>
</body>
Monday, April 19, 2010
Right Granularity of SOA Web Services - An architecture decision
Now let us try to explain this concept by taking an example. Let us consider we are developing a Web Service to retrieve Employee Details. Employee has the following associated characteristics
1) Dependents (An Array of Persons)
2) Skills (An Array of Skills)
3) Peers (An Array of Employees)
4) Direct Reports (An Array of Employees)
So when designing the Web Service to retrieve the employee, you have multiple ways of designing the Web Service.
Fine grained Approach
The biggest advantage of this approach is that, there is great flexibility in what client wants to get from the Web Service. If a Client is interested in getting Only Employee Skills that can be accomplished very easily by calling the corresponding web method. The problem though is that if a Client wants to get the Entire details of the Employee, there has to be 5 calls made to the Web Service provider, which increases the amount of Network traffic. Each Network call made is costly and can also affect performance negatively.
Coarse grained approach
The Key advantage of this approach is that the Network Traffic is reduced as the number of calls is reduced. There are few disadvantages though; now the DTO has become bulky, which contributes to the amount of data sent on the Network. Further, the Client has lost the flexibility of deciding what should be sent back. One more problem is that Client might not want to know about the “Peers” Data, but the server takes time to fetch that information from the Database, which again slows down the Web Service. The Coarse grained approach makes use of the Façade design pattern.
Dynamic Determination
Some of the designs adopt a “dynamic approach” to determine the granularity. The Dynamic approach is an attempt to make the service more versatile. Consider the following scenario. Along with he empID parameter to the getEmployee(), we pass the following Key Value Pairs
fetchSkills – true
fetchDRs – false
fetchPeers – true
fetchDependents – false
The Server side code can read these inputs and determine what should be populated on the Employee DTO. This approach solves the problem of too many Services to call, and also optimizes size of the DTO. But there are certain pitfalls. One of the most important ones is that it tightly couples the Server side code to the structure of the Key value Pairs. Server side code is assuming the existence of certain predefined strings being passed in a Generic Data Structure. The sanctity of the Contract can be easily violated, as there is not much of information about the generic data structure when the contract is formed. Also this nullifies the validation capabilities based on compile time structures as a generic data structure is passed in the call.
Note: The dynamic granularity approach works very well with REST based Services due to the absence of the contract.
Designing Web Services with the correct granularity
Concept of granularity is not absolute. There is no objective way to quantify the granularity of a Service. Determining the right granularity is always an “it depends” question. Yet, this concept of granularity is incredibly important to the enterprise architect because it has a direct impact on two major goals of Service orientation: the composability of loosely-coupled Services, and the reusability of individual Services in different contexts. Before an architect can go about designing a Service Contract, they must first somehow come up with the requirements for that Service.
An architect has two general approaches to identifying Services: starting from the business-process or a business model and decomposing that into sub-processes or sub-models recursively until some condition is met by which it can’t be decomposed any further. Alternatively, an architect can start from the IT systems already implemented, expose Service interfaces from the APIs and access points that already exist, create Service Contracts on top of those interfaces, and then compose them together until the business process requirements are met. While top-down approaches are generally favored to achieve the “right” level of granularity, in reality, proper Service-oriented approaches combine both top-down and bottom-up in a continuous and iterative manner.
Friday, April 16, 2010
Simple and Runnable Code Samples for Java5 features
As I was working with a lot of Java 5 enhancements and had written some simple, runnable examples for demoing lot of the new features in Java 5, wanted to share the code samples for anyone who would like to use them to learn those features
Auto Boxing/Unboxing and the advanced for loop
package com.sreekanth.java5;
import java.util.ArrayList;
import java.util.Iterator;
public class TrialAutoBoxUnBox {
public static void main(String[] args) {
ArrayList myList= new ArrayList();
//Java 1.4you would have done myList.add (new Integer(0));
myList.add (0);
myList.add (1);
//Pre-JDK 5 for loop
for (Iterator i = myList.iterator(); i.hasNext(); )
{
//Java 1.4 you should cast the return to the Integer type
System.out.println(i.next());
}
//another for loop - Post Java-1.5
for (Integer num : myList)
{
System.out.println("i >>" + num);
}
}
}
Enumerated Types
package com.sreekanth.java5;
public class TrialEnumeratedType {
// create an enumerated type - Java 5
public enum MyTypes {CREATE, EDIT, DELETE, VIEW};
public static void main(String[] argv) {
// the enhanced for loop can easily iterate through the contents of the enumerated type
for (MyTypes type : MyTypes.values())
System.out.println(type);
}
}
Concurrency features - Executor
package com.sreekanth.java5;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.sreekanth.java5.util.TestRunnable;;
public class TrialExecutor {
public static void main(String[] args) {
// create multiple runnable
TestRunnable t1 = new TestRunnable("t1");
TestRunnable t2 = new TestRunnable("t2");
// Executor
ExecutorService executor = Executors.newFixedThreadPool(3);
// start threads and place in runnable state
executor.execute(t1);
executor.execute(t2);
// shutdown worker threads
executor.shutdown();
}
}
Runnable Class used by the Executor
package com.sreekanth.java5.util;
import java.util.Random;
public class TestRunnable implements Runnable {
private int sleepTime;
private String threadName;
private static Random randomMaker = new Random();
public TestRunnable(String name) {
threadName = name;
sleepTime = randomMaker.nextInt(5000);
}
public void run() {
try {
// The Java 5 printf function
System.out.printf("%s going to sleep for %d milliseconds.\n", threadName, sleepTime);
Thread.sleep(sleepTime);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s done sleeping\n", threadName);
}
}
Generics and collections
package com.sreekanth.java5;
import java.util.ArrayList;
import java.util.Iterator;
import com.sreekanth.java5.dto.TestDTO;
/**
* @author sreekanth
*
*/
public class TrialGenerics {
/**
* @param args
*/
public static void main(String[] args) {
//Declare a Generic Collection - Aids in the compile time checking of the type
ArrayList dtoList = new ArrayList();
TestDTO d1 = new TestDTO("sreekanth", "d1");
TestDTO d2 = new TestDTO("sreekanth", "d2");
TestDTO d3 = new TestDTO("sreekanth", "d3");
dtoList.add(d1);
dtoList.add(d2);
dtoList.add(d3);
TrialGenerics myTrial = new TrialGenerics();
myTrial.myHelperMethod(dtoList);
}
private void myHelperMethod (ArrayList mydtoList)
{
//Iterator iterator = mydtoList.iterator();
for (Iterator iter = mydtoList.iterator(); iter.hasNext(); )
{
// No need to cast any more !!!
TestDTO item = iter.next();
System.out.println(item.getName());
System.out.println(item.getType());
}
}
}
TestDTO class used by the above program
package com.sreekanth.java5.dto;
public class TestDTO {
String name;
String type;
public TestDTO(String name, String type) {
super();
this.name = name;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Static Imports
package com.sreekanth.java5;
import static java.lang.Math.*;
import static java.lang.System.out;
public class TrialStaticImport {
public static void main(String[] args) {
// No need for System..out
out.println("Hi this is a static import example");
}
}
Callable and Futures - Callable Class
package com.sreekanth.java5.util;
import java.util.concurrent.Callable;
public class TestCallable implements Callable
{
private String threadName;
@Override
public Long call() throws Exception {
long sum = 0;
//sums up some numbers
System.out.println("This is coming from " + this.threadName );
for (long i = 0; i <= 100; i++) {
sum += i;
}
System.out.println("This is the sum from the worker :" + this.threadName + "and the sum is :" + sum);
return sum;
}
public TestCallable(String name) {
threadName = name;
}
}
Use of Callable and Future in a Test Program
package com.sreekanth.java5;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Callable;
import com.sreekanth.java5.util.TestCallable;
/**
* @author sreekanth
*
*/
public class TrialFutureNCallable {
public static void main(String[] args) {
//thread pool of size 10
ExecutorService executor = Executors.newFixedThreadPool(10);
List> list = new ArrayList>();
for (int i = 0; i < 20000; i++) {
Callable worker = new TestCallable("t" + i);
Future submit = executor.submit(worker);
list.add(submit);
}
long sum = 0;
System.out.println(list.size());
// Now retrieve the result
for (Future future : list)
{
try {
sum += future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
System.out.println(sum);
}
}
Auto Boxing/Unboxing and the advanced for loop
package com.sreekanth.java5;
import java.util.ArrayList;
import java.util.Iterator;
public class TrialAutoBoxUnBox {
public static void main(String[] args) {
ArrayList
//Java 1.4you would have done myList.add (new Integer(0));
myList.add (0);
myList.add (1);
//Pre-JDK 5 for loop
for (Iterator
{
//Java 1.4 you should cast the return to the Integer type
System.out.println(i.next());
}
//another for loop - Post Java-1.5
for (Integer num : myList)
{
System.out.println("i >>" + num);
}
}
}
Enumerated Types
public class TrialEnumeratedType {
// create an enumerated type - Java 5
public enum MyTypes {CREATE, EDIT, DELETE, VIEW};
public static void main(String[] argv) {
// the enhanced for loop can easily iterate through the contents of the enumerated type
for (MyTypes type : MyTypes.values())
System.out.println(type);
}
}
Concurrency features - Executor
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.sreekanth.java5.util.TestRunnable;;
public class TrialExecutor {
public static void main(String[] args) {
// create multiple runnable
TestRunnable t1 = new TestRunnable("t1");
TestRunnable t2 = new TestRunnable("t2");
// Executor
ExecutorService executor = Executors.newFixedThreadPool(3);
// start threads and place in runnable state
executor.execute(t1);
executor.execute(t2);
// shutdown worker threads
executor.shutdown();
}
}
Runnable Class used by the Executor
package com.sreekanth.java5.util;
import java.util.Random;
public class TestRunnable implements Runnable {
private int sleepTime;
private String threadName;
private static Random randomMaker = new Random();
public TestRunnable(String name) {
threadName = name;
sleepTime = randomMaker.nextInt(5000);
}
public void run() {
try {
// The Java 5 printf function
System.out.printf("%s going to sleep for %d milliseconds.\n", threadName, sleepTime);
Thread.sleep(sleepTime);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.printf("%s done sleeping\n", threadName);
}
}
Generics and collections
package com.sreekanth.java5;
import java.util.ArrayList;
import java.util.Iterator;
import com.sreekanth.java5.dto.TestDTO;
/**
* @author sreekanth
*
*/
public class TrialGenerics {
/**
* @param args
*/
public static void main(String[] args) {
//Declare a Generic Collection - Aids in the compile time checking of the type
ArrayList
TestDTO d1 = new TestDTO("sreekanth", "d1");
TestDTO d2 = new TestDTO("sreekanth", "d2");
TestDTO d3 = new TestDTO("sreekanth", "d3");
dtoList.add(d1);
dtoList.add(d2);
dtoList.add(d3);
TrialGenerics myTrial = new TrialGenerics();
myTrial.myHelperMethod(dtoList);
}
private void myHelperMethod (ArrayList
{
//Iterator
for (Iterator
{
// No need to cast any more !!!
TestDTO item = iter.next();
System.out.println(item.getName());
System.out.println(item.getType());
}
}
}
TestDTO class used by the above program
package com.sreekanth.java5.dto;
public class TestDTO {
String name;
String type;
public TestDTO(String name, String type) {
super();
this.name = name;
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Static Imports
package com.sreekanth.java5;
import static java.lang.Math.*;
import static java.lang.System.out;
public class TrialStaticImport {
public static void main(String[] args) {
// No need for System..out
out.println("Hi this is a static import example");
}
}
Callable and Futures - Callable Class
package com.sreekanth.java5.util;
import java.util.concurrent.Callable;
public class TestCallable implements Callable
{
private String threadName;
@Override
public Long call() throws Exception {
long sum = 0;
//sums up some numbers
System.out.println("This is coming from " + this.threadName );
for (long i = 0; i <= 100; i++) {
sum += i;
}
System.out.println("This is the sum from the worker :" + this.threadName + "and the sum is :" + sum);
return sum;
}
public TestCallable(String name) {
threadName = name;
}
}
Use of Callable and Future in a Test Program
package com.sreekanth.java5;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Callable;
import com.sreekanth.java5.util.TestCallable;
/**
* @author sreekanth
*
*/
public class TrialFutureNCallable {
public static void main(String[] args) {
//thread pool of size 10
ExecutorService executor = Executors.newFixedThreadPool(10);
List
for (int i = 0; i < 20000; i++) {
Callable
Future
list.add(submit);
}
long sum = 0;
System.out.println(list.size());
// Now retrieve the result
for (Future
{
try {
sum += future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
System.out.println(sum);
}
}
My Photography Page
I have been doing a lot of photography over the last few years and wanted to create a site of my own. Finally did that with Smugmug in the last year
My site: http://sreekanth.smugmug.com
My site: http://sreekanth.smugmug.com
Subscribe to:
Posts (Atom)