Perl Database Example Using ODBC Data Source Name DSN

The aim of this Perl tutorial is to use Perl to read and write to a database. In this example the database connection is an ODBC DSN attached to a Microsoft SQL Database. However, this can be used for any database. This perl example will open a connection to a database and create SQL queries to fetch and insert data.

First lets have a look at the example. It's really self explanatory.
 1. use DBI;
 2. 
 3. # Connect to database
 4. my $dbh = DBI->connect("dbi:ODBC:mydsn", "sa", "Admin-123",
 5.             {RaiseError => 1})
 6.             or die "Couldn't connect to database: " . DBI->errstr;
 7. 
 8. #Retrieve data
 9. my $sth = $dbh->prepare(<<SQL);
10.     select * from testtable
11.     where id < 1000
12. SQL
13. $sth->execute;
14. while (my @row = $sth->fetchrow_array()) {
15.    my ($id, $name, $address) = @row;
16.    print "$id $name $address\n";
17. }
18. 
19. #Insert data
20. $sth = $dbh->prepare("insert into callexpert (starttime, url) values( CONVERT(datetime, ?), ?)");
21. $sth->execute("08.09.2009  6:00:00 AM", "www.google.com");
22. $sth->execute("08.09.2009  6:24:00 AM", "www.facebook.com");
23. 
24. #Finish up    
25. $sth->finish();
26. $dbh->disconnect;
Hide line numbers

Line 3 We connect to the Data Source Name that is pointing to the SQL Server. For MySQL the connection url will look something like "dbi:mysql:MyDatabase;host=www.myhost.com"

Lines 8-17 Read data from testtable and display it on the screan

Lines 19-22 Insert some data into the callexpert table. Here we are using the MS SQL CONVERT function to convert a string into a datetime format.

Creating A Class in Perl With Public Methods

This example demonstrates how to create a class in Perl and use accessor methods such as 'get' and 'set' to access variables/attributes. Also demonstrates 'blessing' with the perl function bless. This is very useful as it allows the encapsulation of related data and helps to neaten code.

Let us have a look at the example. It is self explanatory. We create two files. One file will be named ComplexNumber.pm and the other run.pl. Make sure both these files are in the same place. FYI: The class models a complex number with real and imaginary components - not important

ComplexNumber.pm is the Perl package or 'class'
 1. package ComplexNumber;
 2. 
 3. sub new {
 4.     my $class = shift;
 5.     my $self = {
 6.         REAL => shift,
 7.         IMAGINARY => shift
 8.     };
 9.     bless $self, $class;
10.     return $self;
11. }
12. 
13. sub getReal(){
14.     my $self = shift;
15.     return $self->{REAL};
16. }
17. 
18. sub setReal(){
19.     my $self = shift;
20.     $self->{REAL} = shift;
21. }
22. 
23. sub printNumber(){
24.     my $self = shift;
25.     print "$self->{REAL} + $self->{IMAGINARY}i\n";
26. }
27. 1;
Hide line numbers


run.pl is the script that will instantiate the class and call some of the getter and setter methods.
 1. use ComplexNumber;
 2. 
 3. 
 4. my $num1 = ComplexNumber->new(1,2);
 5. my $num2 = ComplexNumber->new(3,4);
 6. 
 7. $num1->printNumber();
 8. $num2->printNumber();
 9. 
10. print "Changing real from ".$num1->getReal()." to 20\n";
11. $num1->setReal(20);
12. 
13. $num1->printNumber();
Hide line numbers

Moving, Hiding and Changing the Contents of a Layer in Javascript

This simple example shows you how to move a layer, show and hide a layer and change the contents of a layer dynamically from Javascript. This kind of layer manipulation in fundamental to all web 2 applications.

This uses a randomly generated number to move the layer. This also uses document.body.scrollTop to adjust for scrolling and innerHTML to write to the layer.

 1. <html>
 2. <head>
 3. <title>Layer Properties</title>
 4. <script>
 5. function MoveLayer(){
 6.     var x = document.getElementById("mycontainer").style;
 7.     x.top  = parseInt(document.body.scrollTop) + Math.round(Math.random()*200); 
 8.     x.left = parseInt(document.body.scrollLeft) + Math.round(Math.random()*200);
 9. } 
10. function HideLayer(){
11.     var x = document.getElementById("mycontainer").style;
12.     x.visibility = (x.visibility == "visible" ? "hidden" : "visible");
13. }
14. 
15. function WriteToLayer(){
16.     document.getElementById("mycontainer").innerHTML="Now I've overwritten the original stuff"
17. }
18. </script>
19. </head>
20. <body>
21. 
22. <a href="javascript:HideLayer()">Hide/Unhide Layer</a>
23. 
24. <div style="position:absolute;visibility:visible" id="mycontainer">
25.     <a href="javascript:MoveLayer()">Move Layer</a> | 
26.     <a href="javascript:WriteToLayer()">Overwrite Layer</a>
27. </div>
28. 
29. </body>
30. </html>
Hide line numbers

