Java Session 3 - Streams and Threads

idiotdiscSoftware and s/w Development

Aug 15, 2012 (5 years and 3 days ago)

222 views



University of Ulster

1

Java Session 8


Servlets and JDBC

Java Session
0
8



Web Servers,
Servlets and JDBC

Introduction

In this session we explore web servers and the three
-
tier client
-
server model. The
World Wide Web (WWW) started life as part of a distributed document system.
The idea was that the WWW consist
ed of a set of nodes, each of which contained a
tree of documents. In practice, each node containe
d a computer which had a Web
Server. The Web server accessed a file folder which, together with its sub
-
folders,
contained files which could be sent to any
client via the Internet.

Very rapidly it was realised that this set
-
up could easily be extended so that rather
than serving documents, Web servers could be sent requests input by users, and
return dynamically generated pages.

If the request was con
v
erted i
nto SQL then the Web server could interact with a
database system, which could be on another server. Then the Web server would be
responsible for relaying the results of the SQL request back to the client.

In this session we start by creating a simple Web

server which always returns the
same file. There are two ways of accessing the server:
the first is via a browser
such as Firefox, and the second is via
a specially written client which can be run
from the MS
-
DOS command line and which
displays debugging

information.

Next, we create a dynamic Web server. The user is able to send the name of a car
brand to the server, and it replies with a dynamically
-
generated page.

In the final section of the practical we create a servlet
-
based application in which
user
s are able to interrogate a database and get results. This application uses the
well
-
known Tomcat server.



A Simple Web Server

Web servers are simply servers which follow the
hype
r
text transfer protocol
, http.
A
browser
is a program which is designed t
o act a client of a web
-
server. If you
are using a browser such as Mozilla Firefox or Internet Explorer, the browser
makes a TCP connection with the server named in the browsing bar. For example
if you type:


http://www.infj.ulst.ac.uk


The

browser will
connect to the server at the URL
www.infj.ulst.ac.uk

on port 80.
(Port 80 is the default port for all Web servers.)

The server will return
an HTTP
header

and then
a page of HTML text

to the
browser
. The brows
er will display the text, formatted as specified by the HTML
embedded commands.

Of course, in general you can add extra information to the
request, such as


University of Ulster

2

Java Session 8


Servlets and JDBC

specifying the name of a file that you want to view: For example, the file
openhour.html

is viewed
using the following URL:


http://www.infj.ulst.ac.uk/openhour.html


You can also send a specific request to a server, using
parameters.
For example, if
you want

to send a car brand to

the local Web server (at 127.0
.0.1) you can just
type:

http://127.0.0.1
/?brand=ford

This sends the value
ford

for the parameter

brand

to the server.


The
First Web Server
Program

The program below is contained in the Netbeans package
webserver
.


/*


* Main.java


*/


package webserver;


import java.net.*;

import java.io.*;

import java.util.*;


