To follow each document (containing the actual task and guide) and complete each task.
Task 1 Focus: Servlets / Tomcat
Document: Task 1 - Servlets(1).docx
Task 2 Focus: Servlets – Advanced
Document: Task 2 - Filters and Request Dispatching.doc
Task 3 Focus: JDBC and database issues
Document: Task 3 - JDBC.doc
•Make sure Tomcat is Installed and set up (setup file included in task 1)
•Assumes you have a version of Netbeans installed that includes the Apache Tomcat server (ie. The “Java EE” or “All” version of Netbeans ).
•This guide/tasks was created using Netbeans IDE 7.1.2 but the setup should be similar in other recent versions.
•Each task folder directory contains files to help and to be used relating to task
•Netbeans is a free Java Development IDE. It can be downloaded from http://www.netbeans.org
•Java Development Kit can be downloaded from: http://java.sun.com/javase/downloads/index.jsp
•Tomcat can be downloaded from:
Part 1 - Hello World
Part one of the prac today is to setup a servlet that displays a simple web page.
1.Create a class in your Netbeans project that extends HttpServlet.
You will have to import some packages to make use of HttpServlet and the other Java EE classes used in this practical. Use the Java EE API(Google “Java EE API”) or Netbean’s auto import feature to find out what these packages are.
You could create the class in the default package however it is better practice to put the class inside a package. In a Netbeans Web Application project you create packages and classes in the Source Packages folder.
2.Override the doGet method of HttpServlet and make it output a html page.
Remember that you can get a PrintWriter from the HttpServletResponse with:
PrintWriter out = response.getWriter();
Then use this PrintWriter to write the html page out into the response. eg.
3.When you build a Netbeans Web Application Netbeans will compile the java files into class files and place them in the WEB-INF/classes directory of the generated webapp. Class files in this directory are automatically available (on the classpath) to the webapp at run time. You can see that Netbeans is doing this in the Output pane:
Note the line:
Compiling 1 source file to /home/university/2014/semester_1/MyWebapplication/build/web/classes
4.While we have created a class that extends HttpServlet and placed it in the webapp it is still just another class. We have to define in the webapp that this class is a servlet. To do that we need to create a deployment descriptor. A deployment descriptor is an xml file that tells the web container (in our case Tomcat) how to setup the webapp. The deployment descriptor for a webapp is a file called web.xml which is placed in the WEB-INF directory of the webapp. When you deploy the webapp in a web container, the container reads this file to work out how to deploy and setup the webapp.
To create the deployment descriptor (web.xml) file right click on the Web Pages/WEB-INF directory in your project and select new → Standard Deployment Descriptor. This will create a new web.xml file with some basic content. eg.
Now we have a deployment descriptor we can add the class we created previously as a servlet. To do this add the following bit of xml to web.xml inside the webapp element:
Replacing myPackage.MyServlet with the fully qualified path of the class you created earlier. Fully qualified means that you have to include the package name as well as the class name.
This xml tells the web container (Tomcat) that myPackage.MyServlet is a servlet and that we are going to refer to it as hello_world elsewhere in the web.xml file.
While we have told the web container that this class is a servlet we now need to tell it which URLs are to be sent to this servlet. To do this add the following to web.xml:
The servlet-name must match the name you gave to the servlet above. The url-pattern defines the URLs that will be mapped to this servlet. The pattern is relative to the root of the webapp. So if the webapp was called my_webapp then using the above servlet-mapping the servlet would be mapped to the following url:
Once these entries have been made you should be able to run your webapp then enter the above url (replacing port with whatever port the Netbeans Tomcat is listening on) to run your servlet and view the page it generates.
Congratulations, you have created a HttpServlet and created a deployment descriptor (web.xml) to tell the web container that this class is a servlet and which urls should be mapped to it.
In this step we manually typed in the xml in the web descriptor however Netbeans has several wizards that allow us to create the various web.xml elements.
Feel free to use these wizards, however make sure you learn the xml as well as you will need this for the exam.
Part 2 – Request Parameters
Parameters are values that are sent from the client to the server. They come from either the request URL eg.
or from a html form that has been submitted eg.
In either case you access the parameters in the same way inside your servlet:
String name = request.getParameter(“name”);
Modify your previous servlet so that it takes in a parameter called name and outputs it to the page. eg.
You can test your servlet by passing the name parameter in on the URL eg.
Part 3 – Request Method
When you create a html form you can have it either submit using a GET request (the default) or a POST request. You can modify which method it uses with the method parameter. Eg.
<input type="text" name="username" />
<input type="submit" />
Remember that when a HTTPServlet receives a GET request it calls doGet(HttpServletRequest req, HttpServletResponse res) and when it receives a POST request it calls doPost(HttpServletRequest req, HttpServletResponse res).
Modify your servlet so that if it receives a GET request it outputs a form asking the user for their name. The form should be setup so that when it is submitted it uses a POST request.
When the servlet receives a POST request it should read the username parameter and output the following message:
Where <username> is the value of the username parameter.
Part 4 – Servlet Init Params and Context Init Params
Servlet init params – These are params that the person deploying your webapp can define to configure the servlet.
Context init params – These are params that the person deploying your webapp can define to configure the entire webapp.
Both types of params are defined in the web.xml file.
The following fragment from the web.xml file defines a context init param called “Unit” with a value of “Hit321 - Enterprise Applications”:
<param-value>Hit321 - Enterprise Applications</param-value>
The following fragment from the web.xml defines a servlet named param_demo and a servlet init param for this servlet named “Num Students” with a value of “8”:
You can access context init params inside your servlet with the ServletContext:
ServletContext context = this.getServletContext();
String unit = context.getInitParameter(“Unit”);
Similiarly you can get the servlet init params using the ServletConfig:
ServletConfig config = this.getServletConfig();
String numStudents = config.getInitParameter(“NumStudents”);
Create a new servlet that writes out all the context init params and servlet init params. These should appear in the page the servlet returns not in the logs.
Note: You will have to look at the Java EE API to work out how to get all the params rather than just an individual param. (Google “Java EE API”).
Part 5 - Sessions
When a client (eg. A browser) first connects to Tomcat, Tomcat sets up a session for that client. The session can be used to store information that will be remembered for future requests from that same client. This can be used for many purposes such as storing that the client has been authenticated, storing information about the client (eg. Their username) etc.
The session is a general purpose box into which you can put name values pairs that will be available for future requests from the same client.
There is one session per client. So information in one client’s session is typically only accessed during requests from that same client.
After the initial request Tomcat needs a means to determine on future requests which session belongs to that client. The default means by which Tomcat does this is though the use of a cookie and the client’s IP address. The cookie is named JSESSIONID by default in Tomcat. This stores an id that uniquely identifies that client. The browser sends the cookie with subsequent requests. When Tomcat receives a request it checks the value of this cookie and the client’s IP to determine which session belongs to that client. Once it has found the session it attaches it to the HttpServletRequest object so that your servlet’s can access the session.
You obtain the HttpSession object from the request object. Eg.
HttpSession session = request.getSession();
You can then put values into the session with:
The name must be a String but the value can be any Java Object.
You can retrieve values from the session with:
String value = (String)session.getAttribute(“name”);
Note the need for a cast as the getAttribute method returns an Object.
You can remove a value with:
1.Create a servlet that takes in two parameters, one called “name” and one called “value”. It should add an attribute to the session with a name that is the same as the value of the name parameter and a value that is the same as the value of the value parameter.
Don’t worry if an attribute already exists with the same name just overwrite it.
2.Modify your servlet from part 4 so that as well as outputting the init params it also outputs the names and values of all attributes in the session. Use this servlet to test the servlet you just wrote.
Congratulations. Today you have done the following:
•Created a HttpServlet that outputs a web page.
•Created a web descriptor (web.xml) to tell the web container (Tomcat) which classes are Servlets and which URLs are to be sent to these servlets.
•Accessed request parameters sent from the client using both GET and POST requests.
•Defined servlet init parameters and context init parameters in the web descriptor which can be used to configure your servlet and webapp.
•Used the session to store information that persists between requests from a client.
Filters are just classes that implement the interface “Filter”.
The Filter interface defines 3 methods:
Void init(FilterConfig filterConfig);
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain);
As you can see they are very similar to Servlets.
init - Is called when the filter is first loaded.
doFilter - Is called each time a request it passed to the filter.
destroy – Is called when the filter is un-loaded.
The key difference between a Filter and a Servlet is the extra FilterChain parameter passed to doFilter, this is what allows your filter to pass the request on to the next item in the filter chain (Either the destination resource or another filter)
Create a class that implements Filter. The first thing you will have to do is import the javax.servlet, and the java.io packages.
Then implement the methods in the Filter interface.
Each time a request is passed to the filter, doFilter is called. Inside this method the request is passed to the next element in the filter chain using chain.doFilter. You can perform pre and post processing in doFilter. Pre-processing is just code that is run before the call to chain.doFilter and post-processing is just code that is run after the call to chain.doFilter. eg.
Public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
//This line will be run before the call to the servlet.
//This line will be run after the servlet has been run
Make your filter write log messages similar to this.
Create a simple servlet that logs to System.out when doGet is called eg.
public void doGet(…)
System.out.println(“doGet is being processed”);
Map this servlet to a url.
Access the URL for the servlet. Look at the logs you should see something similar to the following:
Notice the “doGet is being processed” line that we logged in the servlet.
Now that we have the simple servlet working and a filter class we need to map the filter to a set of urls. This is similar to the way we map a servlet to a set of urls. To do this add the following lines to your web.xml:
Just like a servlet you give the filter a name and specify the class that runs when the filter is called. Then you map the filter to a url. Unlike a servlet you could also map the filter to a specific servlet eg. You could do:
The servlet name is the name of the servlet you want this filter to be run for, it must be the same as a name you have given to a servlet earlier in the web.xml file.
Now that we have the filter class setup and mapped to a set of urls call your simple servlet again. You should see something like the following in the Tomcat console:
Note the order of the logs. The pre processing log message was output, then chain.doFilter was called. This then went and executed the destination servlet’s doGet and finally returned to the chain.doFilter call and the post processing log message was output. You should be able to see how you can use filters to perform pre-processing before a servlet is called and post-processing after the servlet is called. And as you can map a filter to multiple urls and/or multiple servlets you can remove common code for pre-processing and post processing from servlets and put it in a filter instead.
Examples of pre-processing and post processing include:
•Logging – You can log request details such as request params and time taken to process the request.
•Output encoding/formatting – You can use filters to convert the incoming data to a common format the servlet can understand, then convert the response from the servlet to a format that the client can understand. This can allow you to handle different client types without modifying your servlets.
•Security – You can use a filter to check that the client has authenticated and if not forward them to a login page. (This could be useful for the assignment)
Now that you have the filter working try to make it log how long the servlet takes to handle the request. To do this you will need a servlet that takes a while to execute.
1.Make a servlet that takes a parameter “delay”. It should convert this parameter to an int and call Thread.sleep(delay) to make the servlet take a while to execute. Remember that sleep takes a time in milliseconds so, for example a value of 10,000 is 10 seconds. To test this call it from the browser with a descent delay (eg. 10 seconds) and check that the page takes a while to be returned.
2.Once you have done this try to create a filter that logs how long the servlet takes to handle the request.
Hint: You can use System.currentTimeMillis() to get the current time in milliseconds. Can you work out the difference in the time from before the servlet was called to after it was called?
Request dispatching allows you to do two things. Forward the request to another servlet/resource or include another servlet/resource output in the current output.
Forward – This lets you hand the request off to be handled by another resource/servlet.
Include – This lets you write out to the response, include the output of another servlet/resource and then continue writing out to the response.
Both these actions are performed using a RequestDispatcher. A RequestDispatcher wraps a resource on the server such as HTML file, another servlet, a JSP page etc and allows us to send requests to that resource. A RequestDispatcher can be obtained by several methods.
From the request object:
RequestDispatcher dispatcher = request.getRequestDispatcher("./simple");
The path can be relative to the current request, as in the above example, or it can begin with a “/” in which case it is relative to the root of the webapp. Eg relative to:
From the servlet context:
ServletContext context = getServletContext();
RequestDispatcher dispatcher = context.getRequestDispatcher(“/my_sub_dir/elsewhere”);
The path must be relative to the root of the webapp. Ie. It must start with a “/”
For a specific servlet:
ServletContext context = getServletContext();
RequestDispatcher dispatcher = context.getNamedDispatcher(“servlet name”);
Here the servlet name must match a name given to a servlet in the web.xml file.
In all cases the RequestDispatcher can only be for a resource/servlet in the current webapp. You can't forward to or include an external resource.
Once you’ve obtained a request dispatcher, you can forward to the resource the dispatcher wraps with
Or include the resource with:
As you can see you need to pass the request and the response objects to include or forward so they can be made available to the resource being called.
Please do the following:
1.Create a servlet that outputs a simple message. (Just the message don’t include the whole html page)
2.Create another servlet that outputs a heading, then includes the previous servlet and finally outputs a footer.
3.Try out the difference between obtaining a RequestDispatcher from the request, the servlet context or a named dispatcher.
Filters and RequestDispatchers
As you have seen you can use a Filter to execute some code before passing the request to the request through to the requested resource and to execute some code after the requested resource has been run. However you don’t have to call chain.doFilter at all. You can instead use a request dispatcher to send the request somewhere else.
Create a filter that checks if a request parameter has been passed in. If it has, send the request to the intended destination. If the parameter isn’t passed in send the request to a different servlet using a request dispatcher. This is very similar to the authentication filter you will be setting up in the assignment.
Finally, filters can be passed init parameters similar to servlets. Create a filter that logs all of it’s init params to System.out.
Week 4 Prac – Part 1 – Setting up Derby
For our database we are going to use Apache Derby. If you already have another relational database and JDBC drivers for that database feel free to use that instead. Apache Derby is a free, open-source relational database produced by Apache. It is very small but still supplies all the features we will need.
Pick a directory on your computer and extract Derby there.
Run the following file:
(use the extention .sh instead of .bat if on linux or mac)
You should see a screen like:
Derby is now running and listening for connections on port 1527.
Prac – Part 2 – Setting up the demo servlet
Set up the included servlet JDBCDemo in your Netbeans project. You will most likely have to change the package declaration in the JDBCDemo class to match whatever package you put the class in.
The servlet uses a JDBC driver for Derby. The driver is contained in the JAR file:
You need to make this jar available to your web application. A webapp has access to any jars in either the tomcat lib directory or the webapp's lib directory. That is:
Both these locations are included on the Java classpath for the webapp.
When using a netbeans Web Application Project you can simply add the jar as a library and Netbeans will automatically include it in the webapp's lib directory.
1.In your Netbean's project right click on the libraries folder in the left pane.
2.Select “Add jar/folder”.
3.Navigate to the derbyclient.jar file, select it and click ok
If you now expand “libraries” in the left pane you should see “derbyclient.jar” along with the tomcat and jdk libs.
4.Clean and build your project. You should see a message like the following in the output window.
The file that is being copied to the lib directory is the derby-client. If you wish to check this navigate to the following directory:
5.You should see the derbyclient.jar file.
Now that the derby-client.jar (containing the derby driver) has been included in the web-apps lib directory we need to map some requests to the JDBCDemo servlet. Do this as you have done in previous weeks by adding servlet and servlet-mapping entries to the web.xml file.
Once you have done this run your application and navigate to the servlet in your browser. eg.
You should see something like:
The servlet takes a parameter called “action”. This parameter can have three different values:
1. Create – This does two things, it creates an empty database called “DEMO” then creates a table in this database called “foo-bar” with two columns foo and bar.
2. Add – This takes a request parameter called “foo” and a request parameter called “bar” and inserts them into the table. Use this like:
As the bar column of the table is of type “int”, bar should be a valid integer.
3. List – Lists all the values currently in the table.
Try passing in “create” to create the database and table then pass in “add” a few times to add some values to the table and finally pass in “list” to list all the values in the table. Keep in mind that Derby needs to be running or the servlet won't be able to connect to it and an exception will be thrown.
Prac – Part 3 – The demo code
The following is a description of the jdbc code in the demo servlet. Please open the JDBCDemo class and reference it while reading the following.
This is the standard java sql package. You may also wish to use:
which has extra sql APIs.
//Ensure the JDBC driver is loaded
throw new ServletException(
"An error occurred loading jdbc driver", ex
This loads the JDBC driver class. The Derby JDBC driver is in a class called org.apache.derby.jdbc.ClientDriver in the derbyclient.jar jar file we included above.
ensures that this class is loaded so the DriverManager (discussed below) can find it.
The call to newInstance() is not strictly required, although it is worth putting in as some badly implemented JDBC drivers will fail to load without it.
String attributes = "";
attributes = ";create=true";
Connection conn = DriverManager.getConnection(
"jdbc:derby://localhost:1527/DEMO" + attributes
DriverManager.getConnection returns a Connection. It takes a JDBC URL as a parameter.
The URL consists of:
protocol: The protocol used to communicate with the database. The DriverManager uses this to determine which driver to use.
host: The machine on which the database is running.
database: The name of the database.
attributes: Name value pairs that can be passed to the database. In this case we are passing create=true which tells Derby to create the database if it does not already exist.
The DriverManager looks at the protocol, in this case “jdbc:derby” and attempts to find a driver for this protocol. Once the driver is located it instantiates and returns a Connection to the specified URL.
Statement stmnt = conn.createStatement();
stmnt.execute("insert into foo_bar (foo, bar) values ('" + foo + "', " + bar + ")");
Here we get a Statement object from the Connection with conn.createStatement().
We then use this Statement to execute some sql. The try finally ensures that the statement will be closed even if an exception is thrown.
ResultSet results = stmnt.executeQuery("select foo, bar from foo_bar");
out.write(" : ");
Here we use a statement to execute an sql query. The query’s results are returned as a ResultSet. We then use this ResultSet to iterate over the results and access the values for the result columns.
In all the prac exercises today I want to see Connections and Statements being correctly closed using a try finally block.
Prac – Part 2 - Transactions
When running a statement it may fail for any number of reasons. A typical example is passing in the wrong type for a column. You will often want to run several statements in a single transaction. This means you don’t want any changes saved in the database unless all statements succeed.
To make use of transactions you need to turn off autocommit.
This means that subsequent statements will not be commited (saved) in the database until we call:
It is import to note that once autocommit has been turned off and an update, insert or delete statement has been run the connection cannot be closed. This is because changes have been sent to the database but have not been saved. There are two ways to handle this:
Call conn.commit() to save the changes to the database
Call conn.roleback() to throw away the unsaved changes.
To make use of transactions you will typically:
1.Obtain a connection
2.Turn off autocommit
3.Run the statements you want to be part of the transaction/
4.If all statements ran successfully, commit the changes
5.If a statement failed, ie an exception was thrown, call roleback to throw away any changes made by previous statements.
6.Close the connection
Modify the servlet to take a new action value. When this action is passed in the servlet should run three separate insert,update or delete statements (not select). Use transactions to ensure that if any of the statements fail (throw an Exception) then none of the statements are commited. Hint: Make use of try catch to handle when a statement fails.
Prac – Part 3 – PreparedStatements
PreparedStatements allow you to parameterise the values you are passing in for a statement. An example of a parameterized statement is:
Select * from students where username = ?
You can then set the values for the parameters (The question marks) when you use the statement. This has several advantages. Primarily it allows the database to re-use compiled statements and protects against SQL Injection.
Re-using compiled statements.
When a database receives an sql statement it looks at the text in the statement to see if that same statement has been run before. If it has the database will re-use a compiled version of the statement rather than compiling the statement again. This can have a significant effect on efficiency as compiling an sql statement can take a significant time, especially for complex queries. Keep in mind when I say compiled here I mean inside the database, this has nothing to do with compiling code in your Netbeans project. When checking if the statement has been run before the database simply looks to see if the text that makes up the statement is the same. This means that the following two statements will not be treated as the same:
select * from students where first_name = “John”;
select * from students where first_name = “Jeff”;
PreparedStatements overcome this problem by allowing us to use the same text eg.
Select * from students where first_name = ?
This means that you can use the statement multiple times with different values for the ? and the database will only compile the statement the first time.
This caching of the compiled statements happens in the database. The actual instance of PreparedStatement does not have to be reused. If you make a new instance of PreparedStatement each time you want to run the statement you will still get this advantage as long as the text in the statement is the same.
SQL injection is a serious risk when writing an application that communicates with a database. Imagine if you had the following code:
String username = request.getParameter(“username”);
String password = request.getParameter(“password”);
String sql = “select * from banking_details where username = ‘“ + username “’ and password = ‘“ + password + “’”;
ResultSet results= statement.executeQuery(sql);
This looks ok. The user would have to guess another user’s password to access that
user’s banking details. However what if the user passes in the following queryString:
?username=billgates&password=xxx' or 1 < '2
The sql then becomes:
Select * from banking_details where username = ‘billgates’ and password = ‘xxx' or 1<'2'
This statement would then return Bill Gates banking details. I doubt Bill would be very happy with this.
PreparedStatements protect against this as parameters passed in are treated strictly as values rather than part of the statement. So if you passed in:
‘x’ or 1 < 2
As a parameter of the statement it would be treated as a String not as part of the statement.
Modify the query for adding values to use a PreparedStatement rather than a normal Statement. Use ‘?’’s and set the values being passed in using the PreparedStatement's set methods. Eg.
PreparedStatement prepStatement = conn.prepareStatement(“select * from students where username = ?”);
ResultSet rs = prepStatement.executeQuery();
As always you need to use try catch finally statements to ensure all resources are closed and any exceptions are handled.
In todays practical we looked at the following:
•How to install and start Derby, a Java based relational database.
•How to include the jar file containing the database driver in the lib directory of our webapp so it will be accessible to our code.
•The structure of a JDBC connection string.
•Using the DriverManager class to obtain a Connection using a JDBC connection string.
•Running sql statements using the Statement class.
•Using ResultSets to iterate over the results of sql queries.
•Using try finally statements to ensure that statements and connections are closed even if an exception is thrown.
•Using PreparedStatements to improve performance and/or protect against SQL injection attacks.
•Using transactions to only save the changes made by multiple statements if all the statements suceed.
Congratulations, you now have an understanding of the core JDBC features of Java.