How to Write a Simple Recursive Web and Image Crawler in Perl

Aim
The aim of this tutorial is to demonstate a simple yet effective Perl based webcrawler. In this example we will initially open a socket to a starting website, grab the links and then recursively trawl those links for more links. This builds on the previous perl tutorial Perl Socket and File Example. This is a great starting point to building your very own customized perl web crawler. I am not using the Mechanize package as the aim is to keep everthing light and tight and hard core. Leave any questions or problems as comments and I will endeavour to answer them.

Assumptions
This article assumes that you have a compatible Perl installation and a reasonable understanding or regular expressions. Previous perl experience not required.

Versions used in this example
Sofware/Component
Image
Active Perl 5
ActivePerl-5.10.1.1006-MSWin32-x86-291086.msi
Microsoft Windows XP
N/A


Quick Overview
The aim of this example is to trawl through a website and it's links, find all the images and write the references to a file. You can then simple view the html file and see all the images, without having to navigate throught the site. To keep life simple this is a recursive program so we don't need to a database to store our urls and everything is kept simple.

The depth of the drill specifies how deep the crawler will go. Be careful, because if a site has an average of 10 links and you drill to a depth of 5 links deep you will end up reading 100, 000 pages and finishing up your badwidth. If you give a regex to the script it will then ignore all pages that do not match the regex in the thml body. As you can see I'm not actually downloading any images, there is no need to. All you need are the HTML IMG tags and you can view them in your browser.

For example

pwc.pl codediaries.blogspot.com -d 3 -s "(java|C\+\+)" -p 50"

Will start at codediaries.blogspot.com will follow links 3 deep, and save all the images it finds in myimages.html file with 50 pics per page, but only images referenced from pages that have the word either "java" or "C++" in them.

You can download the file here or copy it off the listing below (turn off line numbering at the bottom).


Example
 1. # Righteous Ninja            #
 2. # scriptdiaries.blogspot.com #
 3. 
 4. use IO::Socket;
 5. 
 6. my %imagehash=();
 7. my %urlhash=();
 8. 
 9. my $depth_limit=0;
