|
Welcome to the Java Developer Connection Java Technology Fundamentals Newsletter.
This monthly newsletter provides a way for you to learn the basics of the Java programming language, discover new resources, and keep up-to-date on the latest additions to the JDC's New to Java Programming Center.
For more Java technology content, visit these sites:
java.sun.com - The latest Java platform releases, tutorials, and newsletters.
java.net - A web forum for collaborating and building solutions together.
java.com - The marketplace for Java technology, applications and services.
Java Programming Language Basics
Working with Assertions
The Java 2 Platform, Standard Edition (J2SE) provides an assertion facility. Introduced with the 1.4 version of J2SE, one can think of the assertion facility as an advanced form of exception handling. Assertions represent are boolean expressions that a programmer believes to be true at specific points in the program. Is variable anInt greater than 2, for instance. The facility to check an assertion can be enabled or disabled at any time, so you might test the application with them enabled, and deploy with them disabled.
Assertion checking is like exception handling, but no exceptions are thrown if assertions fail. Instead, an AssertionError is thrown, and no try-catch block is necessary.
There are two basic constructs when using assertions:
assert booleanExpression;
assert booleanExpression : message;
You might add an assertion statement as the pre- or post-condition of a method. The boolean expression may also call a method. Other obvious places are else conditions in if blocks, where conditions are assumed, or default cases of a switch statement, which should never be reached. The only limitation of the assert keyword is that it must be in an executable block. It can’t be with class variable declarations for instance, but can be within any method declaration.
Using assertions to compile and run your programs requires the use of some special command line options. To compile your program, you must pass the compiler a -source 1.4 setting. By default, the compiler runs in 1.3 compatibility mode. You must explicitly request the 1.4 source mode. Then, at runtime, you must explicitly enable assertion checking with the enableassertions option, or the shorter –ea option, as by default assertion checking is disabled.
Here’s a simple example that walks you through the necessary steps. It checks on the number of command line arguments and reports a problem if the count isn’t 0.
public class AssertTest {
public static void main(String args[]) {
assert args.length == 0 : args.length + " != 0";
System.out.println(args.length);
}
}
To compile the program, be sure to use the -source option. javac -source 1.4 AssertTest.java
To test the program, just run the program and pass command line arguments:
java -ea AssertTest 1 2 3 4
This will report 4 since assert checking at runtime is disabled by default.
Now, if you run the program with assertion checking enabled, you’ll see the error message:
java -ea AssertTest 1 2 3 4
Reports the following problem:
Exception in thread "main" java.lang.AssertionError: 4 != 0
at AssertTest.main(AssertTest.java:3)
Essentially, that is the whole assertion facility. The hardest part is figuring out where to put the assert keywords.
While the -ea option is an easy way to enable assertions for an entire program, there are other options available. Also, ea doesn’t work for system classes; for that, you need to use enablesystemassertions, or more easily esa.
To enable assertions for an entire package tree (the package and all subpackages), you can follow the -ea option with a colon, the name of the package, and an ellipsis. For instance, the following will enable assertion checking for the net.java.util package, and all its subpackages.
java –ea:net.java.util... MyJava
For a specific class, you would just specify the full class name, instead of ending the package name with the three periods.
If you want to enable assertion checking for a whole set of packages but not for a class or package (tree), that’s where the –da tag comes into play. Just list the enabling and disabling options and you’re all set. For instance, the following enables assertion checking for the net.java.util package, but not the net.java.util.Math class.
java –ea:net.java.util... –da:net.java.util.Math MyClass
In addition to enabling assertion checking from the command line, you can also programmatically enable (or disable) checking. This only affects classes loaded in the future, so this isn’t something that can be just turned on and off at will.
The ClassLoader of the class controls the enabling and disabling of assertions through the following four methods:
setDefaultAssertionStatus()
This sets the default status for packages and classes loaded by the class loader. This setting can be overwritten by setting the specific package and class options.
setPackageAssertionStatus()
To override the status for a package and all its subpackages, pass in the package name and enabling status. Providing a null package name sets the assertion status for the unnamed package.
setClassAssertionStatus()
To override the status for a specific class, pass in the fully-qualified class name and enabling status.
clearAssertionStatus()
Resets all package and class settings to false, and then resets the class loader to setting false also.
To get the class loader for a class, call the getClassLoader() method of the Class object. In a non-static method, this would be done with the following:
ClassLoader loader = getClass().getClassLoader();
For a static method, you can’t call getClass() as you don’t have an instance, so you just add .class to the end of your current class name:
ClassLoader loader = MyClass.class.getClassLoader();
Just remember that this only has an effect on classes loaded after the change. In most cases, you’ll find yourself just enabling things from the command line.
What’s left with assertion checking? Just learning where to put them, really. This just takes practice. If you want to watch for special cases that typically shouldn’t happen and don’t overload code with if-blocks, assertion checking is a good way to go. Just don’t overuse them as it does bulk of the .class file sizes.
Java Bits
Introducing JavaServer Pages Technologies
JavaServer Pages (JSP) technology enables web developers and designers to develop and maintain dynamic web pages. JSP technology separates the user interface from content generation, so that designers can change the overall page layout without altering the underlying dynamic content.
JSP pages are frequently used to process forms, build single web pages from different files, get live content from other sites, validate information, personalize content, grab data from databases, create interactive quizzes or polls, and more.
In the past, web developers used Perl or similar languages for dynamic web site functionality, but JSP pages provide an easy way for developers to do the same things and more using the Java programming language. You can even incorporate JavaBeans or use JSP pages and servlets together. In fact, when a JSP is compiled by the server, it is compiled into a servlet. More on servlets below.
To create JSP pages, you can use a simple text editor or Sun's Java Studio Creator. The latter comes with everything you need for creating, running, and testing JSPs. If you prefer, you can use your favorite text editor for creating JSPs, but to run and test you need a web server.
Download either Sun's Java Studio Creator, or Tomcat, so you can follow this article and run the code sample. Both are free of charge:
Sun Java Studio Creator
Tomcat @ Jakarta
A JSP page contains static content such as HTML and JSP elements for generating the dynamtic content of of the page. Neither the JSP page or HTML code has any dependencies on the other.
Before a JSP is sent to a client, the server processes the JSP elements, converting and compiling them into a servlet. Once compiled, the JSP code is executed and the static and dynamic content is merged. The resulting response is then sent to the client.
To insert Java code in with HTML code, you need to use special identifiers to enclose your code and you need to save the page with a .jsp extension. There are various identifiers available, depending on what you are trying to code, but for simplicity in this article, you're only going to learn those used with scriptlets.
Scriptlets are blocks of code, enclosed with the following identifiers:
<% start identifier
%> close identifier
Place the Java code you've been learning between identifiers.
When you use scripting elements, you automatically have a number of objects available to you from the web server, no matter which server software you're using. The only instances of classes you need to be aware of for this article are:
javax.servlet.http.HttpServletRequest
javax.servlet.http.HttpServletResponse
These classes provide many useful methods for creating JSP applications. You'll use the getParameter method in the example below.
To demonstrate how to put JSP pages to use, see how this online quiz is built. The quiz requires two pages:
- An HTML page to format quiz questions, and possible answers with radio buttons. The Submit button calls the JSP page.
- The JSP page gets the user's responses from the form through the
getParameter method, processes which question answers are correct or incorrect, then sends back a response page, letting the user know how he or she scored.
First, a straight-forward HTML quiz page:
The HTML Quiz Page:
<html>
<head>
<title>Quiz</title>
</head>
<body>
<h2>JavaServer Pages Quiz</h2>
<p>
<-- Note that action calls the JSP -->
<form name="jspquiz" method="POST" action="checkanswers.jsp">
<br>
1. What is the purpose of a JavaServer Page (JSP)?
<br>
<input type="radio" value="1" name="q1">
Provides an entry point for web site
<br><input type="radio" value="2" name="q1">
Allows you to create dynamic web pages
<br><input type="radio" value="3" name="q1">
Creates a JavaBean
<p>2. What type of software to I need to test and run JSP pages?
<br>
<input type="radio" value="1" name="q2">
Just the J2SE download
<br><input type="radio" value="2" name="q2">
My favorite text editor
<br><input type="radio" value="3" name="q2">
Sun's Java Studio Creator, Tomcat, or some other server software
<p>3. Can I use JavaBeans with my JSP pages?
<br>
<input type="radio" value="1" name="q3">
Only when a Swing interface is created
<br><input type="radio" value="2" name="q3">
The JSP specification includes standard tags for bean use and
manipulation
<br><input type="radio" value="3" name="q3">
Absolutely not
<p>
<input type="submit" value="Submit" name="submitButton"> </form>
</body>
</html>
Now, create the checkanswers.jsp page:
<html>
<head><title>Quiz Answers</title></head>
<body>
<h3>Quiz Answers</h3><p>
<%-- This is a JSP comment. Note the identifiers --%>
<%-- An array is created for correct and incorrect answers --%>
<%-- Also note the request.getParameter method calls --%>
<%!
int [] CorrectAnswers;
int [] UsersAnswers;
int score;
%>
<%
score=0;
CorrectAnswers = new int[3];
UsersAnswers = new int[3];
CorrectAnswers[0] = 2;
CorrectAnswers[1] = 3;
CorrectAnswers[2] = 2;
UsersAnswers[0] = Integer.parseInt(request.getParameter("q1"));
UsersAnswers[1] = Integer.parseInt(request.getParameter("q2"));
UsersAnswers[2] = Integer.parseInt(request.getParameter("q3"));
for (int i = 0; i < CorrectAnswers.length; i++)
{
if (CorrectAnswers[i]==UsersAnswers[i])
score = score + 1;
}
%>
You got <%=score %> correct out of <%=CorrectAnswers.length %>
<p>
</body>
</html>
the code is plain Java programming you've been learning, with variables, arrays, and if statements. The request.getParameter method retrieves the answer for each question. The loop iterates through the questions, then the if statement compares the array of CorrectAnswers against the array of UserAnswers. An int of 1 is added for every correct response.
Lastly, the variable score is printed to the screen along with the rest of the HTML content.
Check your server software to save these two files in the correct directories, then bring up the HTML page in your browser and take the test.
See this quiz live on java.sun.com
Making Sense of the Java Class
Servlets and the javax.servlet.http Package
A servlet can be thought of as an applet that runs on the server side--without a face. Since servlets run inside servers, they do not need a graphical user interface. They are Java application components which are downloaded, on demand, to the part of the system which needs them. Although all servlets are written in the Java programming language, their clients may be written in any language.
Servlets support the familiar programming model of accepting requests and generating responses. This model is used with a variety of distributed system programming toolsets, ranging from remote procedure calls to the HTTP requests made to web servers.
The javax.servlet package and the javax.servlet.http package provide the classes and interfaces to define servlets. HTML servlet classes extend the javax.servlet.http.HttpServlet abstract class, which provides a framework for handling HTTP protocol.
The javax.servlet.http package provides the following interfaces and classes:
Interfaces:
HttpServletRequest
HttpServletResponse
HttpSession
HttpSessionBindingListener
HttpSessionContext
Classes:
Cookie
HttpServlet
HttpSessionBindingEvent
HttpUtils
The servlet container creates an HttpServletRequest object and passes it as an argument to the servlet's service methods: doGet, doPost, and so forth.
The class HttpServlet provides an abstract class to be subclassed to create an HTTP servlet suitable for a web site. A subclass of HttpServlet must override at least one method, usually one of these:
doGet, if the servlet supports HTTP GET requests
doPost, for HTTP POST requests
doPut, for HTTP PUT requests
doDelete, for HTTP DELETE requests
init and destroy, to manage resources that are held for the life of the servlet
getServletInfo, which the servlet uses to provide information about itself
There's almost no reason to override the service method. service handles standard HTTP requests by dispatching them to the handler methods for each HTTP request type. Servlets typically run on multitude servers, so be aware that a servlet must handle concurrent requests. Be careful to synchronize access shared resources. Shared resources include in-memory data such as instance or class variables and external objects such as files, database connections, and network connections.
The following example allows the user to enter text in a forum, then returns an HTML page with the text when the user clicks the button.
<HTML>
<HEAD>
<TITLE>Example</TITLE>
</HEAD>
<BODY BGCOLOR="WHITE">
<TABLE BORDER="2" CELLPADDING="2">
<TR><TD WIDTH="275">
<H2>I'm a Form</H2>
Enter some text and click the Submit button.<BR>
Clicking Submit invokes the servlet,<BR>
which returns an HTML page to the browser.
<FORM METHOD="POST" ACTION="/servlet/ExampServlet">
<INPUT TYPE="TEXT" NAME="DATA" SIZE=30>
<P>
<INPUT TYPE="SUBMIT" VALUE="Click Me">
<INPUT TYPE="RESET">
</FORM>
</TD></TR>
</TABLE>
</BODY>
</HTML>
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ExampServlet extends HttpServlet {
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<title>Example</title>" +
"<body bgcolor=FFFFFF>");
out.println("<h2>Button Clicked</h2>");
String DATA = request.getParameter("DATA");
if(DATA != null){
out.println(DATA);
} else {
out.println("No text entered.");
}
out.println("<P>Return to <A
HREF=../simpleHTML.html>Form</A>");
out.close();
}
}
Check your servlet container software for where you need to store your servlet. See For More Information for a list of articles and tutorials on creating servlets.
Program Challenge
The biggest trick with assertions is figuring out where to add them, identifying the pre/post conditions, as well as the internal, class, and control-flow invariants. Instead of creating a program from scratch, take the solution from a prior challenge and add assertions to it.
Last month's code:
import java.io.*;
import java.util.*;
import java.util.zip.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
public class ZipTable {
private static class FrameShower implements Runnable {
final Frame frame;
public FrameShower(Frame frame) {
this.frame = frame;
}
public void run() {
frame.setVisible(true);
}
}
public static void main(String args[]) {
final JFrame frame = new JFrame("Zip Me");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = frame.getContentPane();
final ZipTableModel model = new ZipTableModel();
JTable table = new JTable(model);
JScrollPane pane = new JScrollPane(table);
contentPane.add(pane, BorderLayout.CENTER);
JButton button = new JButton("Pick Zip");
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
loadTable(frame, model);
}
};
button.addActionListener(listener);
contentPane.add(button, BorderLayout.SOUTH);
frame.setSize(400, 400);
Runnable runner = new FrameShower(frame);
EventQueue.invokeLater(runner);
}
private static void loadTable(Frame frame, ZipTableModel model) {
JFileChooser fileChooser = new JFileChooser(".");
int status = fileChooser.showOpenDialog(frame);
if (status == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
try {
model.setFile(file);
} catch (IOException e) {
System.err.println("Unable to load zip: " + file.getName());
}
}
}
private static String compressionMethod(int method) {
String returnValue;
if (method == ZipEntry.STORED) {
returnValue = "Stored";
} else if (method == ZipEntry.DEFLATED) {
returnValue = "Deflated";
} else {
returnValue = "Unknown";
}
return returnValue;
}
private static class ZipTableModel extends AbstractTableModel {
String columns[] = {"Name", "Time", "Size", "Compressed Size",
"Method"};
ZipEntry entries[];
ZipFile zip;
public ZipTableModel() {
}
public ZipTableModel(File file) throws IOException {
setFile(file);
}
public int getColumnCount() {
return columns.length;
}
public String getColumnName(int column) {
return columns[column];
}
public int getRowCount() {
if (zip == null) {
return 0;
} else {
return zip.size();
}
}
public void setFile(File file) throws IOException {
zip = new ZipFile(file);
entries = null;
fireTableChanged(new TableModelEvent(this));
}
public Object getValueAt(int row, int column) {
if (zip == null) {
return null;
} else if (entries == null) {
loadEntries();
}
if (column == 0) {
return entries[row].getName();
} else if (column == 1) {
return new Date(entries[row].getTime());
} else if (column == 2) {
return new Long(entries[row].getSize());
} else if (column == 3) {
return new Long(entries[row].getCompressedSize());
} else {
return compressionMethod(entries[row].getMethod());
}
}
private void loadEntries() {
entries = new ZipEntry[getRowCount()];
int count = 0;
Enumeration enum = zip.entries();
while (enum.hasMoreElements()) {
entries[count++] = (ZipEntry)enum.nextElement();
};
}
}
}
See a possible solution to the Challenge
Sun's Courses
Implementing Intermediate Java Programming Language Concepts
This course is designed for students with little or no programming experience who want to continue learning to program using the Java programming language. You'll learn intermediate object-oriented programming (OOP) concepts, such as inheritance and encapsulation. Additionally, arrays are introduced as a method for storing and accessing similar data.
» Find out more:
Online Chats
Missed the Open Source APIs for Java Technology Games Chat?
You can read the archived chat here
For More Information
Downloading the Java 2 Platform
For most Java development, you need the class libraries, compiler, tools, and runtime environment provided with the J2SE development kit.
Find archived issues of the following Java technology developer newsletters or manage your current newsletter subscriptions: https://softwarereg.sun.com/registration/developer/en_US/subscriptions
Subscribe to the following newsletters for the latest information about technologies and products in other Java platforms:
- Core Java Technologies Newsletter. Learn about new products, tools, resources, and events of interest to developers working with core Java technologies.
- Wireless Developer Newsletter. Learn about the latest releases, tools, and resources for developers working on wireless and Java Card technologies and applications.
- Core Java Technologies Tech Tips (formerly JDC Tech Tips) Get expert tips, sample code solutions, and techniques for developing in the Java 2 Platform, Standard Edition (J2SE)
You can subscribe to these and other JDC publications on the JDC Newsletters and Publications
page
PRIVACY STATEMENT:
Sun respects your online time and privacy. You have received this based on your e-mail preferences. If you would prefer not to receive this information, please follow the steps at the bottom of this message to unsubscribe.
IMPORTANT: Please read our Terms of Use, Privacy, and Licensing policies:
http://www.sun.com/share/text/termsofuse.html
http://www.sun.com/privacy/
http://developer.java.sun.com/berkeley_license.html
Copyright 2004 Sun Microsystems,
Inc. All rights reserved. 4150 Network Circle, Santa Clara, CA 95054
FEEDBACK
Comments? Send your feedback on the Java Technology Fundamentals Newsletter to: dana.nourie@sun.com
SUBSCRIBE/UNSUBSCRIBE
- To subscribe, go to the subscriptions page, choose the newsletters you want to subscribe to and click Update
- To unsubscribe, go to the subscriptions page, uncheck the appropriate check box, and click Update
Trademark Information: http://www.sun.com/suntrademarks/
Java, J2EE, J2SE, J2ME, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.
|