public class Main extends Thread {



private byte[] content;


private byte[] header;


private int port = 82
;



public Main(String data, String encoding,


String MIMEType, int port)


throws UnsupportedEnc
odingException {


this(data.getBytes(encoding), encoding, MIMEType, port);


}



public Main(byte[] data, String encoding,


String MIMEType, int port) throws UnsupportedEncodingException {




this.content = data;


t
his.port = port;


String header = "HTTP/1.0 200 OK
\
r
\
n" +


"Server: Dodgy Jack 1.0
\
r
\
n" +


"Content
-
length: " + this.content.length + "
\
r
\
n" +


"Content
-
type: " + MIMEType + "
\
r
\
n
\
r
\
n";


System.out.print
ln("Header is:" + header);


this.header = header.getBytes("ASCII");


}




public void run() {




try {


ServerSocket server = new ServerSocket(this.port);


System.out.println("Accepting connections on port " +



University of Ulster

3

Java Session 8


Servlets and JDBC


server.getLocalPort());


System.out.println("Data to be sent:");


System.out.write(this.content);




while (true) {




Socket sock = null;


try {



sock = server.accept();


OutputStream out = new BufferedOutputStream(


sock.getOutputStream() );


InputStream in = new BufferedInputStream(



sock.getInputStream() );




StringBuffer request = new StringBuffer(80);


while (true) {


int c = in.read();


if (c == '
\
r' || c == '
\
n' || c ==
-
1)



break;


request.append((char) c);


}


System.out.println("Request is:" + request.toString());




// If this is HTTP/1.0 or later sen
d a MIME header


if (request.toString().indexOf("HTTP/") !=
-
1) {


out.write(this.header);


}




out.write(this.content);


out.flush();


} // end try


catch (IOException e) {


System.out.println("Exception:" + e);


}


finally {


if (sock != null)


sock.close();



}


} // end while


} // end try


catch (IOException ex) {


System.err.println("Could not start server. Port Occupied");


}


} // end run



/*
--------------------------------------------------
------------------


**/


public static void main(String[] args) {



try {


String contentType = "text/plain";


if (args[0].endsWith(".html") || args[0].endsWith(".htm")) {


contentType = "text/html";


}


System.out.println("Content type is:" + contentType);


// Read file to be sent to client


InputStream in = new FileInputStream(args[0]);


ByteArrayOutputStream out = new ByteArrayOutput
Stream();


int b;


while ((b = in.read()) !=
-
1)


out.write(b);


byte[] data = out.toByteArray();



University of Ulster

4

Java Session 8


Servlets and JDBC



// Set the port to listen on


int port;


try {



port = Integer.parseInt(args[1]);


if (port < 1 || port > 65535) port = 8080;


}


catch (Exception ex) {


port = 82
;


}


String encoding = "ASCII";


if (args
.length >= 2)


encoding = args[2];


Thread t = new Main(data, encoding, contentType, port);


t.start();


}


catch (ArrayIndexOutOfBoundsException ex) {


System.out.println(


"
Usage: java
-
jar webserver.jar filename port encoding");


}


catch (Exception ex) {


System.err.println(ex);


}


}

}

Running the webserver.jar file

1. Download the Netbeans project webserver

2. Run an MS
-
DOS window and move

to the
dist

subdirectory of the project.

3. Have a look at
garage.html
. You could type:

notepad garage.html

4. Type the following line:


java
-
jar webserver.jar garage.html 82

ASCII


Content type is:text/html

Header is:HTTP/1.0 200 OK

Server: Dodgy Jack 1
.0

Content
-
length: 128

Content
-
type: text/html



Accepting connections on port 82

Data to be sent:

<html>

<head>

<title>Dodgy vehicles</title>

</head>

<body>

Come to our garage and get really good value

</body>

</html>

Using Browser to Make

Requests to the

Server

Fire up a browser and navigate to:

http://127.0.0.1:82



University of Ulster

5

Java Session 8


Servlets and JDBC

Using Client Program to Make Requests to the Server

In order to look at what is going on at the client end, we can use a program which
makes an explicit Socket connection and then receives both

the HTTP: header and
the html and just prints them out.


import java.net.*;

import java.io.*;

import java.util.*;


public class Main {



public static void main(String[] args) {


String host = "127.0.0.1";


int port = 82;


if (args
.length > 0) {


port = Integer.parseInt(args[0]);


}


String brandValue = null;


if (args.length > 1) {


brandValue = args[1];


}


Socket clientSock = null;


try {


clientSock = new

Socket(host, port);


System.out.println("Socket has been obtained");




Writer out =


new OutputStreamWriter(clientSock.getOutputStream(),


"8859_1");


Strin
g request = "GET / HTTP/1.1";


if (brandValue != null) {


request = "GET /?brand=" + brandValue + " HTTP/1.1";


}




out.write(request);


out.write("
\
r
\
n");



out.flush();




System.out.println(


"The following request has been sent " +


"on the socket output stream:");


System.out.println(request);




InputStreamReader in = n
ew InputStreamReader(


new BufferedInputStream(


clientSock.getInputStream()),


"8859_1");


System.out.println(



"The following response has been received " +


"from the server:");


int c;


while ( (c = in.read()) !=
-
1 ) {


if ( ( c >= 32 && c <127 )


|| c == '
\
t' || c == '
\
r'
|| c == '
\
n' )


System.out.write(c) ;


}


}


catch (Exception e) {


System.out.println("Exception raised:" + e);


}



University of Ulster

6

Java Session 8


Servlets and JDBC


finally {


try {


if ( clientSock != null) {


clientSock.close();


}


}


catch (IOException e) {}


}


}



}

The Second Web Server Program

This program, contained in the
Netbeans project,
web
query
server
, i
s very
similar to the first p
rogram, except that the client request should contain a
parameter called
brand

which has is a brand such as ‘polo’, ‘ford’, etc
...

The
program parses the GET line in the header sent by the client and adds the brand
name into the web page it sends back to
the client.


The code below is a fragment from the Main.java file for this server.




System.out.println("Request is:" + request.toString());


// Parse the request


String get = request.toString();


StringTokenizer st = new StringTokenize
r(get, "?= ");


String method = st.nextToken();


String parameterName = null;


String parameterValue = null;


boolean requestOK = false;


if (method.equals("GET")) {


try {


String padding = st.nextToken();



parameterName = st.nextToken();


System.out.println("Parameter:" + parameterName);


parameterValue = st.nextToken();


System.out.println("Parameter value:" + parameterValue);


if (parameterName.equals(
"brand") &&


parameterValue != null) {


requestOK = true;


}


}


catch (Exception e) {}


}


// If this is HTTP/1.0 or later send a MIME header


if (request.toString().indexOf("HT
TP/") !=
-
1) {


out.write(this.header);


}


Writer outWriter = new OutputStreamWriter(out);


Date now = new Date();


outWriter.write("<HTML>
\
r
\
n");


outWriter.write("<HEAD><TITLE>Dodgy Garage</TITLE><HEAD>
\
r
\
n");


ou
tWriter.write("<BODY>");


if (requestOK) {



outWriter.write("Hello, we stock the <H1> " +



parameterValue + " </H1> brand.");


}


else {



University of Ulster

7

Java Session 8


Servlets and JDBC



outWriter.write("Problems reading your request...");



}


outWriter.write("</BODY></HTML>
\
r
\
n");


outWriter.flush();


Now try running this server in an MS_DOS window.

1. Download the Netbeans project.

2. Navigate to the dist directory.

3. Use the java command line shown below.


jav
a
-
jar
webqueryserver.jar

Content type is:text/html

Header is:HTTP/1.0 200 OK

Server: Dodgy Jack 2.0

Content
-
type: text/html



Accepting connections on port 83


Accessing the Server from
the
Browser

To access the server use your browser again:

Use the URL

shown

below:

http://127.0.0.1:83
/?brand=lion


Meanwhile you should see the following in the MS
-
DOS window for the server.


Request is:GET /?brand=lion

HTTP/1.1

Parameter:brand

Parameter value:lion

Accessing the Server from
the
Java Client

Run the client p
rogram in the MS
-
DOS window with the following command:

java
-
jar webclient.jar 83 polo


Socket has been obtained

The following request has been sent on the socket output stream:

GET /?brand=polo HTTP/1.1

The following response has been received from the s
erver:

HTTP/1.0 200 OK

Server: Dodgy Jack 2.0

Content
-
type: text/html


<HTML>

<HEAD><TITLE>Dodgy Garage</TITLE><HEAD>

<BODY>Hello, we stock the <H1> polo </H1> brand.</BODY></HTML>




University of Ulster

8

Java Session 8


Servlets and JDBC

Java Servlets

Many modern
enterprise
systems implement three
-
tier client
-
server systems using
Java servlets

and JDBC. A Java servlet is a named method which is designed to
respond to a specific request. The Java servlet engine passes requests to the servlet
and the servlet constructs a Web page to send back to the client.

htt
p://w
ww.infj.ulst.ac.uk/

In this session you can create a simple web
-
site which uses servlets to interface to
a back
-
end database.


It is easy to implement a
simple Web server in Java.

Creating a
Servlet
-
Based
Web Application

Netbeans allows you to creat
e a
servlet
-
based
Web application and deploy it to a
Web server such as the Tomcat server. You may not be able to deploy your
application in the lab, but you should be able to use the inbuilt server that is
distributed with Netbeans
.


1. Run Netbeans and
select


File/New Project

2. Choose the Project category to be Web and select the project type to be a Web
application.

3. Call your project plum.

4. Select

File/New File

5. Select your file to be of category Web and of file type Servlet.

6.
Call it
Bana
na.

7.
You will see the outline of a servlet appear.



protected void processRequest(HttpServletRequest request,


HttpServletResponse response)


throws ServletException, IOException {


response.setContentType("text
/html;charset=UTF
-
8");


PrintWriter out = response.getWriter();


/* TODO output your page here


out.println("<html>");


out.println("<head>");


out.println("<title>Servlet
Banana
</title>");


out.println("</head>")
;


out.println("<body>");


out.println("<h1>Servlet Banana at " + request.getContextPath () +


"</h1>");



University of Ulster

9

Java Session 8


Servlets and JDBC


out.println("</body>");


out.println("</html>");


*/


out.close();

Modifyi
ng the Servlet

Uncomment the Servlet code and compile and run it.

Just compile the actual file, by right
-
clicking on its name in the Project panel, or by
pressing F9.

If you then run the file you will see your default browser run and the servlet will
run i
n the browser.


A Servlet that Creates a Form

Create another servlet called ChatForm, with the code below, and run it. You’l
l
see a web page with a text box

appear.



out.println("<head>");


out.println("<title>Servlet ChatForm</title>");



out.println("</head>");


out.println("<body>");


out.write("What is your name?");



out.write("<FORM METHOD=GET ACTION=
\
"/plum/Chatty
\
">");


out.write("<INPUT TYPE=TEXT NAME=theanswer SIZE=20>");


out.write("<INPUT
TYPE=SUBMIT VALUE=
\
"Send
\
">");


out.write("</FORM>");


out.println("</body>");


The Code that accepts the Form Information

Finally, create a servlet called Chatty. This servlet should run the following code:



response.setContentType(
"text/html;charset=UTF
-
8");


PrintWriter out = response.getWriter();


String userSays = request.getParameter("theanswer");


String message = "What a nice name!";



out.write("
<HEAD><TITLE>Chatty</TITLE></HEAD><BODY> ");


out.write("You said:" + userSays + "<BR>");


out.write(message);



out.write("</BODY>
\
r
\
n");


out.flush();


out.close();





University of Ulster

10

Java Session 8


Servlets and JDBC

JDBC Connectivity

Finally, the code below allows you to connect to a database.

Making a Connection
v
ia

Windows XP

Before it can work you need to be able to make a connection to the database. To
do this you need to access

Control Panel/Administrative Tools/Data Sources

WARNING


you may not have this access available in the lab, so you might need
to try

connecting at home.

You need to know where the file
cars.mdb

is located and then you give it the
name
cars

as its DNS


Data Source Name and connect it using the Microsoft
Access Driver.

After you have done this you should be able to run the database exam
ple.


1.

Add another
servlet

file called Cars to your existing
plum

project.

2.

Cut and paste the code below. Note that you need to make JDBC available.

3.

Run the
servlet
in the usual way.


/*


* Cars.java


*/


import java.io.*;

import java.net.*;


import javax.s
ervlet.*;

import javax.servlet.http.*;



import java.sql.*; // 0. make JDBC available


public class Cars extends HttpServlet {




/** Processes requests for both HTTP <code>GET</code> and
<code>POST</code> methods.


* @param request servlet reque
st


* @param response servlet response


*/


protected void processRequest(HttpServletRequest request,


HttpServletResponse response)


throws ServletException, IOException {


response.setContentType("text/html;charset=UTF
-
8
");


PrintWriter out = response.getWriter();


String sqlStatement =


"SELECT make, year, price, mot FROM carslist";



// S
pecify that the JDBC
-
ODBC bridge is being used 1.Driver name


String driverName = "sun.jdbc.o
dbc.JdbcOdbcDriver";



// I
dentify the cars database as the connectionURL


String connectionURL = "jdbc:odbc:cars";



// I
nitialise connection, statement and result set variables



University of Ulster

11

Java Session 8


Servlets and JDBC


Connection con = null;


Statement stmt =
null;


ResultSet rs = null;



// C
onnect to the database, pose the query and get results


try {



//2. Make a new instance of the driver.



Class.forName(driverName).newInstance();





//3. Connect to a par
ticular database



con = DriverManager.getConnection(connectionURL);





//4. Create a statement to use with an SQL query:



stmt = con.createStatement();




//5. Execute the statement on the database



rs = stmt.executeQuery(sqlStatement);


}


catch (Exception e) {



out.println(e);


}



out.println(


"<center><h3>Contents of the Cars Database</h3></center>");




try { /* 6. The resu
lt set which is returned can be scanned


and sent to html page */


/* If there is data in the ResultSet, get its metadata,


* e.g. number of columns, column labels, etc. */


if (rs.next()) {



ResultSetMetaData rsmd = rs.getMetaData();


int colCount = rsmd.getColumnCount();


//set up variables to contain the database fields data


String make;


int year;


i
nt price;


String mot;




//set up an HTML table


out.println("<center><table border>");


out.println("<tr>");




// obtain and print the database fields column labels




for (int i = 0; i < colCount; i++)


out.println("<th>" +


rsmd.getColumnLabel(i + 1) +


"</th>");


out.println("</tr>");





// obtain and print out each record of the database


do {


out.println("<tr>");


make = rs.getString(1);


year = rs.getInt(2);


price = rs.ge
tInt(3);


mot = rs.getString(4);




out.println("<td>" + make + "</td>");


out.println("<td>" + year + "</td>");


out.println("<td>" + "£" + price + "</td>");



out.println("<td>" + mot + "</td>");



University of Ulster

12

Java Session 8


Servlets and JDBC


out.println("</tr>");


}


while (rs.next());


// close the HTML table


out.println("</table></center>");


}



else


out.println("No records could be found");


}


catch (Exception e) { out.println(e); }




// close the connection to the database


try { if (con != null) con.close(); }


catch (Exc
eption e) { out.println(e); }




// print standard HTML footer


out.println("</body>");


out.println("</html>");


out.flush();


out.close();


}


Exercises

1. Modify the client program

to point to another (or any) browser and
port number
and see what the server sends back.

2. What happens to the HTTP header: information that arrives at the server if
different browsers are used?

3. (HARD) Modify the
Chatfor
m

servlet
so it calls the
Cars

servlet

and so

that
you
can pass
a parameter for th
e brand. Change the Cars
servle
t
and it will return all
cars of that brand back to you.


Remarks

We have skimmed over the surface here.

For example, it’s possible to use visual programming in
Netbeans t
o

create the
forms and web pages.

There is also the possibility of using a system such as Ajax in order to avoid
downloading new pages each time a request is sent to the Web server. With Ajax,
only the data that is new is sent back to the browser
and the br
owser only has to
change part of the display

area
.

If the page being sent to a browser has several components such as images and
applets then these components can be downloaded concurrently using threads.