10. my $pics_per_page=50;
11. my $output_file="images.html";
12. my $search_terms=" ";
13. 
14. 
15. #recursive subroutine - careful of stack overflow.
16. sub recursiveget{
17.     
18.     my $hostname;
19.     my $port;
20.     my $page="/";
21.     my $current_depth= $_[1];
22.     my $baseurl=$_[0];
23.     
24.     $current_depth++;
25.     
26.     $_[0]=~s/http:\/\///;
27.     
28.     $urlhash{"$_[0]"} = 1;
29.     
30.     if($_[0] =~ m/:(\d+)/ ){
31.         $port = $1;
32.     }
33.     if($_[0] =~ m/(.+?)(:|\/)/ ){
34.         $hostname = $1;
35.     }
36.     else{
37.         $hostname = $_[0];
38.     }
39.     if($_[0] =~ m/(\/.+)/ ){
40.         $page = ($1);
41.     }
42.     
43.     $port=($port)?$port:80;
44. 
45.     my $sock = new IO::Socket::INET (PeerAddr => $hostname ,
46.                                         PeerPort => $port, 
47.                                         Proto => 'tcp');
48.                         
49.     if(!$sock){
50.         print "$baseurl\t\tFailed\n";
51.         return;
52.     }
53. 
54.     
55.     eval{ #catch any processing errors and ignore them
56.     
57.     printf $sock ("GET $page HTTP/1.0\n");
58.     printf $sock ("Host: $hostname\n");
59.     printf $sock ("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
60.     printf $sock ("User-Agent: Mozilla/5\n");
61.     printf $sock ("Connection: keepalive\n");
62.       printf $sock ("\n\n");
63.     
64.     my $data="";
65.     while (<$sock>) {
66.         if($_=~ m/validate_response/i) {
67.              last;
68.         }
69.         else{
70.             $data.=$_;
71.         }
72.     }
73.     #check to see if it's a redirect- and if it is go to the new site.
74.     if($data=~ m/HTTP\/1\.\d +302/i && $data=~ m/Location: (.*)\r\n/){
75.         print "$baseurl\t\tRedirect\n";
76.         &recursiveget("".$1, $current_depth);
77.     }
78.     elsif($data!~ m/HTTP\/1\.\d +200/i){
79.         print "$baseurl\t\tHTTP Error\n";
80.         return;
81.     }
82.     #grab the images
83.     else{
84.         #check is the page matches any of my search terms
85.         if($data !~ m/$search_terms/ig){
86.             #ignore
87.         }
88.         else{
89.             $page =~ m/(.*)\//;
90.             $page=$1;
91.             while($data =~ m/\<.*?img.*?src="(.+?)".*?\>/g){
92.                 $temp=$1;
93.                 if($temp =~ m/http:\/\//i){
94.                     $picurl=$temp;
95.                 }
96.                 else{
97.                      $picurl= "http://$hostname:$port$page/$temp";
98.                 }
99.                 if( not exists $imagehash{$picurl} ){
100.                     $imagehash{$picurl}=1;
101.                      writetofile($picurl, $baseurl);
102.                  }
103.             }
104.          }
105.         while($data=~ m/href=\"(.*?)\"/ig ){
106.             if($1 !~ m/(mailto:|irc:|^#|\.css)/i){
107.                 $temp=$1;
108.                 if($temp =~ m/http:\/\//i){
109.                     $newurl=$temp;
110.                 }
111.                 elsif($temp =~ m/^\//){
112.                     $newurl=$hostname.":"."$port$temp";
113.                 }
114.                 else{
115.                     #$temp =~ s/^\///;
116.                     $newurl=$hostname.":"."$port$page/$temp";
117.                 }
118.                 #print "$newurl\n";
119.                 if ($current_depth <= $depth_limit){
120.                     if ( ! exists $urlhash{ $newurl } ){
121.                         &recursiveget($newurl,$current_depth);
122.                     }
123.                 }
124.             }
125.         }
126.         print "$baseurl\t\tOK\n";
127.     }
128.     };#end eval - ignore any errors
129.     if($@){
130.         print "$@\n";
131.         #ignore;
132.     }
133. }
134. 
135. #called from recursiveget to print out the urls
136. my $counter=1;
137. my $fileseq=2;
138. sub writetofile{
139.     printf IMAGEFILE "<a href=\"$_[1]\"><img src=\"$_[0]\"/></a>";
140.     if(++$counter % $pics_per_page == 0){
141. 
142.         print IMAGEFILE "<p><a href=\"$fileseq$output_file\">Next Page</a></p>";    
143.         print IMAGEFILE "</body></html>";    
144.         close (IMAGEFILE);    
145.     
146.         open (IMAGEFILE, ">$fileseq$output_file");
147.         $fileseq++;
148.         print IMAGEFILE "<html><body>";
149.     }
150. }
151. 
152. #show useage information
153. sub showuseage{
154.     print "This application will crawl for images and put the references into an file.\n\n";
155.     print "useage:  PWC.PL site [-d depth] [-p pics/page] [-s search regex]\n"; 
156.     print "Example:  PWC.PL codediaries.blogspot.com -d 2 -p 100 -s \"(ninja|barbie)\" \n\n";
157.     exit;
158. }
159. 
160. 
161. #main
162. &showuseage unless @ARGV[0];
163. for ($i=1; $i < $#ARGV+1 ;$i++){
164. 
165.     if( @ARGV[$i] eq "-d"){
166.         $depth_limit=@ARGV[$i] unless !@ARGV[++$i];
167.     }
168.     elsif( @ARGV[$i] eq "-p"){
169.         $pics_per_page=@ARGV[$i] unless !@ARGV[++$i];
170.     }
171.     elsif( @ARGV[$i] eq "-s"){
172.         $search_terms=@ARGV[$i] unless !@ARGV[++$i];
173.     }
174.     else{
175.         &showuseage;
176.     }
177. }    
178. $output_file="images.html";
179. 
180. open (IMAGEFILE, ">$output_file");
181. print IMAGEFILE "<html><body>";
182. 
183. #Call recursive routine
184. &recursiveget(@ARGV[0],0);
185. 
186. print IMAGEFILE "</body></html>";    
187. close (IMAGEFILE);
188. 
189. print "Finished\n";
Hide line numbers

Some improvements that should probably be done are to limit the search to the starting domain and not go all over the place.

Asynchronous Javascript And XML Example (AJAX)

This is a simple javascript AJAX tutorial using php, javascript and XMLHttpRequest. AJAX is the fundamental lynchpin of web 2 services and underpins almost every widget today. This is the simplest javascript example that demonstrates AJAX. No prior php knowledge required. Great for beginers to AJAX.

This example consists of two files. ajaxexample.html contains all the javascript and getresult.php is the php backend that returns an xml result. Create or copy these two files into the same directory on a webserver (such as apache) that supports php.

ajaxexample.html
 1. <html>
 2. <head>
 3. <script language="javascript">
 4. function new_XHR() {
 5.     var xhr;
 6.     try{
 7.         xhr = new ActiveXObject("Msxml2.XMLHTTP");
 8.     }catch(e){
 9.     try{
10.         xhr = new ActiveXObject("Microsoft.XMLHTTP");
11.         }catch(E){
12.             xhr = false;
13.         }
14.     }
15.     if(!xhr && typeof XMLHttpRequest != 'undefined'){
16.         xhr = new XMLHttpRequest();
17.     }
18.     return xhr;
19. }
20. 
21. var myxhr;
22. function DoAjaxCall(){
23.       myxhr = new_XHR();
24.       myxhr.onreadystatechange=MyAjaxCallback;
25.       myxhr.open('GET',"getresult.php?"
26.         +"name="+document.getElementById("NameBox").value);
27.       myxhr.send(null);
28.     }
29.        
30. function MyAjaxCallback(){
31.     var name;
32.     var message;
33.     if(myxhr.readyState==4 && myxhr.status==200){
34.         var subrootNode = myxhr.responseXML.getElementsByTagName('user-data');
35.         for(i = 0 ; i < subrootNode[0].childNodes.length ; i++){
36.             var node = subrootNode[0].childNodes[i];
37.             if(node.tagName=="name")
38.                 name=node.firstChild.nodeValue;
39.             else if(node.tagName=="message")
40.                 message=node.firstChild.nodeValue;
41.             else{}
42.         }
43.         document.getElementById("MessagePane").innerHTML = 
44.                                     "<b>"+name+" :</b> \""+message+"\""; 
45.     }
46. }
47. </script>
48. </head>
49. <body>
50. <form>
51. Name <input id="NameBox" type="text"/>
52. <a href="javascript:DoAjaxCall()">Send the data without submitting the form</a>
53. </form>
54. <div id="MessagePane"/>
55. </body>
56. </html>
Hide line numbers
Now type http://127.0.0.1/WEB/AJAXExample/ajaxexample.html in a browser, type your name in the textbox and click on the link.

lines 4-19 Creates an XMLHttpRequest object

lines 22-28 DoAjaxCall get's called when you click on the link. This creates an XMLHttpRequest object sets MyAjaxCallback as the callback function and adds the url to call.

lines 30-46 Once getresult.php is called the MyAjaxCallback function is called with the reuslt. You can then 'decode' the XMLHttpRequest object by traversing the sctructure and extracting the information.

getresutl.php
 1. <?php header('Content-type: text/xml');
 2.  
 3. $my_name = $_GET["name"];
 4. 
 5. $dom = new DomDocument('1.0');
 6. $dom->formatOutput = true;
 7. 
 8. $userdata = $dom->createElement( "user-data" );
 9. $dom->appendChild( $userdata );
10. 
11. $name = $dom->createElement("name");
12. $name->appendChild($dom->createTextNode("Doctor Octopus"));
13. $userdata->appendChild($name);
14. 
15. $mesg = $dom->createElement("message");
16. $mesg->appendChild($dom->createTextNode("Hello there $my_name, prepare to be mangled"));
17. $userdata->appendChild($mesg);
18. 
19. echo $dom->saveXml();
20. 
21. ?>
Hide line numbers
You can call this php script directly by typeing http://127.0.0.1/WEB/AJAXExample/getresult.php?name=sheena in your browser

Creating Classes in Javascript

This example demonstrates how to create a pseudo class in javascript. The javascript class is actually an empty function and you can assign attributes to it at runtime. This is very useful as it allows the encapsulation of related data and helps to make code neat.

Let us have a look at the example. It is self explanatory. We create two instances of MyClass, a and b, but assign different attributes to them.
 1. function MyClass(){}
 2. 
 3. a = new MyClass();
 4. a.text = "The sum is "
 5. a.num1 = 10;
 6. a.num2 = 20;
 7. 
 8. b = new MyClass();
 9. b.firstname = "Jason";
10. b.lastname = "Bourne";
11. 
12. function X(p){
13.     if(p.num1!=null)
14.         alert(p.text +(p.num1 + p.num2));
15.     else
16.         alert(p.firstname+" "+p.lastname);    
17. }
18. 
19. X(a);
20. X(b);
Hide line numbers

Javascript - Get URL Parameters from Form Submit

This example illustrates how Javascript extracts name and value pairs from a 'GET' submission or an url. You can use this as a means to pass Javascript values from one HTML page to another.

This code will extract name/value pairs from a URL such as http://codediarie.com/test.html?name=charlie&address=15%20Monterey%20Place%20Cherrybrook%20NSW%Australia.
 1. function MyGetUrlParams(){
 2.   var url_params = new Array();
 3.   var urla = location.href.substring(location.href.indexOf('?')+1).split('&');
 4.   for(i=0;i< urla.length ;i++){
 5.     url_params[urla[i].substring(0,urla[i].indexOf('='))]=
 6.     urla[i].substring(urla[i].indexOf('=')+1);
 7.   }
 8.   return url_params;
 9. }
10. 
11. ...
12. #stuff
13. ...
14. 
15. alert(MyGetUrlParams()['name']);
16. alert(MyGetUrlParams()['address']);
17. 
18. var params = MyGetUrlParams();
19. for (i in params){
20.   alert(params[i]);
21. }
Hide line numbers
Line 3 We decode location.href and put the values into an associative array with the names as keys.

Line 15-21 We can then use this array to get the values using the names - in many ways.

Scripting, Web 2 and Widget Tutorials

Examples and snippets about javascript, web 2, ajax, php, perl and much more. Learn how to create exciting widgets using yahoo, google and wtitter apis and DOM. Harness the power of web 2 to deliver rich content. Simple to understand yet comprehensive examples and tutorials.

Javascript

Perl

PHP

Technology Tutorial Trail - JavaEE, Database, Tomcat, Glassfish

Every application tutorial is listed here. Clean, simple and concise. C++ and Java tutorials based on application and technologies. This is frequently updated as tutorials are added. For core tutorials such as sockets, threads etc please see Core Tutorial Trail.

Core Tutorials (sockets, threads, servlets etc)

Ant / Nmake / Make


Database C++
EJB
JMS
JNI
JNDI Connection Pooling
Struts
Tomcat
  • Configure application based logging using context.xml
Web 2
Web Services
Cant find what you are looking for? Try the Core Tutorial Trail for core examples.

Adding HTTP Headers To Requests in Filters and Servlets

Aim
The aim of this tutorial is to demonstrate how you can add Headers to the ServletRequest and HttpServletRequest objects in either servlets or filters. This requires subclassing the HttpServletRequestWrapper class.

Assumptions
This article assumes that you can compile, deploy and test the filter/servlet.  For an example that demonstrates compiling and deploying a filter please go to Complete Java Filter Example. To create a JSP page that will display headers please have a look at JSP Page That Displays All Headers and Parameters.


  1. First let us have a look at subclassing the HttpServletRequestWrapper class. As you can see we have overridden getHeaderNames and getHeader to include our custom headers. These custom header are added through the addHeader function which is a new function. Our custom headers are stored in a hashmap.
     1. package myfilter;
     2. 
     3. import javax.servlet.http.HttpServletRequest;
     4. import javax.servlet.http.HttpServletRequestWrapper;
     5. import java.util.*;
     6. 
     7. public class MyServletRequestWrapper extends HttpServletRequestWrapper{
     8. 
     9.     private Map headerMap;
    10.     
    11.     public void addHeader(String name, String value){
    12.         headerMap.put(name, new String(value));
    13.     }
    14.     
    15.     public MyServletRequestWrapper(HttpServletRequest request){
    16.         super(request);
    17.         headerMap = new HashMap();
    18.     }
    19. 
    20.     public Enumeration getHeaderNames(){
    21.         
    22.         HttpServletRequest request = (HttpServletRequest)getRequest();
    23.         
    24.         List list = new ArrayList();
    25.         
    26.         for( Enumeration e = request.getHeaderNames() ; e.hasMoreElements() ;)
    27.             list.add(e.nextElement().toString());
    28.         
    29.         for( Iterator i = headerMap.keySet().iterator() ; i.hasNext() ;){
    30.             list.add(i.next());
    31.         }
    32.         
    33.         return Collections.enumeration(list);
    34.     }
    35.     
    36.     public String getHeader(String name){
    37.         Object value;
    38.         if((value = headerMap.get(""+name)) != null)
    39.             return value.toString();
    40.         else
    41.             return ((HttpServletRequest)getRequest()).getHeader(name);
    42.         
    43.     }
    44. }
    Hide line numbers

  2. Now let's have a look at a filter that will use this wrapper to add some custom headers. You can observe on line 31 how we use the wrapper to wrap the HttpServletRequest.
     1. package myfilter;
     2. 
     3. import java.io.IOException;
     4. import javax.servlet.*;
     5. import javax.servlet.http.HttpServletRequest;
     6. import javax.servlet.http.HttpServletResponse;
     7. import javax.servlet.http.HttpServletResponseWrapper;
     8. import javax.servlet.http.HttpSession;
     9. 
    10. import java.util.logging.*;
    11. 
    12. 
    13. public class MyFilter implements javax.servlet.Filter {
    14.     private ServletContext servletContext;
    15.     private Logger log;
    16.     
    17.     public MyFilter(){
    18.         super();
    19.     }
    20.     
    21.     public void init(FilterConfig filterConfig) throws ServletException {
    22.         servletContext = filterConfig.getServletContext();
    23.         log = Logger.getLogger(MyFilter.class.getName());
    24.     }
    25. 
    26.     public void doFilter(   ServletRequest req, 
    27.                             ServletResponse res, 
    28.                             FilterChain filterChain)
    29.         throws IOException, ServletException {
    30. 
    31.         MyServletRequestWrapper httpReq    = new MyServletRequestWrapper((HttpServletRequest)req);
    32.         HttpServletResponse    httpRes   = (HttpServletResponse)res;
    33.         
    34.         HttpSession session = httpReq.getSession();
    35. 
    36.         httpReq.addHeader("MY-HEADER-X1", "header 1");
    37.         httpReq.addHeader("MY-HEADER-X2", "header 2");
    38. 
    39.         filterChain.doFilter(httpReq, httpRes);
    40.             
    41.     }
    42. 
    43.     public void destroy(){
    44.     }
    45. 
    46. }
    Hide line numbers

JSP Page that Displays all the Headers and Parameters

Here is a simple page that displays all the header information and parameter names and values using getHeaderNames and getParameterNames;

 1. <%@ page  import="java.util.*" %>
 2. <html>
 3. <head></head>
 4. <body>
 5. 
 6. <h3> Parameter Names </h3>
 7. <%  
 8.     String parameter;
 9.     Enumeration parameterNames;
10.     for( parameterNames = request.getParameterNames() ; parameterNames.hasMoreElements() ; ){
11.         parameter = parameterNames.nextElement().toString();
12.         out.println("[ "+parameter+" ] = "+request.getParameterValues(parameter)[0]+"<br/>");            
13.     }
14. %>
15. 
16. <h3>Header Names</h3>
17. <%  
18.     String header;
19.     Enumeration headerNames;
20.     for( headerNames = request.getHeaderNames() ; headerNames.hasMoreElements() ; ){
21.         header = headerNames.nextElement().toString();
22.         out.println("[ "+header+" ] = "+request.getHeader(header)+"<br/>");            
23.     }
24. %>
25. 
26. </body>
27. </html>
Hide line numbers

Complete Java Filter Example

Aim
The aim of this tutorial is to create a simple yet fully functional Java Filter. This filter will redirect a request based on a URL parameter and modify the "body" text in a response. This filter can be deployed in any java container. Please leave any question or comments at the end and I will endeavour to answer them.

Assumptions
This article assumes that you have Glassfish or Tomcat or an equivalent java container installed and configured.

Versions used in this example
Sofware/Component
Image
Windows XP SP2
N/A
Glassfish
N/A
JDK 1.5.0
N/A
Links to these files can be found here

For the purposes of this tutorial the files are stored in the structure below. The FilterExample directory is the working directory.

FilterExample
_|_web_bin
_|__|_index.html
_|__|_WEB-INF
_|__|__|_web.xml
_|__|__|_classes
_|__|_filtered
_|__|__|_index.html
_|_web_src
_|__|_myfilter
_|__|__|_MyFilter.java

Create and deploy the Service
  1. First let's write the filter and save it as MyFilter.java in the web_src/myfilter directory. As you can see we inspect the request for a parameter named "redirect." If we find it we redirect the page to google. This is configured throught the init-parameters for the filter and is in the web.xml file. The response is modified by appending "hello There" just before the closing body tag.
     1. package myfilter;
     2. 
     3. import java.io.IOException;
     4. import javax.servlet.*;
     5. import javax.servlet.http.HttpServletRequest;
     6. import javax.servlet.http.HttpServletResponse;
     7. import javax.servlet.http.HttpServletResponseWrapper;
     8. import javax.servlet.http.HttpSession;
     9. 
    10. import java.util.logging.*;
    11. 
    12. import java.io.CharArrayWriter;
    13. import java.io.PrintWriter;
    14. 
    15. public class MyFilter implements javax.servlet.Filter {
    16.     private String redirectPage;
    17.     private ServletContext servletContext;
    18.     private Logger log;
    19.     
    20.     public MyFilter(){
    21.         super();
    22.     }
    23.     
    24.     public void init(FilterConfig filterConfig) throws ServletException {
    25.         servletContext = filterConfig.getServletContext();
    26.         redirectPage = filterConfig.getInitParameter("Redirect-Page");
    27.         log = Logger.getLogger(MyFilter.class.getName());
    28.     }
    29. 
    30.     public void doFilter(   ServletRequest req, 
    31.                             ServletResponse res, 
    32.                             FilterChain filterChain)
    33.         throws IOException, ServletException {
    34. 
    35.         HttpServletRequest httpReq    = (HttpServletRequest)req;
    36.         HttpServletResponse    httpRes   = (HttpServletResponse)res;
    37.         
    38.         HttpSession session = httpReq.getSession();
    39. 
    40.         if(httpReq.getParameterValues("redirectme")!=null){
    41.             httpRes.sendRedirect(redirectPage);
    42.         }        
    43.         else{
    44.             PrintWriter out = httpRes.getWriter();
    45.             CharResponseWrapper wrapper = new CharResponseWrapper(httpRes);
    46. 
    47.             filterChain.doFilter(httpReq, wrapper);
    48.             
    49.             if(wrapper.getContentType() != null && wrapper.getContentType().indexOf("text/html")!=-1) {
    50.                 CharArrayWriter caw = new CharArrayWriter();
    51.                 caw.write(wrapper.toString().substring(0, wrapper.toString().indexOf("</body>")-1));
    52.                 caw.write("<p>\nHello There</p>");
    53.                 caw.write("\n</body></html>");
    54.                 httpRes.setContentLength(caw.toString().length());
    55.                 out.write(caw.toString());
    56.             }
    57.             else{
    58.                 out.write(wrapper.toString());
    59.             }
    60.             out.close();
    61.         }
    62.     }
    63. 
    64.     public void destroy(){
    65.     }
    66. 
    67. }
    68. 
    69. class CharResponseWrapper extends HttpServletResponseWrapper {
    70.     private CharArrayWriter output;
    71. 
    72.     public String toString() {
    73.         return output.toString();
    74.     }
    75.     public CharResponseWrapper(HttpServletResponse response) {
    76.         super(response);
    77.         output = new CharArrayWriter();
    78.     }
    79.     public PrintWriter getWriter() {
    80.         return new PrintWriter(output);
    81.     }
    82. }
    Hide line numbers

  2. Now cd into the web_src directory and compile the source. Replace the path to Glassfish's lib directory with your local path. This could be lib in tomcat or any servlet container.

    ..FilterExample\web_src>javac myfilter\MyFilter.java -d ..\web_bin\WEB-INF\classes -extdirs d:\downloads\glassfish\lib

  3. Now create the web.xml file which will have our filter mapping and an init parameter. Save this under the WEB-INF directory under web_bin.
     1. <?xml version="1.0" encoding="ISO-8859-1"?>
     2. 
     3. <web-app>
     4. 
     5.    <!-- Define servlet-mapped and path-mapped example filters -->
     6.     <filter>
     7.         <filter-name>My Filter</filter-name>
     8.         <filter-class>myfilter.MyFilter</filter-class>
     9.         <init-param>
    10.             <param-name>Redirect-Page</param-name>
    11.             <param-value>http://www.google.com</param-value>
    12.         </init-param>
    13.     </filter>
    14. 
    15.     <!-- Define filter mappings for the defined filters -->
    16.     <filter-mapping>
    17.         <filter-name>My Filter</filter-name>
    18.         <url-pattern>/filtered/*</url-pattern>
    19.     </filter-mapping>
    20. 
    21. </web-app>
    Hide line numbers
    As you can see the filter will intercept any url starting with "/filter/*"

  4. now create a simple index.html file and save one copy in the web_bin directory and one in the web_bin/filtered directory.
     1. <html>
     2. <head></head>
     3. <body>
     4. <h1>Test</h1>
     5. </body>
     6. </html>
    Hide line numbers

  5. Now create the war file. Cd into the web_bin directory and jar it all up.

    ..FilterExample\web_bin>jar -cvf myfilter.war *

  6. Finally deploy this war file in the servlet container of your choice. Glassfish in this example.

Testing the filter
  1. First navigate to
    http://localhost:8080/myfilter/index.html.
    No change as the html is just served up.

  2. Now navigate to
    http://localhost:8080/myfilter/filtered/index.html.
    This url matches the url pattern in the web.xml file and the filter gets called. You will notice that "Hello There" appended to the html.

  3. Now navigate to
    http://localhost:8080/myfilter/filtered/index.html?redirectme=foo.
    This time the filter catches the redirectme using getParameterValues and redirect the browser to google.

To add headers to a Request please visit Adding HTTP Headers To Requests in Filters and Servlets.
To stop responses committing and redirecting errors visit Modifying and Redirecting Filter Responses

Simple Windows C++ DLL Example with Implicit and Explicit Calls

Aim
The aim of this Windows C++ tutorial is to build a simple Dynamic Link Library or DLL using the command line Visual C++ compiler (cl.exe0. Then create two small C++ test programs that will call this DLL implicitly by linking with the lib file and explicitly using LoadLibrary and GetProcAddress. Also note that the explicit linking requires a "def" definition file with the exported funtion names.

Assumptions
This article assumes that you have a compatible version of Visual C++ installed and you have run vcvars32. The file is called MyHook because it will be used later as a windows keyboard hook dll.

Versions used in this example
Sofware/Component
Image
Windows XP SP2
N/A
Visual C++ 2008 Express Edition
N/A
Links to these files can be found here


CPPDLLExample
_|_MyHook.cpp
_|_MyHook.h
_|_MyHook.def
_|_CPPDllImplicit.cpp
_|_CPPDllExplicit.cpp

The dll requires 3 files. Source file, header file and a definitions file. This def file is required to expose the functions for explicit linking only

Create the DLL
  1. Create the source file and save it as MyHook.h
     1. #ifndef MYHOOK_H
     2. #define MYHOOK_H
     3. 
     4. #ifdef MYHOOK_DLLEXPORT
     5. #define MYHOOK_API __declspec(dllexport)
     6. #else
     7. #define MYHOOK_API
     8. #endif
     9. 
    10. MYHOOK_API int AddNumbers(int, int);
    11. MYHOOK_API int GetMessage(char*, int);
    12. 
    13. #endif
    Hide line numbers

  2. Create the source file and save it as MyHook.cpp
     1. #include "MyHook.h"
     2. #include <string.h>
     3. 
     4. MYHOOK_API int AddNumbers(int x, int y){
     5.     return x + y;
     6. }
     7. MYHOOK_API int GetMessage(char* x, int length){
     8.     if(length>32){
     9.         strcpy(x, "hello from dll");
    10.         return 0;
    11.     }
    12.     else
    13.         return -1;
    14. }
    Hide line numbers

  3. Finally create the definitions file and save it as MyHook.def
     1. ; MyHook.def : Declares the module parameters for the DLL.
     2. 
     3. LIBRARY      "myhook"
     4. DESCRIPTION  "MyHook Windows Dynamic Link Library"
     5. 
     6. EXPORTS
     7.     ; Explicit exports can go here
     8.     AddNumbers
     9.     GetMessage
    10.     
    11. SECTIONS
    12.     ; Pragma sections
    Hide line numbers

  4. Build the library on the command line

    ...CPPDLLExample>cl -o myhook.dll myHook.cpp /D MYHOOK_DLLEXPORT /link /DLL /DEF:"MyHook.def"


Write and Compile Implicit caller
  1. Write implicit compiler and save it as CallDLLImplicit.cpp
     1. #include <iostream>
     2. #include "MyHook.h"
     3. 
     4. using namespace std;
     5. int main(){
     6. 
     7.     char msg[64];
     8.     cout << AddNumbers(5,10) << endl;
     9.     GetMessage(msg, 64);
    10.     cout << msg << endl;
    11. 
    12. }
    Hide line numbers

  2. Build the program using,

    ...CPPDLLExample>cl CallDllImplicit.cpp MyHook.lib

Write and compile the explicit client
  1. Write the explicit caller and save it as CallDllExplicit.cpp
     1. #include <iostream>
     2. #include <windows.h>
     3. 
     4. typedef int(*pAddNumbers)(int,int);
     5. typedef int(*pGetMessage)(char*,int);
     6. 
     7. using namespace std;
     8. int main(){
     9. 
    10.     HINSTANCE hInstance;
    11.     
    12.     if(!(hInstance=LoadLibrary("myhook.dll"))){
    13.         cout << "could not load library" << endl;
    14.         goto FINISH;
    15.     }
    16. 
    17.     pAddNumbers padd = (pAddNumbers)GetProcAddress(hInstance, "AddNumbers");
    18.     pGetMessage pget = (pGetMessage)GetProcAddress(hInstance, "GetMessage");
    19. 
    20.     if(!padd || !pget){
    21.         cout << "could no load functions" << endl;
    22.         goto FINISH;
    23.     }
    24. 
    25.     char msg[64];
    26. 
    27.     cout << padd(20,35) << endl;
    28.     pget(msg, 64);
    29.     cout << msg << endl;
    30. 
    31. FINISH:
    32.     cout<<"finished"<<endl;
    33. }
    Hide line numbers

  2. Now cd out to the workingdirectory build it

    ...CPPDLLExample>cl CallDLLExplicit.cpp


Running the executables
  1. Open a command prompt into your working directory and the executables. You should be able to see the results. Delete the dll and run them again - you should get an error message

Back to the tutorial trail | Home