Composition and Inheritance

Objects and Java by Bill Venners
Chapter 6:
Composition and Inheritance

Modeling the relationships between types is a fundamental part of the process of object-oriented design. This chapter shows you how to model relationships using composition and inheritance. It describes many facets of inheritance in Java, including abstract classes and final classes. [bv:need better intro]

Composition

As you progress in an object-oriented design, you will likely encounter objects in the problem domain that contain other objects. In this situation you will be drawn to modeling a similar arrangement in the design of your solution. In an object-oriented design of a Java program, the way in which you model objects that contain other objects is with composition, the act of composing a class out of references to other objects. With composition, references to the constituent objects become fields of the containing object.

For example, it might be useful if the coffee cup object of your program could contain coffee. Coffee itself could be a distinct class, which your program could instantiate. You would award coffee with a type if it exhibits behavior that is important to your solution. Perhaps it will swirl one way or another when stirred, keep track of a temperature that changes over time, or keep track of the proportions of coffee and any additives such as cream and sugar.

To use composition in Java, you use instance variables of one object to hold references to other objects. For the CoffeeCupexample, you could create a field for coffee within the definition of class CoffeeCup, as shown below: [bv: implement the methods]

// In Source Packet in file inherit/ex1/CoffeeCup.java
class CoffeeCup {

    private Coffee innerCoffee;

    public void addCoffee(Coffee newCoffee) {
        // no implementation yet
    }

    public Coffee releaseOneSip(int sipSize) {
        // no implementation yet
        // (need a return so it will compile)
        return null;
    }

    public Coffee spillEntireContents() {
        // no implementation yet
        // (need a return so it will compile)
        return null;
    }
}

// In Source Packet in file inherit/ex1/Coffee.java
public class Coffee {

    private int mlCoffee;

    public void add(int amount) {
        // No implementation yet
    }

    public int remove(int amount) {
        // No implementation yet
        // (return 0 so it will compile)
        return 0;
    }

    public int removeAll() {
        // No implementation yet
        // (return 0 so it will compile)
        return 0;
    }
}

In the example above, the CoffeeCup class contains a reference to one other object, an object of type Coffee. Class Coffeeis defined is a separate source file.

The relationship modeled by composition is often referred to as the “has-a” relationship. In this case a CoffeeCup has Coffee. As you can see from this example, the has-a relationship doesn’t mean that the containing object must have a constituent object at all times, but that the containing object may have a constituent object at some time. Therefore the CoffeeCup may at some time contain Coffee, but it need not contain Coffee all the time. (When a CoffeeCup object doesn’t contain Coffee, its innerCoffee field is null.) In addition, note that the object contained can change throughout the course of the containing object’s life.

[bv: need to add UML diagram for composition, and explain the difference between composition and agregation and why I draw my diagrams like I do.]

Inheritance

As you partition your problem domain into types you will likely want to model relationships in which one type is a more specific or specialized version of another. For example you may have identified in your problem domain two types, Cup and CoffeeCup, and you want to be able to express in your solution that a CoffeeCup is a more specific kind of Cup (or a special kind of Cup). In an object-oriented design, you model this kind of relationship between types with inheritance.

Building Inheritance Hierarchies

The relationship modeled by inheritance is often referred to as the “is-a” relationship. In the case of Cup and CoffeeCup, a “CoffeeCup is-a Cup.” Inheritance allows you to build hierarchies of classes, such as the one shown in Figure 5-1. The upside-down tree structure shown in Figure 5-1 is an example of an inheritance hierarchy displayed in UML form. Note that the classes become increasingly more specific as you traverse down the tree. A CoffeeCup is a more specific kind of Cup. A CoffeeMug is a more specific kind of CoffeeCup. Note also that the is-a relationship holds even for classes that are connected in the tree through other classes. For instance, a CoffeeMug is not only more specific version of a CoffeeCup, it is also a more specific version of a Cup. Therefore, the is-a relationship exists between CoffeeMug and Cup: a CoffeeMug is-a Cup.


Figure 5-1. The is-a relationship of inheritance

[bv: mention this is a UML diagram]

When programming in Java, you express the inheritance relationship with the extends keyword:

class Cup {
}
class CoffeeCup extends Cup {
}
class CoffeeMug extends CoffeeCup {
}

In Java terminology, a more general class in an inheritance hierarchy is called a superclass. A more specific class is a subclass. In Figure 5-1, Cup is a superclass of both CoffeeCup and CoffeeMug. Going in the opposite direction, both CoffeeMug and CoffeeCup are subclasses of Cup. When two classes are right next to each other in the inheritance hierarchy, their relationship is said to be direct. For example Cup is a direct superclass of CoffeeCup, and CoffeeMug is a direct subclass of CoffeeCup.

The act of declaring a direct subclass is referred to in Java circles as class extension. For example, a Java guru might be overheard saying, “Class CoffeeCup extends class Cup.” Owing to the flexibility of the English language, Java in-the-knows may also employ the term “subclass” as a verb, as in “Class CoffeeCup subclasses class Cup.” One other way to say the same thing is, “Class CoffeeCup descends from class Cup.”

An inheritance hierarchy, such as the one shown in Figure 5-1, defines a family of types. The most general class in a family of types–the one at the root of the inheritance hierarchy–is called the base class. In Figure 5-1, the base class is Cup. Because every class defines a new type, you can use the word “type” in many places you can use “class.” For example, a base class is a base type, a subclass is a subtype, and a direct superclass is a direct supertype.

In Java, every class descends from one common base class: Object. The declaration of class Cup above could have been written:

class Cup extends Object { // "extends Object" is optional
}

This declaration of Cup has the same effect as the earlier one that excluded the “extends Object” clause. If a class is declared with no extends clause, it by default extends the Object class. (The only exception to this rule is class Object itself, which has no superclass.) The inheritance hierarchy of Figure 5-1 could also have shown the Object class hovering above the Cup class, in its rightful place as the most super of all superclasses. In this case, class Object remained invisible, because the purpose of the figure was to focus on one particular family of types, the Cup family.

In Java, a class can have only one direct superclass. In object-oriented parlance, this is referred to as single inheritance . It contrasts with multiple inheritance , in which a class can have multiple direct superclasses. Although Java only supports single inheritance of classes through class extension, it supports a special variant of multiple inheritance through “interface implementation.” Java interfaces, and how a class implements them, will be discussed in Chapter 7.

Inheriting interface and implementation

Modeling an is-a relationship is called inheritance because the subclass inherits the interface and, by default, the implementation of the superclass. Inheritance of interface guarantees that a subclass can accept all the same messages as its superclass. A subclass object can, in fact, be used anywhere a superclass object is called for. For example, a CoffeeCup as defined in Figure 5-1 can be used anywhere a Cup is needed. This substitutability of a subclass (a more specific type) for a superclass (a more general type) works because the subclass accepts all the same messages as the superclass. In a Java program, this means you can invoke on a subclass object any method you can invoke on the superclass object.

This is only half of the inheritance story, however, because by default, a subclass also inherits the entire implementation of the superclass. This means that not only does a subclass accept the same messages as its direct superclass, but by default it behaves identically to its direct superclass when it receives one of those messages. Yet unlike inheritance of interface, which is certain, inheritance of implementation is optional. For each method inherited from a superclass, a subclass may choose to adopt the inherited implementation, or to override it. To override a method, the subclass merely implements its own version of the method.

Overiding methods is a primary way a subclass specializes its behavior with respect to its superclass. A subclass has one other way to specialize besides overriding the implementation of methods that exist in its direct superclass. It can also extend the superclass’s interface by adding new methods. This possibility will be discussed in detail later in the next chapter.

Suppose there is a method in class Cup with the following signature:

public void addLiquid(Liquid liq) {
}

The addLiquid() method could be invoked on any Cup object. Because CoffeeCup descends from Cup, the addLiquid()method could also be invoked on any CoffeeCup object.

If you do not explicitly define in class CoffeeCup a method with an identical signature and return type as the addLiquid()method shown above, your CoffeeCup class will inherit the same implementation (the same body of code) used by superclass Cup. If, however, you do define in CoffeeCup an addLiquid() method with the same signature and return type, that implementation overrides the implementation that would otherwise have been inherited by default from Cup.

When you override a method, you can make the access permission more public, but you cannot make it less public. So far, you have only been introduced to two access levels, public and private. There are, however, two other access levels that sit in-between public and private, which form the two ends of the access-level spectrum. (All four access levels will be discussed together in Chapter 8.). In the case of the addLiquid() method, because class Cup declares it with public access, class CoffeeCup must declare it public also. If CoffeeCup attempted to override addLiquid() with any other access level, class CoffeeCup wouldn’t compile.

For an illustration of the difference between inheriting and overriding the implementation of a method, see Figure 5-2. The left side of this figure shows an example of inheriting an implementation, whereas the right side shows an example of overriding the implementation.

The method in question is the familiar addLiquid() method. In the superclass, Cup, a comment indicates that the code of the method, which is not shown in the figure, will cause the liquid to swirl clockwise as it is added to the cup. Liquid added to an instance of the CoffeeCup class defined on the left will also swirl clockwise, because that CoffeeCup inherits Cup‘s implementation of addLiquid(), which swirls clockwise. By contrast, liquid added to an instance of the CoffeeCup class defined on the right will swirl counterclockwise, because this CoffeeCup class overrides Cup‘s implementation with one of its own. A more advanced CoffeeCup could override addLiquid() with an implementation that first checks to see whether the coffee cup is in the northern or southern hemisphere of the planet, and based on that information, decide which way to swirl.


Figure 5-2. Inheriting vs. overriding the implementation of a method

In addition to the bodies of public methods, the implementation of a class includes any private methods and any fields defined in the class. Using the official Java meaning of the term “inherit,” a subclass does not inherit private members of its superclass. It only inherits accessible members. Well- designed classes most often refuse other classes direct access to their non-constant fields, and this policy generally extends to subclasses as well. If a superclass has private fields, those fields will be part of the object data in its subclasses, but they will not be “inherited” by the subclass. Methods defined in the subclasses will not be able to directly access them. Subclasses, just like any other class, will have to access the superclass’s private fields indirectly, through the superclass’s methods.

Hiding Fields

If you define a field in a subclass that has the same name as an accessible field in its superclass, the subclass’s field hides the superclass’s version. (The type of the variables need not match, just the names.) For example, if a superclass declares a public field, subclasses will either inherit or hide it. (You can’t override a field.) If a subclass hides a field, the superclass’s version is still part of the subclass’s object data; however, the subclass doesn’t “inherit” the superclass’s version of the field, because methods in the subclass can’t access the superclass’s version of the field by its simple name. They can only access the subclass’s version of the field by its simple name. You can access the superclass’s version by qualifying the simple name with the super keyword, as in super.fieldName. (More on super in the next section.)

Java permits you to declare a field in a subclass with the same name as a field in a superclass so you can add fields to a class without worrying about breaking compatibility with already existing subclasses. For example, you may publish a library of classes that your customers can use in their programs. If your customers subclass the classes in your library, you will likely have no idea what new fields they have declared in their subclasses. In making enhancements to your library, you may inadvertently add a field that has the same name as a field in one of your customer’s subclasses. If Java didn’t permit field hiding, the next time you released your library, your customer’s program might not run properly, because the like- named field in the subclass would clash with the new field in the superclass from your library. Java’s willingness to tolerate hidden fields makes subclasses more accepting of changes in their superclasses.

[bv: See Behind the Scenes in this chapter for a description of object images on a JVM heap?]

Abstract Classes and Methods

As you perform an object-oriented design, you may come across classes of objects that you would never want to instantiate. Those classes will nevertheless occupy a place in your hierarchies. An example of such a class might be the Liquid class from the previous discussions. Class Liquid served as a base class for the family of types that included subclasses CoffeeMilk, and Tea. While you can picture a customer walking into a caf� and ordering a coffee, a milk, or a tea, you might find it unlikely that a customer would come in and order a “liquid.” You might also find it difficult to imagine how you would serve a “liquid.” What would it look like? How would it taste? How would it swirl or gurgle?

Java provides a way to declare a class as conceptual only, not one that represents actual objects, but one that represents a category of types. Such classes are called abstract classes. To mark a class as abstract in Java, you merely declare it with the abstract keyword. The abstract keyword indicates the class should not be instantiated. Neither the Java compiler nor the Java Virtual Machine will allow an abstract class to be instantiated. The syntax is straightforward:

// In Source Packet in file inherit/ex6/Liquid.java
abstract class Liquid {

    void swirl(boolean clockwise) {
        System.out.println("One Liquid object is swirling.");
    }

    static void gurgle() {
        System.out.println("All Liquid objects are gurgling.");
    }
}

The above code makes Liquid a place holder in the family tree, unable to be an object in its own right.

Note that the Liquid class shown above still intends to implement a default behavior for swirling and gurgling. This is perfectly fine, however, classes are often made abstract when it doesn’t make sense to implement all of the methods of the class’s interface. The abstract keyword can be used on methods as well as classes, to indicate the method is part of the interface of the class, but does not have any implementation in that class. Any class with one or more abstract methods is itself abstract and must be declared as such. In the Liquid class, you may decide that there is no such thing as a default swirling behavior that all liquids share. If so, you can declare the swirl() method abstract and forgo an implementation, as shown below:

// In Source Packet in file inherit/ex7/Liquid.java
abstract class Liquid {

    abstract void swirl(boolean clockwise);

    static void gurgle() {
        System.out.println("All Liquid objects are gurgling.");
    }
}

In the above declaration of Liquid, the swirl() method is part of Liquid‘s interface, but doesn’t have an implementation. Any subclasses that descend from the Liquid class shown above will have to either implement swirl() or declare themselves abstract. For example, if you decided there were so many varieties of coffee that there is no sensible default implementation for Coffee, you could neglect to implement swirl() in Coffee. In that case, however, you would need to declare Coffee abstract. If you didn’t, you would get a compiler error when you attempted to compile the Coffee class. You would have to subclass Coffee (for example: Latte, Espresso, CafeAuLait) and implement swirl() in the subclasses, if you wanted the Coffee type to ever see any action.

Most often you will place abstract classes at the upper regions of your inheritance hierarchy, and non- abstract classes at the bottom. Nevertheless, Java does allow you to declare an abstract subclass of a non- abstract superclass. For example, you can declare a method inherited from a non-abstract superclass as abstract in the subclass, thereby rendering the method abstract at that point in the inheritance hierarchy. This design implies that the default implementation of the method is not applicable to that section of the hierarchy. As long as you implement the method again further down the hierarchy, this design would yield an abstract class sandwiched in the inheritance hierarchy between a non-abstract superclass and non- abstract subclasses.

Final Classes and Methods

Most Java programmers have two hats on their shelf, both of which they wear at different times. Sometimes they wear their “designer” hat, and build libraries of classes for others to use. Other times they wear their “client” hat, and make use of a library of classes created by someone else. Some Java programmers even wear both hats at the same time, completely oblivious to the rules of fashion.

When you put on your “designer” hat and work to build a library of classes that will be distributed to people you don’t know and don’t necessarily trust, you will likely encounter situations in which you want to prevent a client from declaring a subclass of one of the classes in your library. Or you might want to allow a client to declare a subclass, but you want to prevent them from overriding specific methods of the superclass. The reason you’ll feel the need for this kind of control is that a client could take advantage of polymorphism to effectively change the behavior of the classes in your library. For example, a swirl() method of a hot beverage object could be redefined to swirl right out of the cup and dampen or possibly even scald a customer. Fortunately, Java gives you the final keyword to prevent just such nightmarish scenarios as that.

If you declare a method final, no subclass will be allowed to override that method. If you declare an entire class final, no other class will be allowed to extend it. In other words, a class declared final cannot be subclassed. In an inheritance diagram, a final class is the end of the line. No other classes will appear below it. Subclasses can appear below a non-finalclass that contains a final method, but every subclass will inherit the final implementation of the method.

Because marking a class or method final is so restrictive to clients of the class, you should use it with caution. Only if you are certain you want to absolutely prevent clients from declaring a subclass or overriding a method should you use the finalkeyword on a class or method.

Initialization and inheritance
When an object is initialized, all the instance variables defined in the object’s class must be set to proper initial values. While this is necessary, often it is not enough to yield a fully initialized class. An object incorporates not only the fields explicitly declared in its class, but also those declared in its superclasses. To fully initialize an object, therefore, all instance variables declared in its class and in all its superclasses must be initialized.

Instance data of objects
Every object, except class Object itself, has at least one superclass. When an object is created, the Java virtual machine allocates enough space for all the object’s instance variables, which include all fields defined in the object’s class and in all its superclasses. For example, consider the following classes:

// Declared in file Object.java (not In source packet)
package java.lang;
public class Object {
    // Has no fields
    // Has several methods, not shown...
}

// In source packet in file init/ex14/Liquid.java
class Liquid {
    // Has two fields:
    private int mlVolume;
    private float temperature; // in Celsius
    // Has several methods, not shown...
}

// In source packet in file init/ex14/Coffee.java
class Coffee extends Liquid {
    // Has two fields:
    private boolean swirling;
    private boolean clockwise;
    // Has several methods, not shown...
}
 
Figure 4-1. Class Coffee‘s superclasses and fields

You can see the inheritance hierarchy for class Coffee, as defined above, in Figure 1. This figure, as well as the code above, shows Object as having no instance variables. But it is possible that Object could have instance variables. The actual internal make-up of class Object is a detail specific to each Java platform implementation. It is extremely likely, however, that Objectwill have no fields in any given Java platform implementation. Because Object is the superclass of all other objects, any fields declared in Object must be allocated for every object used by every Java program.

In Figure 2, you can see the data that must be allocated on the heap for a Coffee object. The part of the heap that is occupied by the instance data for the Coffee object is shown in the cyan color. Keep in mind that the actual manner of representing objects on the heap is an implementation detail of each particular Java virtual machine. This figure represents just one of many possible schemes for storing objects on the heap inside the JVM.

 
Figure 4-2. Instance data for a Coffee object

Figure 2 shows that the instance data for a Coffee object includes each instance variable defined in class Coffee and each of Coffee‘s superclasses. Both of Liquid‘s fields, mlVolume and temperature, are part of the Coffee object’s data, as well as Coffee‘s fields: swirling and clockwise. This is true even though Coffee doesn’t actually inherit the mlVolume and temperature fields from class Liquid.

A note on the word “inherit”
In Java jargon, the word “inherit” has a restricted meaning. A subclass inherits only accessible members of its superclasses — and only if the subclass doesn’t override or hide those accessible members. A class’s members are the fields and methods actually declared in the class, plus any fields and methods it inherits from superclasses. In this case, because Liquid‘s mlVolume and temperature fields are private, they are not accessible to class CoffeeCoffee does not inherit those fields. As a result, the methods declared in class Coffee can’t directly access those fields. Despite this, those fields are still part of the instance data of a Coffee object.

Pointers to class data
Figure 2 also shows, as part of the instance data of the Coffee object, a mysterious 4-byte quantity labeled “native pointer to class information.” Every Java virtual machine must have the capability to determine information about its class, given only a reference to an object. This is needed for many reasons, including type-safe casting and the instanceof operator.

Figure 2 illustrates one way in which a Java virtual machine implementation could associate class information with the instance data for an object. In this figure, a native pointer to a data structure containing class information is stored along with the instance variables for an object. The details in which the various ways a JVM could connect an object’s data with its class information are beyond the scope of this article. The important thing to understand here is that class information will in some way be associated with the instance data of objects, and that the instance data includes fields for an object’s class and all its superclasses.

Initializing fields in superclasses
Each class contains code to initialize the fields explicitly declared in that class. Unlike methods, constructors are never inherited. If you don’t explicitly declare a constructor in a class, that class will not inherit a constructor from its direct superclass. Instead, the compiler will generate a default constructor for that class. This is because a superclass constructor can’t initialize fields in the subclass. A subclass must have its own constructor to initialize its own instance variables. In the class file, this translates to: every class has at least one <init> method responsible for initializing the class variables explicitly declared in that class.

For every object, you can trace a path of classes on an inheritance hierarchy between the object’s class and class Object. For the Coffee object described above and shown in Figures 1 and 2, the path is: CoffeeLiquidObject. To fully initialize an object, the Java virtual machine must invoke (at least) one instance initialization method from each class along the object’s inheritance path. In the case of Coffee, this means that at least one instance initialization method must be invoked for each of the classes CoffeeLiquid, and Object.

During initialization, an <init> method may use one field in calculating another field’s initial value. While this is perfectly reasonable, it brings up the possibility that a field could be used before it has been initialized to its proper (not default) initial value. As mentioned earlier in this article, Java includes mechanisms that help prevent an instance variable from being used before it has been properly initialized. One mechanism is the rule, enforced by the Java compiler, forbidding initializers from directly using instance variables declared textually after the variable being initialized. Another mechanism is the order in which the fields from each class along an object’s inheritance path are initialized: the “order of initialization.”

Order of initialization
In Java, the fields of an object are initialized starting with the fields declared in the base class and ending with the fields declared in the object’s class. For a CoffeeCup object with the inheritance path shown in Figure 1, the order of initialization of fields would be:

  1. Object‘s fields (this will be quick, because there are none)
  2. Liquid‘s fields (mlVolume and temperature)
  3. Coffee‘s fields (swirling and clockwise)

This base-class-first order aims to prevent fields from being used before they are initialized to their proper (not default) values. In a constructor or initializer, you can safely use a superclass’s field directly, or call a method that uses a superclass’s field. By the time the code in your constructor or initializer is executed, you can be certain that the fields declared in any superclasses have already been properly initialized.

For example, you could safely use the temperature variable declared in class Liquid when you are initializing the swirlingvariable declared in class Coffee. (Perhaps if the temperature is above the boiling point for coffee, you set swirling to false.) If temperature were not private, class Coffee would inherit the field, and you could use it directly in an initializer or constructor of class Coffee. In this case, temperature is private, so you’ll have to use the temperature field indirectly, through a method:

// In source packet in file init/ex15/Liquid.java
class Liquid {

    private int mlVolume;
    private float temperature; // in Celsius

    public Liquid() {
        mlVolume = 300;
        temperature = (float) (Math.random() * 100.0);
    }

    public float getTemperature() {
        return temperature;
    }
    // Has several other methods, not shown...
}

// In source packet in file init/ex15/Coffee.java
class Coffee extends Liquid {

    private static final float BOILING_POINT = 100.0f; // Celsius
    private boolean swirling;
    private boolean clockwise;

    public Coffee(boolean swirling, boolean clockwise) {
        if (getTemperature() >= BOILING_POINT) {
            // Leave swirling at default value: false
            return;
        }
        this.swirling = swirling;
        if (swirling) {
            this.clockwise = clockwise;
        } // else, leave clockwise at default value: false
    }
    // Has several methods, not shown,
    // but doesn't override getTemperature()...
}

In the example, the constructor for Coffee invokes getTemperature() and uses the return value in the calculation of the proper initial value of swirling and clockwisegetTemperature() returns the value of the temperature variable; thus, the constructor for Coffee uses a field declared in Liquid. This works because, by the time the code inside Coffee‘s constructor is executed, the instance variables declared in Liquid are guaranteed to have already been initialized to their proper starting values.

Design Corner

Composition versus Inheritance

Behind the Scenes

[bv: want to have description of object image on the JVM heap here?]

[bv: want to mention that Object can be redefined?]

The structure of <init>
How does Java ensure the correct ordering of initialization? By the manner in which the Java compiler generates the instance initialization method. Into each <init> method, the compiler can place three kinds of code:

  1. An invocation of another constructor
  2. Initializers in textual order
  3. The constructor body

The order in which the compiler places these components into the <init> method determines the order of initialization of an object’s fields.

(Almost) every constructor’s first act
For every class except Object, the first thing each <init> method will do is invoke another constructor. If you included a this() invocation as the first statement in a constructor, the corresponding <init> method will start by calling another <init> method of the same class. For example, for the following class:

// In source packet in file init/ex4/CoffeeCup.java
class CoffeeCup {

    private int innerCoffee;

    public CoffeeCup() {
        this(237); // Calls other constructor
        // Could have done more construction here
    }

    public CoffeeCup(int amount) {
        innerCoffee = amount;
    }
    // ...
}

The <init> method for the no-arg constructor would first invoke the <init> method for the constructor, which takes an intparameter, passing it 237.

Automatic invocation of super()
For any class except class java.lang.Object, if you write a constructor that does not begin with a this() invocation, the <init> method for that constructor will begin with an invocation of a superclass constructor. You can explicitly invoke a superclass constructor using the super() statement. If you don’t, the compiler will automatically generate an invocation of the superclass’s no-arg constructor. (This is true for default constructors as well. With the exception of class Object, the <init>method for any default constructor will do only one thing: invoke the <init> method for the superclass’s no-arg constructor.) For example, given this CoffeeCup constructor from the example above:

public CoffeeCup(int amount) {
    innerCoffee = amount;
}

The corresponding <init> method would begin with an invocation of the <init> method for Liquid‘s (the direct superclass’s) no-arg constructor.

Alternatively, you could have included an explicit super() statement at the top of the Coffee constructor, as in:

public CoffeeCup(int amount) {
    super();
    innerCoffee = amount;
}

This version has the same effect as the previous version. If you want to invoke the superclass’s no-arg constructor, you needn’t provide an explicit super() invocation. The compiler will generate a no-arg super() invocation for you.

Invoking super() with arguments
If, on the other hand, you want to invoke a superclass constructor that takes parameters, you must provide an explicit super()invocation. Here’s an example:

// In source packet in file init/ex16/Liquid.java
class Liquid {

    private int mlVolume;
    private float temperature; // in Celsius

    public Liquid(int mlVolume, float temperature) {
        this.mlVolume = mlVolume;
        this.temperature = temperature;
    }

    public float getTemperature() {
        return temperature;
    }
    // Has several other methods, not shown,
    // but doesn't include another constructor...
}

// In source packet in file init/ex16/Coffee.java
public class Coffee extends Liquid {

    private static final float BOILING_POINT = 100.0f; // Celsius
    private boolean swirling;
    private boolean clockwise;

    public Coffee(int mlVolume, float temperature,
        boolean swirling, boolean clockwise) {

        super(mlVolume, temperature);
        if (getTemperature() > BOILING_POINT) {
            // Leave swirling at default value: false
            return;
        }
        this.swirling = swirling;
        if (swirling) {
            this.clockwise = clockwise;
        } // else, leave clockwise at default value: false
    }
    // has several methods, not shown,
    // but doesn't override getTemperature()...
}

In this example, Coffee‘s constructor explicitly invokes Liquid‘s constructor with a super() statement. Because class Liquid explicitly declares a constructor, the Java compiler won’t generate a default constructor. Moreover, because Liquiddoesn’t explicitly declare a no-arg constructor, class Liquid won’t have a no-arg constructor at all. For this reason, had Coffee‘s constructor not started with an explicit super() invocation, class Coffee would not have compiled. (Given this declaration of class Liquid, a simple new Liquid() statement would not compile either. You must invoke the constructor that is available to you, as in: new Liquid(25, 50.0).) If a subclass’s direct superclass does not offer a no-arg constructor, every constructor in that subclass must begin with either an explicit super() or this()invocation.

Only one constructor invocation allowed
Note that you can’t have both this() and super() in the same constructor. You can only have one or the other (or neither, if the direct superclass includes a no-arg constructor). If a constructor includes a this() or super() invocation, it must be the first statement in the constructor.

Catching exceptions not allowed
One other rule enforced on constructors is that you can’t catch any exceptions thrown by the constructor invoked with this()or super(). To do so, you would have to begin your constructor with a try statement:

// In source packet in file init/ex17/Coffee.java
// THIS WON'T COMPILE, BECAUSE THE super() INVOCATION
// DOESN'T COME FIRST IN THE CONSTRUCTOR
class Coffee extends Liquid {
    //...
    public Coffee(int mlVolume, float temperature,
        boolean swirling, boolean clockwise) {

        try {
            super(mlVolume, temperature);
        }
        catch (Throwable e) {
            //...
        }
        //...
    }
    //...
}

The point to understand here is that if any instance initialization method completes abruptly by throwing an exception, initialization of the object fails. This in turn means that object creation fails, because in Java programs, objects must be properly initialized before they are used.

The proper way to signal that an error occurred during object initialization is by throwing an exception. If an <init> method throws an exception, it is likely that at least some of the fields that <init> method normally takes responsibility for did not get properly initialized. If you were able to catch an exception thrown by an <init> method you invoked with this() or super(), you could ignore the exception and complete normally. This could result in an improperly or incompletely initialized object being returned by new. This is why catching exceptions thrown by <init> methods invoked via this() or super() is not allowed.

Inheritance and initialization order
From the many rules that surround the invocation of instance initialization methods via this() or super(), there arises a clear and certain order for instance variable initialization. Although <init> methods are called in an order starting from the object’s class and proceeding up the inheritance path to class Object, instance variables are initialized in the reverse order. Instance variables are initialized in an order starting from class Object and proceeding down the inheritance path to the object’s class. The reason the order of instance variable initialization is reverse to that of <init> method invocation is that the first thing each <init> method (except Object‘s) does is call another <init> method. So the superclass <init> method is invoked and completes before any initialization code of the current class’s <init> method begins execution.

As an example of this ordering, consider again the inheritance hierarchy for class Coffee as shown in Figure 1 and the following implementation of those classes:

// In source packet in file init/ex18/Liquid.java
class Liquid {

    private int mlVolume;
    private float temperature; // in Celsius

    Liquid(int mlVolume, float temperature) {
        this.mlVolume = mlVolume;
        this.temperature = temperature;
    }
    //...
}

// In source packet in file init/ex18/Coffee.java
class Coffee extends Liquid {

    private boolean swirling;
    private boolean clockwise;

    public Coffee(int mlVolume, float temperature,
        boolean swirling, boolean clockwise) {

        super(mlVolume, temperature);
        this.swirling = swirling;
        this.clockwise = clockwise;
    }
    //...
}

When you instantiate a new Coffee object with the new operator, the Java virtual machine first will allocate (at least) enough space on the heap to hold all the instance variables declared in Coffee and its superclasses. Second, the virtual machine will initialize all the instance variables to their default initial values. Third, the virtual machine will invoke the <init> method in the Coffee class.

The first thing Coffee‘s <init> method will do is invoke the <init> method in its direct superclass, Liquid. The first thing Liquid‘s <init> method will do is invoke the no-arg <init> method in its direct superclass, ObjectObject‘s <init>method most likely will do nothing but return, because it has no instance variables to initialize. (Once again, what Object‘s <init> method actually does is an implementation detail of each particular Java runtime environment.) When Object‘s <init> method returns, Liquid<init> method will initialize mlVolume and temperature to their proper starting values and return. When Liquid<init> method returns, Coffee‘s <init> method will initialize swirling and clockwise to their proper starting values and return. Upon normal completion of Coffee‘s <init> method (in other words, so long as it doesn’t complete abruptly by throwing an exception), the JVM will return the reference to the new Coffee object as the result of thenew operator.

this() won’t change the order of initialization
Note that if an <init> method begins not by invoking a superclass’s <init> method (a super() invocation), but instead by invoking another <init> method from the same class (a this() invocation), the order of instance variable initialization remains the same. You can have several this() invocations in a row if you wish. In other words, you could have an <init>method that invokes another with this(), and that <init> method invokes yet another with this(), and so on. But in the end, there will always be an <init> method with a super() invocation — either an explicit super() invocation or a compiler-generated one. Since this() and super() are both always the first action a constructor takes, the instance variables will always be initialized in order from the base class on down.

In addition to the code for constructor invocations and constructor bodies, the Java compiler also places code for any initializers in the <init> method. If a class includes initializers, the code for them will be placed after the superclass method invocation but before the code for the constructor body, in every <init> method that begins with an explicit or implicit super()invocation. Code for initializers are not included as part of <init> methods that begin with a this() invocation. Because initializer code appears only in <init> methods that begin with a super() invocation, and not in those that begin with athis() invocation, the initializers for a class are guaranteed to be run only once for each new class creation. Because initializers appear after the super() invocation and before the code from the constructor’s body, you can always be certain that initializers will have been run by the time any constructor code for that class is executed.

Calling subclassed methods from constructors
The strict ordering of instance variable initialization enforced by the Java compiler is, in part, an effort to ensure that during the initialization process, instance variables are never used before they have been initialized to their proper initial values. As illustrated earlier in this article, however, the rules of ordering are not bulletproof. There are ways you can use an instance variable during initialization before it has been initialized to its proper value, while it still has its default value. In the case of instance variable initializers, you can invoke a method that uses a variable declared textually after the variable being initialized. Another way to use an instance variable before it has been properly initialized is to invoke a method from a superclass initializer or constructor that uses instance variables in a subclass.

Unlike C++, which treats the invocation of virtual functions from constructors specially, Java methods invoked from <init>methods behave the same as if they were invoked from any method. If <init> in a superclass invokes a method that has been overridden in a subclass, the subclass’s implementation of that method will run. If the subclass’s method implementation uses instance variables explicitly declared in the subclass, those variables will still have their default initial values.

You should be careful when you invoke methods from initializers or constructors, because you can end up using instance variables before they’ve been properly initialized — while they still have their default initial values. It is fine to use variables while they still have their default initial values, so long as it is the result you are aiming for. If you invoke non-private methods from initializers and constructors, remember that later some other programmer could come along, extend your class, and override those methods, thereby thwarting your grand initialization scheme.

Example Programs

Could perhaps show how class vars can be used to keep track of all the instances of the class and then how a gurgleAllObjects() class method can send gurgle() methods to all objects.

On the CD-ROM

The CD-ROM contains several examples from this chapter, all of which are in subdirectories of the inherit directory. The files for example one are in the ex1 subdirectory, the files for example two are in ex2, and so on.

Example one is simply the CoffeeCup and Coffee classes, shown above, that illustrate composition. In this version of CoffeeCup, the innerCoffee instance variable is a reference to an object of type Coffee. The files are in the inherit/ex1directory.

Example two is the polymorphism example. All of the code for this example is shown above as part of the text of this chapter. The files are in the inherit/ex2 directory. In this example, the addLiquid() method of class CoffeeCup use polymorphism to call the appropriate swirl() method an object that either is or descends from class Liquid. If you execute the Java application, Example2, it will print out the output:

Liquid Swirling
Coffee Swirling
Milk Swirling

Example three is an example of poor design that doesn’t take advantage of polymorphism. Only the UglyCoffeeCup class from this example is shown in the text of this chapter. (The rest aren’t shown because this example doesn’t provide a positive role model.) All the files exist in the inherit/ex3 directory of the CD-ROM, however, so you can run the applicationExample3. When you run Example3, you get the same output as Example2 gives you. The example works, it just doesn’t take advantage of polymorphism. Try to avoid this style of program design.

Example four illustrates the difference between static and dynamic binding. The code for all the files in this example, which are shown above as part of the text of this chapter. The files are in the inherit/ex4 directory. You can see the different between static and dynamic binding by running Example4a, which doesn’t yield the desired behavior of gurgling all milk objects. Example4b shows one way to gurgle milk, however, the preferred way to gurgle milk is shown in Example4c. When you runExample4c, it will print out:

One Milk object is swirling.
All Milk objects are gurgling.

Example five illustrates adding behavior to one member of a family of types, and using instanceof to access that behavior. All of the code in this example is shown above in the text of this chapter. The files are in the inherit/ex5 directory of the CD- ROM. In this example, two of the source files, Example5a.java and Example5c.java, don’t compile. These files illustrate that you can’t access a method defined in a subclass, Tea, if you have a reference to a superclass, Liquid. You can, however, run Example5b and Example5d. When you run Example5d, which illustrates the proper way to access the readFuture() method defined in subclass Tea, the application will print out:

Tea Swirling
Reading the future...

Examples six and seven are simply the two Liquid classes, shown above, that illustrate abstract classes and methods. In example six, which is in the inherit/ex6 directory, class Liquid is declared abstract even though it doesn’t contain any abstract methods. In example seven, which is in the inherit/ex7 directory, both the swirl() method and the Liquid class itself are declared abstract.



Association, Aggregation and Composition

By Lokesh Gupta | Filed Under: Object Oriented

Association, aggregation and composition are three kind of relationships which classes can have in object oriented programming. Let’s understand the difference between them.

Table of Contents

1. Association
2. Aggregation
3. Composition
4. Summary

1. Association in Java

We call association those relationships whose objects have an independent lifecycle and where there is no ownership between the objects.

Let’s take an example of a teacher and student. Multiple students can associate with a single teacher, and a single student can associate with multiple teachers, but both have their own lifecycles (both can be create and delete independently); so when a teacher leaves the school, we don’t need to delete any students, and when a student leaves the school, we don’t need to delete any teachers.

association

2. Aggregation in Java

We call aggregation those relationships whose objects have an independent lifecycle, but there is ownership, and child objects cannot belong to another parent object.

Let’s take an example of a cell phone and a cell phone battery. A single battery can belong to a phone, but if the phone stops working, and we delete it from our database, the phone battery will not be deleted because it may still be functional. So in aggregation, while there is ownership, objects have their own lifecycle.

aggregation

3. Composition in Java

We use the term composition to refer to relationships whose objects don’t have an independent lifecycle, and if the parent object is deleted, all child objects will also be deleted.

Let’s take an example of the relationship between questions and answers. Single questions can have multiple answers, and answers cannot belong to multiple questions. If we delete questions, answers will automatically be deleted.

composition

4. Summary

Sometimes, it can be a complicated process to decide if we should use association, aggregation, or composition. This difficulty is caused in part because aggregation and composition are subsets of association, meaning they are specific cases of association.

Association, Aggregation and Composition Relationship
Association, Aggregation and Composition Relationship

https://www.artima.com/objectsandjava/webuscript/CompoInherit1.html


OR, as SamualSam said on tutorialspoint:

Association

Association refers to the relationship between multiple objects. It refers to how objects are related to each other and how they are using each other’s functionality. Composition and aggregation are two types of association.

Composition

The composition is the strong type of association. An association is said to composition if an Object owns another object and another object cannot exist without the owner object. Consider the case of Human having a heart. Here Human object contains the heart and heart cannot exist without Human.

Aggregation

Aggregation is a weak association. An association is said to be aggregation if both Objects can exist independently. For example, a Team object and a Player object. The team contains multiple players but a player can exist without a team.

Example of Composition

//Car must have Engine
public class Car {
   //engine is a mandatory part of the car
   private final Engine engine;

   public Car () {
      engine = new Engine();
   }
}

//Engine Object
class Engine {}

Example of Aggregation

//Team
public class Team {      
   //players can be 0 or more
   private List players;

   public Car () {
      players = new ArrayList();
   }
}
//Player Object
class Player {}

Understanding Association, Aggregation, and Composition

In this article we will try to understand 3 important concepts association, aggregation and composition.

Table of contents

Introduction

In this article, we will try to understand three important concepts: association, aggregation, and composition.

We will also try to understand in what kind of scenarios we need them. These three concepts have really confused a lot of developers and in this article, my attempt would be to present the concepts in a simplified manner with some real world examples.

Extracting real world relationships from a requirement

The whole point of OOP is that your code replicates real world objects, thus making your code readable and maintainable. When we say real world, the real world has relationships. Let’s consider the simple requirement listed below:

  1. Manager is an employee of XYZ limited corporation.
  2. Manager uses a swipe card to enter XYZ premises.
  3. Manager has workers who work under him.
  4. Manager has the responsibility of ensuring that the project is successful.
  5. Manager’s salary will be judged based on project success.

If you flesh out the above five point requirement, we can easily visualize four relationships:-

  • Inheritance
  • Aggregation
  • Association
  • Composition

Let’s understand them one by one.

Requirement 1: The IS A relationship

If you look at the first requirement (Manager is an employee of XYZ limited corporation), it’s a parent child relationship or inheritance relationship. The sentence above specifies that Manager is a type of employee, in other words we will have two classes: parent class Employee, and a child class Manager which will inherit from the Employee class.

Note: The scope of this article is only limited to aggregation, association, and composition. We will not discuss inheritance in this article as it is pretty straightforward and I am sure you can get 1000s of articles on the net which will help you in understanding it.

Requirement 2: The Using relationship: Association

Requirement 2 is an interesting requirement (Manager uses a swipe card to enter XYZ premises). In this requirement, the manager object and the swipe card object use each other but they have their own object life time. In other words, they can exist without each other. The most important point in this relationship is that there is no single owner.

Image 1 for Understanding Association, Aggregation, and Composition

The above diagram shows how the SwipeCard class uses the Manager class and the Manager class uses the SwipeCard class. You can also see how we can create objects of the Manager class and SwipeCard class independently and they can have their own object life time.

This relationship is called the “Association” relationship.

Requirement 3: The Using relationship with Parent: Aggregation

The third requirement from our list (Manager has workers who work under him) denotes the same type of relationship like association but with a difference that one of them is an owner. So as per the requirement, the Manager object will own Worker objects.

The child Worker objects can not belong to any other object. For instance, a Worker object cannot belong to a SwipeCard object.

But… the Worker object can have its own life time which is completely disconnected from the Manager object. Looking from a different perspective, it means that if the Manager object is deleted, the Worker object does not die.

This relationship is termed as an “Aggregation” relationship.

Image 2 for Understanding Association, Aggregation, and Composition

Requirements 4 and 5: The Death relationship: Composition

The last two requirements are actually logically one. If you read closely, the requirements are as follows:

  1. Manager has the responsibility of ensuring that the project is successful.
  2. Manager’s salary will be judged based on project success.

Below is the conclusion from analyzing the above requirements:

  1. Manager and the project objects are dependent on each other.
  2. The lifetimes of both the objects are the same. In other words, the project will not be successful if the manager is not good, and the manager will not get good increments if the project has issues.

Below is how the class formation will look like. You can also see that when I go to create the project object, it needs the manager object.

Image 3 for Understanding Association, Aggregation, and Composition

This relationship is termed as the composition relationship. In this relationship, both objects are heavily dependent on each other. In other words, if one goes for garbage collection the other also has to be garbage collected, or putting from a different perspective, the lifetime of the objects are the same. That’s why I have put in the heading “Death” relationship.

Putting things together

Below is a visual representation of how the relationships have emerged from the requirements.

Image 4 for Understanding Association, Aggregation, and Composition

The source code

You can download the sample source code for this article.

Summarizing

To avoid confusion henceforth for these three terms, I have put forward a table below which will help us compare them from three angles: owner, lifetime, and child object.

AssociationAggregationComposition
OwnerNo ownerSingle ownerSingle owner
Life timeHave their own lifetimeHave their own lifetimeOwner’s life time
Child objectChild objects all are independentChild objects belong to a single parentChild objects belong to a single parent

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Shivprasad koirala

 Architect https://www.questpond.com
India 

Do not forget to watch my Learn step by step video series.

Learn MVC 5 step by step in 16 hours
Learn MVC Core step by step
Learn Angular tutorials step by step for beginners
Learn Azure Step by Step
Learn Data Science Step by Step
Learn Xamarin Mobile Programming Step by Step
Learn Design Pattern in 8 hours
Learn C# in 100 hours series
Learn Data structures and Algorithm Step by Step
Learn SQL Server in 16 hours series
Learn Javascript in 2 hours series
Learn MSBI in 32 hours
Learn SharePoint Step by Step in 8 hours
Learn TypeScript in 45 minutes

Source: link

HashMap values() Method in Java

The java.util.HashMap.values() method of HashMap class in Java is used to create a collection out of the values of the map. It basically returns a Collection view of the values in the HashMap.

Syntax:

Hash_Map.values()

Parameters: The method does not accept any parameters.

Return Value: The method is used to return a collection view containing all the values of the map.

Below programs are used to illustrate the working of java.util.HashMap.values() Method:
Program 1: Mapping String Values to Integer Keys.

// Java code to illustrate the values() method 
import java.util.*; 

public class Hash_Map_Demo { 
	public static void main(String[] args) 
	{ 

		// Creating an empty HashMap 
		HashMap<Integer, String> hash_map = new HashMap<Integer, String>(); 

		// Mapping string values to int keys 
		hash_map.put(10, "Geeks"); 
		hash_map.put(15, "4"); 
		hash_map.put(20, "Geeks"); 
		hash_map.put(25, "Welcomes"); 
		hash_map.put(30, "You"); 

		// Displaying the HashMap 
		System.out.println("Initial Mappings are: " + hash_map); 

		// Using values() to get the set view of values 
		System.out.println("The collection is: " + hash_map.values()); 
	} 
} 


Output:

Initial Mappings are: {20=Geeks, 25=Welcomes, 10=Geeks, 30=You, 15=4}
The collection is: [Geeks, Welcomes, Geeks, You, 4]

Program 2: Mapping Integer Values to String Keys.filter_none

// Java code to illustrate the values() method 
import java.util.*; 

public class Hash_Map_Demo { 
	public static void main(String[] args) 
	{ 

		// Creating an empty HashMap 
		HashMap<String, Integer> hash_map = new HashMap<String, Integer>(); 

		// Mapping int values to string keys 
		hash_map.put("Geeks", 10); 
		hash_map.put("4", 15); 
		hash_map.put("Geeks", 20); 
		hash_map.put("Welcomes", 25); 
		hash_map.put("You", 30); 

		// Displaying the HashMap 
		System.out.println("Initial Mappings are: " + hash_map); 

		// Using values() to get the set view of values 
		System.out.println("The collection is: " + hash_map.values()); 
	} 
} 


Output:

Initial Mappings are: {4=15, Geeks=20, You=30, Welcomes=25}
The collection is: [15, 20, 30, 25]

Note: The same operation can be performed with any type of Mappings with variation and combination of different data types.

 

Recommended Posts:

Source: link

Getting Started with Web Applications

A web application is a dynamic extension of a web or application server. There are two types of web applications:

Web Applications

In the Java 2 platform, web components provide the dynamic extension capabilities for a web server. Web components are either Java servlets, JSP pages, or web service endpoints. The interaction between a web client and a web application is illustrated in Figure 3–1. The client sends an HTTP request to the web server. A web server that implements Java Servlet and JavaServer Pages technology converts the request into an HTTPServletRequest object. This object is delivered to a web component, which can interact with JavaBeans components or a database to generate dynamic content. The web component can then generate an HTTPServletResponse or it can pass the request to another web component. Eventually a web component generates a HTTPServletResponse object. The web server converts this object to an HTTP response and returns it to the client.

Figure 3–1 Java Web Application Request Handling
Diagram of web application request handling. Clients
and web components communicate using HttpServletRequest and HttpServletResponse.

Servlets are Java programming language classes that dynamically process requests and construct responses. JSP pages are text-based documents that execute as servlets but allow a more natural approach to creating static content. Although servlets and JSP pages can be used interchangeably, each has its own strengths. Servlets are best suited for service-oriented applications (web service endpoints are implemented as servlets) and the control functions of a presentation-oriented application, such as dispatching requests and handling nontextual data. JSP pages are more appropriate for generating text-based markup such as HTML, Scalable Vector Graphics (SVG), Wireless Markup Language (WML), and XML.

Since the introduction of Java Servlet and JSP technology, additional Java technologies and frameworks for building interactive web applications have been developed. Figure 3–2 illustrates these technologies and their relationships.

Figure 3–2 Java Web Application Technologies
Diagram of web application technologies. JavaServer Pages,
the JSP Standard Tag Library, and JavaServer Faces rest on JavaServlet technology.

Notice that Java Servlet technology is the foundation of all the web application technologies, so you should familiarize yourself with the material in Chapter 4, Java Servlet Technology even if you do not intend to write servlets. Each technology adds a level of abstraction that makes web application prototyping and development faster and the web applications themselves more maintainable, scalable, and robust.

Web components are supported by the services of a runtime platform called a web container. A web container provides services such as request dispatching, security, concurrency, and life-cycle management. It also gives web components access to APIs such as naming, transactions, and email.

Certain aspects of web application behavior can be configured when the application is installed, or deployed, to the web container. The configuration information is maintained in a text file in XML format called a web application deployment descriptor (DD). A DD must conform to the schema described in the Java Servlet Specification.

This chapter gives a brief overview of the activities involved in developing web applications. First it summarizes the web application life cycle. Then it describes how to package and deploy very simple web applications on the Application Server. It moves on to configuring web applications and discusses how to specify the most commonly used configuration parameters. It then introduces an example, Duke’s Bookstore, which illustrates all the Java EE web-tier technologies, and describes how to set up the shared components of this example. Finally it discusses how to access databases from web applications and set up the database resources needed to run Duke’s Bookstore.

Web Application Life Cycle

A web application consists of web components, static resource files such as images, and helper classes and libraries. The web container provides many supporting services that enhance the capabilities of web components and make them easier to develop. However, because a web application must take these services into account, the process for creating and running a web application is different from that of traditional stand-alone Java classes.

  1. Develop the web component code.
  2. Develop the web application deployment descriptor.
  3. Compile the web application components and helper classes referenced by the components.
  4. Optionally package the application into a deployable unit.
  5. Deploy the application into a web container.
  6. Access a URL that references the web application.

Developing web component code is covered in the later chapters. Steps 2 through 4 are expanded on in the following sections and illustrated with a Hello, World-style presentation-oriented application. This application allows a user to enter a name into an HTML form (Figure 3–3) and then displays a greeting after the name is submitted (Figure 3–4).

Figure 3–3 Greeting Form
Screen capture of Duke's greeting, "Hello, my name is
Duke. What's yours?" Includes a text field for your name and Submit and Reset
buttons.
Figure 3–4 Response
Screen capture of Duke's response, "Hello, Charlie!"

The Hello application contains two web components that generate the greeting and the response. This chapter discusses two versions of the application: a JSP version called hello1, in which the components are implemented by two JSP pages (tut-install/javaeetutorial5/examples/web/hello1/web/index.jsp and tut-install/javaeetutorial5/examples/web/hello1/web/response.jsp) and a servlet version called hello2, in which the components are implemented by two servlet classes (tut-install/javaeetutorial5/examples/web/hello2/src/servlets/GreetingServlet.java and tut-install/javaeetutorial5/examples/web/hello2/src/servlets/ResponseServlet.java). The two versions are used to illustrate tasks involved in packaging, deploying, configuring, and running an application that contains web components. The section Chapter 2, Using the Tutorial Examples explains how to get the code for these examples.

After you install the tutorial bundle, the source code for the examples is in the following directories:

  • tut-install/javaeetutorial5/examples/web/hello1/
  • tut-install/javaeetutorial5/examples/web/hello2/

Web Modules

In the Java EE architecture, web components and static web content files such as images are called web resources. A web module is the smallest deployable and usable unit of web resources. A Java EE web module corresponds to a web application as defined in the Java Servlet specification.

In addition to web components and web resources, a web module can contain other files:

  • Server-side utility classes (database beans, shopping carts, and so on). Often these classes conform to the JavaBeans component architecture.
  • Client-side classes (applets and utility classes).

A web module has a specific structure. The top-level directory of a web module is the document root of the application. The document root is where JSP pages, client-side classes and archives, and static web resources, such as images, are stored.

The document root contains a subdirectory named WEB-INF, which contains the following files and directories:

  • web.xml: The web application deployment descriptor
  • Tag library descriptor files (see Tag Library Descriptors)
  • classes: A directory that contains server-side classes: servlets, utility classes, and JavaBeans components
  • tags: A directory that contains tag files, which are implementations of tag libraries (see Tag File Location)
  • lib: A directory that contains JAR archives of libraries called by server-side classes

If your web module does not contain any servlets, filter, or listener components then it does not need a web application deployment descriptor. In other words, if your web module only contains JSP pages and static files then you are not required to include a web.xml file. The hello1example, first discussed in Packaging Web Modules, contains only JSP pages and images and therefore does not include a deployment descriptor.

You can also create application-specific subdirectories (that is, package directories) in either the document root or the WEB-INF/classes/directory.

A web module can be deployed as an unpacked file structure or can be packaged in a JAR file known as a web archive (WAR) file. Because the contents and use of WAR files differ from those of JAR files, WAR file names use a .war extension. The web module just described is portable; you can deploy it into any web container that conforms to the Java Servlet Specification.

To deploy a WAR on the Application Server, the file must also contain a runtime deployment descriptor. The runtime deployment descriptor is an XML file that contains information such as the context root of the web application and the mapping of the portable names of an application’s resources to the Application Server’s resources. The Application Server web application runtime DD is named sun-web.xml and is located in the WEB-INF directory along with the web application DD. The structure of a web module that can be deployed on the Application Server is shown in Figure 3–5.

Figure 3–5 Web Module Structure
Diagram of web module structure. WEB-INF and web pages
are under the root. Under WEB-INF are descriptors and the lib, classes, and
tags directories.

Packaging Web Modules

A web module must be packaged into a WAR in certain deployment scenarios and whenever you want to distribute the web module. You package a web module into a WAR by executing the jar command in a directory laid out in the format of a web module, by using the Ant utility, or by using the IDE tool of your choice. This tutorial shows you how to use NetBeans IDE or Ant to build, package, and deploy the sample applications.

  1. Select File->Open Project.
  2. In the Open Project dialog, navigate to:
    tut-install/javaeetutorial5/examples/web/
  3. Select the hello1 folder.
  4. Select the Open as Main Project check box.
  5. Click Open Project.
  6. In the Projects tab, right-click the hello1 project and select Build.
  1. In a terminal window, go to tut-install/javaeetutorial5/examples/web/hello1/.
  2. Type ant. This command will spawn any necessary compilations, copy files to the tut-install/javaeetutorial5/examples/web/hello1/build/ directory, create the WAR file, and copy it to the tut-install/javaeetutorial5/examples/web/hello1/dist/ directory.

Deploying a WAR File

You can deploy a WAR file to the Application Server in a few ways:

  • Copying the WAR into the domain-dir/autodeploy/ directory.
  • Using the Admin Console.
  • By running asadmin or ant to deploy the WAR.
  • Using NetBeans IDE.

All these methods are described briefly in this chapter; however, throughout the tutorial, you will use ant and NetBeans IDE for packaging and deploying.

Setting the Context Root

context root identifies a web application in a Java EE server. You specify the context root when you deploy a web module. A context root must start with a forward slash (/) and end with a string.

In a packaged web module for deployment on the Application Server, the context root is stored in sun-web.xml.

  1. Expand your project tree in the Projects pane of NetBeans IDE.
  2. Expand the Web Pages and WEB-INF nodes of your project.
  3. Double-click sun-web.xml.
  4. In the editor pane, click Edit As XML.
  5. Edit the context root, which is enclosed by the context-root element.

Deploying a Packaged Web Module

If you have deployed the hello1 application, before proceeding with this section, undeploy the application by following one of the procedures described in Undeploying Web Modules.

Deploying with the Admin Console

  1. Expand the Applications node.
  2. Select the Web Applications node.
  3. Click the Deploy button.
  4. Select the radio button labeled “Package file to be uploaded to the Application Server.”
  5. Type the full path to the WAR file (or click on Browse to find it), and then click the OK button.
  6. Click Next.
  7. Type the application name.
  8. Type the context root.
  9. Select the Enabled box.
  10. Click the Finish button.

Deploying with asadmin

To deploy a WAR with asadmin, open a terminal window or command prompt and execute


asadmin deploy full-path-to-war-file

Deploying with Ant

To deploy a WAR with the Ant tool, open a terminal window or command prompt in the directory where you built and packaged the WAR, and execute


ant deploy

Deploying with NetBeans IDE

  1. Select File->Open Project.
  2. In the Open Project dialog, navigate to your project and open it.
  3. In the Projects tab, right-click the project and select Undeploy and Deploy.

Testing Deployed Web Modules

Now that the web module is deployed, you can view it by opening the application in a web browser. By default, the application is deployed to host localhost on port 8080. The context root of the web application is hello1.

  1. Open a web browser.
  2. Enter the following URL in the web address box:
    http://localhost:8080/hello1
  3. Enter your name, and click Submit.

The application should display the name you submitted as shown in Figure 3–3 and Figure 3–4.

Listing Deployed Web Modules

The Application Server provides two ways to view the deployed web modules: the Admin Console and the asadmin command.

  1. Open the URL http://localhost:4848/asadmin in a browser.
  2. Expand the nodes Applications->Web Applications.

Use the asadmin command as follows:


asadmin list-components

Updating Web Modules

  1. Recompile any modified classes.
  2. If you have deployed a packaged web module, update any modified components in the WAR.
  3. Redeploy the module.
  4. Reload the URL in the client.

Updating a Packaged Web Module

This section describes how to update the hello1 web module that you packaged.

First, change the greeting in the file tut-install/javaeetutorial5/examples/web/hello1/web/index.jsp to

<h2>Hi, my name is Duke. What’s yours?</h2>

To update the project in NetBeans IDE:

  • Right-click on the project and select Build.
  • Right-click on the project and select Undeploy and Deploy.

To update the project using the Ant build tool:

  • Type ant to copy the modified JSP page into the build directory.
  • Type ant deploy to deploy the WAR file.

To view the modified module, reload the URL in the browser.

You should see the screen in Figure 3–6 in the browser.

Figure 3–6 New Greeting
Screen capture of Duke's new greeting, "Hi, my name is
Duke. What's yours?" Includes a text field for your name and Submit and Reset
buttons.

Dynamic Reloading

If dynamic reloading is enabled, you do not have to redeploy an application or module when you change its code or deployment descriptors. All you have to do is copy the changed JSP or class files into the deployment directory for the application or module. The deployment directory for a web module named context-root is domain-dir/applications/j2ee-modules/context-root. The server checks for changes periodically and redeploys the application, automatically and dynamically, with the changes.

This capability is useful in a development environment, because it allows code changes to be tested quickly. Dynamic reloading is not recommended for a production environment, however, because it may degrade performance. In addition, whenever a reload is done, the sessions at that time become invalid and the client must restart the session.

  1. Select the Applications Server node.
  2. Select the Advanced tab.
  3. Check the Reload Enabled box to enable dynamic reloading.
  4. Enter a number of seconds in the Reload Poll Interval field to set the interval at which applications and modules are checked for code changes and dynamically reloaded.
  5. Click the Save button.
  1. Create an empty file named .reload at the root of the module:
    domain-dir/applications/j2ee-modules/context-root/.reload
  2. Explicitly update the .reload file’s time stamp each time you make these changes. On UNIX, execute
    touch .reload

For JSP pages, changes are reloaded automatically at a frequency set in the Reload Poll Interval field. To disable dynamic reloading of JSP pages, set the Reload Poll Interval field value to –1.

Undeploying Web Modules

You can undeploy web modules in four ways: you can use NetBeans IDE, the Admin Console, the asadmin command, or the Ant tool.

  1. Ensure the Sun Java System Application Server is running.
  2. In the Runtime window, expand the Sun Java System Application Server instance and the node containing the application or module.
  3. Right-click the application or module and choose Undeploy.
  1. Open the URL http://localhost:4848/asadmin in a browser.
  2. Expand the Applications node.
  3. Select Web Applications.
  4. Click the check box next to the module you wish to undeploy.
  5. Click the Undeploy button.

Use the asadmin command as follows:


asadmin undeploy context-root

To use the Ant tool, execute the following command in the directory where you built and packaged the WAR:


ant undeploy

Configuring Web Applications

Web applications are configured by means of elements contained in the web application deployment descriptor.

The following sections give a brief introduction to the web application features you will usually want to configure. A number of security parameters can be specified; these are covered in Chapter 30, Securing Web Applications.

In the following sections, examples demonstrate procedures for configuring the Hello, World application. If Hello, World does not use a specific configuration feature, the section gives references to other examples that illustrate how to specify the deployment descriptor element.

Mapping URLs to Web Components

When a request is received by the web container it must determine which web component should handle the request. It does so by mapping the URL path contained in the request to a web application and a web component. A URL path contains the context root and an alias:


http://host:port/context-root/alias

Setting the Component Alias

The alias identifies the web component that should handle a request. The alias path must start with a forward slash (/) and end with a string or a wildcard expression with an extension (for example, *.jsp). Since web containers automatically map an alias that ends with *.jsp, you do not have to specify an alias for a JSP page unless you wish to refer to the page by a name other than its file name.

  1. Select File->Open Project.
  2. In the Open Project dialog, navigate to:
    tut-install/javaeetutorial5/examples/web/
  3. Select the hello2 folder.
  4. Select the Open as Main Project check box.
  5. Click Open Project.
  6. Expand the project tree in the Projects pane.
  7. Expand the Web pages node and then the WEB-INF node in the project tree.
  8. Double-click the web.xml file inside the WEB-INF node.

The following steps describe how to make the necessary edits to the web.xml file, including how to set the display name and how to map the servlet components. Because the edits are already in the file, you can just use the steps to view the settings.

  1. Click General at the top of the editor to open the general view.
  2. Enter hello2 in the Display Name field.
  1. Click Servlets at the top of the editor to open the servlets view.
  2. Click Add Servlet.
  3. In the Add Servlet dialog, enter GreetingServlet in the Servlet Name field.
  4. Enter servlets.GreetingServlet in the Servlet Class field.
  5. Enter /greeting in the URL Pattern field.
  6. Click OK.
  7. Repeat the preceding steps, except enter ResponseServlet as the servlet name, servlets.ResponseServlet as the servlet class, and /response as the URL pattern.

If you are not using NetBeans IDE, you can add these settings using a text editor.

  1. Select File->Open Project.
  2. In the Open Project dialog, navigate to:
    tut-install/javaeetutorial5/examples/web/
  3. Select the hello2 folder.
  4. Select the Open as Main Project check box.
  5. Click Open Project.
  6. In the Projects tab, right-click the hello2 project and select Build.
  1. In a terminal window, go to tut-install/javaeetutorial5/examples/web/hello2/.
  2. Type ant. This target will build the WAR file and copy it to the tut-install/javaeetutorial5/examples/web/hello2/dist/directory.

To deploy the example using NetBeans IDE, right-click on the project in the Projects pane and select Undeploy and Deploy.

To deploy the example using Ant, type ant deploy. The deploy target in this case gives you an incorrect URL to run the application. To run the application, please use the URL shown at the end of this section.

To run the application, first deploy the web module, and then open the URL http://localhost:8080/hello2/greeting in a browser.

Declaring Welcome Files

The welcome files mechanism allows you to specify a list of files that the web container will use for appending to a request for a URL (called a valid partial request) that is not mapped to a web component.

For example, suppose you define a welcome file welcome.html. When a client requests a URL such as host:port/webapp/directory, where directory is not mapped to a servlet or JSP page, the file host:port/webapp/directory/welcome.html is returned to the client.

If a web container receives a valid partial request, the web container examines the welcome file list and appends to the partial request each welcome file in the order specified and checks whether a static resource or servlet in the WAR is mapped to that request URL. The web container then sends the request to the first resource in the WAR that matches.

If no welcome file is specified, the Application Server will use a file named index.XXX, where XXX can be html or jsp, as the default welcome file. If there is no welcome file and no file named index.XXX, the Application Server returns a directory listing.

  1. Open the project if you haven’t already.
  2. Expand the project’s node in the Projects pane.
  3. Expand the Web Pages node and then the WEB-INF node.
  4. Double-click web.xml.
  5. Do one of the following, making sure that the JSP pages you specify are actually included in the WAR file:
    1. Click Pages at the top of the editor pane and enter the names of the JSP pages that act as welcome files in the Welcome Files field.
    2. Click XML at the top of the editor pane, specify the JSP pages using welcome-file elements and include these elements inside a welcome-file-list element. The welcome-file element defines the JSP page to be used as the welcome page.The example discussed in Encapsulating Reusable Content Using Tag Files has a welcome file.

Setting Initialization Parameters

The web components in a web module share an object that represents their application context (see Accessing the Web Context). You can pass initialization parameters to the context or to a web component.

  1. Open the project if you haven’t already.
  2. Expand the project’s node in the Projects pane.
  3. Expand the Web Pages node and then the WEB-INF node.
  4. Double-click web.xml.
  5. Click General at the top of the editor pane.
  6. Select the Context Parameters node.
  7. Click Add.
  8. In the Add Context Parameter dialog, do the following:
    1. Enter the name that specifies the context object in the Param Name field.
    2. Enter the parameter to pass to the context object in the Param Value field.
    3. Click OK.

Alternatively, you can edit the XML of the web.xml file directly by clicking XML at the top of the editor pane and using the following elements to add a context parameter:

  • A param-name element that specifies the context object
  • A param-value element that specifies the parameter to pass to the context object
  • A context-param element that encloses the previous two elements

For a sample context parameter, see the example discussed in The Example JSP Pages.

  1. Open the project if you haven’t already.
  2. Expand the project’s node in the Projects pane.
  3. Expand the Web Pages node and then the WEB-INF node.
  4. Double-click web.xml.
  5. Click Servlets at the top of the editor pane.
  6. After entering the servlet’s name, class, and URL pattern, click the Add button under the Initialization Parameters table.
  7. In the Add Initialization Parameter dialog:
    1. Enter the name of the parameter in the Param Name field.
    2. Enter the parameter’s value in the Param Value Field.
    3. Click OK.

Alternatively, you can edit the XML of the web.xml file directly by clicking XML at the top of the editor pane and using the following elements to add a context parameter:

  • A param-name element that specifies the name of the initialization parameter
  • A param-value element that specifies the value of the initialization parameter
  • An init-param element that encloses the previous two elements

Mapping Errors to Error Screens

When an error occurs during execution of a web application, you can have the application display a specific error screen according to the type of error. In particular, you can specify a mapping between the status code returned in an HTTP response or a Java programming language exception returned by any web component (see Handling Servlet Errors) and any type of error screen.

  1. Open the project if you haven’t already.
  2. Expand the project’s node in the Projects pane.
  3. Expand the Web Pages node and then the WEB-INF node.
  4. Double-click web.xml.
  5. Click Pages at the top of the editor pane.
  6. Expand the Error Pages node.
  7. Click Add.
  8. In the Add Error Page dialog:
    1. Click Browse to locate the page that you want to act as the error page.
    2. Enter the HTTP status code that will cause the error page to be opened in the Error Code field.
    3. Enter the exception that will cause the error page to load in the Exception Type field.
    4. Click OK.

Alternatively, you can click XML at the top of the editor pane and enter the error page mapping by hand using the following elements:

  • An exception-type element specifying either the exception or the HTTP status code that will cause the error page to be opened.
  • A location element that specifies the name of a web resource to be invoked when the status code or exception is returned. The name should have a leading forward slash (/).
  • An error-page element that encloses the previous two elements.

You can have multiple error-page elements in your deployment descriptor. Each one of the elements identifies a different error that causes an error page to open. This error page can be the same for any number of error-page elements.


Note –

You can also define error screens for a JSP page contained in a WAR. If error screens are defined for both the WAR and a JSP page, the JSP page’s error page takes precedence. See Handling JSP Page Errors.


For a sample error page mapping, see the example discussed in The Example Servlets.

Declaring Resource References

If your web component uses objects such as enterprise beans, data sources, or web services, you use Java EE annotations to inject these resources into your application. Annotations eliminate a lot of the boilerplate lookup code and configuration elements that previous versions of Java EE required.

Although resource injection using annotations can be more convenient for the developer, there are some restrictions from using it in web applications. First, you can only inject resources into container-managed objects. This is because a container must have control over the creation of a component so that it can perform the injection into a component. As a result, you cannot inject resources into objects such as simple JavaBeans components. However, JavaServer Faces managed beans are managed by the container; therefore, they can accept resource injections.

Additionally, JSP pages cannot accept resource injections. This is because the information represented by annotations must be available at deployment time, but the JSP page is compiled after that; therefore, the annotation will not be seen when it is needed. Those components that can accept resource injections are listed in Table 3–1.

This section describes how to use a couple of the annotations supported by a servlet container to inject resources. Chapter 25, Persistence in the Web Tier describes how web applications use annotations supported by the Java Persistence API. Chapter 30, Securing Web Applicationsdescribes how to use annotations to specify information about securing web applications.Table 3–1 Web Components That Accept Resource Injections

Component  Interface/Class 
Servlets  javax.servlet.Servlet
Servlet Filters  javax.servlet.ServletFilter
Event Listeners  javax.servlet.ServletContextListenerjavax.servlet.ServletContextAttributeListenerjavax.servlet.ServletRequestListenerjavax.servlet.ServletRequestAttributeListenerjavax.servlet.http.HttpSessionListenerjavax.servlet.http.HttpSessionAttributeListenerjavax.servlet.http.HttpSessionBindingListener
Taglib Listeners  Same as above 
Taglib Tag Handlers  javax.servlet.jsp.tagext.JspTag
Managed Beans  Plain Old Java Objects 

Declaring a Reference to a Resource

The @Resource annotation is used to declare a reference to a resource such as a data source, an enterprise bean, or an environment entry. This annotation is equivalent to declaring a resource-ref element in the deployment descriptor.

The @Resource annotation is specified on a class, method or field. The container is responsible for injecting references to resources declared by the @Resource annotation and mapping it to the proper JNDI resources. In the following example, the @Resource annotation is used to inject a data source into a component that needs to make a connection to the data source, as is done when using JDBC technology to access a relational database:

@Resource javax.sql.DataSource catalogDS;
public getProductsByCategory() {
    // get a connection and execute the query
    Connection conn = catalogDS.getConnection();
    ..
}

The container injects this data source prior to the component being made available to the application. The data source JNDI mapping is inferred from the field name catalogDS and the type, javax.sql.DataSource.

If you have multiple resources that you need to inject into one component, you need to use the @Resources annotation to contain them, as shown by the following example:

@Resources ({
    @Resource (name="myDB" type=java.sql.DataSource),
    @Resource(name="myMQ" type=javax.jms.ConnectionFactory)
})

The web application examples in this tutorial use the Java Persistence API to access relational databases. This API does not require you to explicitly create a connection to a data source. Therefore, the examples do not use the @Resource annotation to inject a data source. However, this API supports the @PersistenceUnit and @PersistenceContext annotations for injecting EntityManagerFactory and EntityManager instances, respectively. Chapter 25, Persistence in the Web Tier describes these annotations and the use of the Java Persistence API in web applications.

Declaring a Reference to a Web Service

The @WebServiceRef annotation provides a reference to a web service. The following example shows uses the @WebServiceRefannotation to declare a reference to a web service. WebServiceRef uses the wsdlLocation element to specify the URI of the deployed service’s WSDL file:

...
import javax.xml.ws.WebServiceRef;
...
public class ResponseServlet extends HTTPServlet {
@WebServiceRef(wsdlLocation=
    "http://localhost:8080/helloservice/hello?wsdl")
static HelloService service;

Duke’s Bookstore Examples

In Chapters Chapter 4, Java Servlet Technology through Chapter 15, Internationalizing and Localizing Web Applications a common example, Duke’s Bookstore, is used to illustrate the elements of Java Servlet technology, JavaServer Pages technology, the JSP Standard Tag Library, and JavaServer Faces technology. The example emulates a simple online shopping application. It provides a book catalog from which users can select books and add them to a shopping cart. Users can view and modify the shopping cart. When users are finished shopping, they can purchase the books in the cart.

The Duke’s Bookstore examples share common classes and a database schema. These files are located in the directory tut-install/javaeetutorial5/examples/web/bookstore/. The common classes are packaged into a JAR. Each of the Duke’s Bookstore examples must include this JAR file in their WAR files. The process that builds and packages each application also builds and packages the common JAR file and includes it in the example WAR file.

The next section describes how to create the bookstore database tables and resources required to run the examples.

Accessing Databases from Web Applications

Data that is shared between web components and is persistent between invocations of a web application is usually maintained in a database. To maintain a catalog of books, the Duke’s Bookstore examples described in Chapters Chapter 4, Java Servlet Technology through Chapter 15, Internationalizing and Localizing Web Applications use the Java DB database included with the Application Server.

To access the data in a database, web applications use the new Java Persistence API (see Chapter 24, Introduction to the Java Persistence API). See Chapter 25, Persistence in the Web Tier to learn how the Duke’s Bookstore applications use this API to access the book data.

To run the Duke’s Bookstore applications, you need to first populate the database with the book data and create a data source in the application server. The rest of this section explains how to perform these tasks.

Populating the Example Database

  1. In a terminal window, go to the books directory or any one of the bookstore1 through bookstore6 example directories.
  2. Start the Java DB database server. For instructions, see Starting and Stopping the Java DB Database Server. You don’t have to do this if you are using NetBeans IDE. It starts the database server automatically.
  3. Type ant create-tables. This task runs a command to read the file tutorial.sql and execute the SQL commands contained in the file.
  4. At the end of the processing, you should see the following output:

[sql]

181 of 181 SQL statements executed successfully

When you are running create-tables, don’t worry if you see a message that an SQL statement failed. This usually happens the first time you run the command because it always tries to delete an existing database table first before it creates a new one. The first time through, there is no table yet, of course.

Creating a Data Source in the Application Server

A DataSource object has a set of properties that identify and describe the real world data source that it represents. These properties include information such as the location of the database server, the name of the database, the network protocol to use to communicate with the server, and so on.

Data sources in the Application Server implement connection pooling. To define the Duke’s Bookstore data source, you use the installed Derby connection pool named DerbyPool.

  1. Expand the Resources node.
  2. Expand the JDBC node.
  3. Select the JDBC Resources node.
  4. Click the New… button.
  5. Type jdbc/BookDB in the JNDI Name field.
  6. Choose DerbyPool for the Pool Name.
  7. Click OK.

Further Information about Web Applications

For more information on web applications, see:

Source:
https://docs.oracle.com/cd/E19879-01/819-3669/bnadr/index.html

How to Install Apache Tomcat 9 (on Windows, Mac OS X, Ubuntu) and Get Started with Java Servlet Programming

How to Install Apache Tomcat 9 (on Windows, macOS, Ubuntu) and Get Started with Java Servlet Programming

This practical can be completed in a 3-hour session. This installation and configuration guide is applicable to Tomcat 9, and possibly the earlier versions. Take note that Tomcat 9 requires JDK 8 and later.

1.  Introduction

1.1  Web Application (Webapp)

web application (or webapp), unlike standalone application, runs over the Internet. Examples of webapps are google, amazon, facebook and twitter. A webapp is typically a 3-tier (or multi-tierclient-server database application run over the Internet as illustrated in the diagram below. It comprises five components:
  1. HTTP Server: E.g., Apache HTTP Server, Apache Tomcat Server, Microsoft Internet Information Server (IIS), nginx, Google Web Server (GWS), and others.
  2. HTTP Client (or Web Browser): E.g., Internet Explorer (MSIE), FireFox, Chrome, Safari, and others.
  3. Database: E.g., Open-source MySQL, PostgreSQL, Apache Derby, mSQL, SQLite, OpenOffice’s Base; Commercial Oracle, IBM DB2, SAP SyBase, Microsoft SQL Server, Microsoft Access; and others.
  4. Client-Side Programs: Could be written in HTML Form, JavaScript, and others.
  5. Server-Side Programs: Could be written in Java Servlet/JSP, ASP, PHP, Perl, Python, JavaScript, and others.
HTTP_ClientServerSystem.png
A typical use case is:
  1. A user, via a web browser (HTTP client), issues a URL request to an HTTP server to start a webapp.
  2. The HTTP server returns an HTML form (client-side program), which is loaded and rendered in the client’s browser.
  3. The user fills up the query criteria inside the form and submits the form.
  4. The client-side program sends the query parameters to a server-side program.
  5. The server-side program receives the query parameters, queries the database based on these parameters, and returns the query result to the client-side program.
  6. The client-side program receives the query result and displays on the browser.
  7. The process repeats for the next request-response.

1.2  Hypertext Transfer Protocol (HTTP)

  • HTTP is an application layer protocol runs over TCP/IP. The IP provides support for routing and addressing (via a unique IP address for machines connected to the Internet); while TCP supports multiplexing via 64K ports from port number 0 to 65535. The default port number assigned to HTTP is TCP port 80. (Notes: TCP Port numbers below 1024 are reserved for popular protocols such as HTTP, FTP, SMTP; Port numbers 1024 and above could be used for applications.)
  • HTTP is an asynchronous request-response application-layer protocol. A client sends a request message to the server. The server then returns a response message to the client. In other words, HTTP is a pull protocol, a client pulls a page from the server (instead of server pushes pages to the clients).
  • The syntax of the message is defined in the HTTP specification.
HTTP_RequestResponseMessages.png

1.3  Apache Tomcat HTTP Server

Apache Tomcat is a Java-capable HTTP server, which could execute special Java programs known as “Java Servlet” and “Java Server Pages (JSP)”. Tomcat is an open-source project, under the “Apache Software Foundation” (which also provides the most use, open-source, industrial-strength Apache HTTP Server). The mother site for Tomcat is http://tomcat.apache.org. Alternatively, you can find tomcat via the Apache mother site @ http://www.apache.org. Tomcat was originally written by James Duncan Davison (then working in Sun) in 1998, based on an earlier Sun’s server called Java Web Server (JWS). It began at version 3.0 after JWS 2.1 it replaced. Sun subsequently made Tomcat open-source and gave it to Apache. The various Tomcat releases are:
  1. Tomcat 3.0 (1999): Reference Implementation (RI) for Servlet 2.2 and JSP 1.1.
  2. Tomcat 4.1 (Sep 2002): RI for Servlet 2.3 and JSP 1.2.
  3. Tomcat 5.0 (Dec 2003): RI for Servlet 2.4 and JSP 2.0.
  4. Tomcat 6.0 (Feb 2007): RI for Servlet 2.5 and JSP 2.1.
  5. Tomcat 7.0 (Jan 2011): RI for Servlet 3.0, JSP 2.2 and EL 2.2.
  6. Tomcat 8.0 (Jun 2014): RI for Servlet 3.1, JSP 2.3, EL 3.0 and WebSocket 1.0. Tomcat 8.5 (June 2016) supports HTTP/2, OpenSSL, TLS virtual hosting and JASPIC 1.1.
  7. Tomcat 9.0 (Jan 2018): RI for Servlet 4.0, JSP 2.3, EL 3.0, WebSocket 1.0, JASPIC 1.1.
  8. Tomcat 10.0 (???):

2.  How to Install Tomcat and Get Started with Java Servlet Programming

2.1  STEP 0: Create a Directory to Keep all your Works

I shall assume that you have created a directory called “c:\myWebProject” (for Windows) or “~\myWebProject” (for macOS) in your earlier exercises. Do it otherwise. This step is important; otherwise, you will be out-of-sync with this article and will not be able to find your files later.

2.2  STEP 1: Download and Install Tomcat

For Windows

  1. Goto http://tomcat.apache.org ⇒ Under “Tomcat 9.0.{xx} Released”, where {xx} is the latest update number ⇒ Click “Download” ⇒ Under “9.0.{xx}” ⇒ Binary Distributions ⇒ Core ⇒ “zip” (e.g., “apache-tomcat-9.0.{xx}.zip“, about 11 MB).
  2. UNZIP (right-click ⇒ Extract All) the downloaded file into your project directory “c:\myWebProject“. Tomcat shall be unzipped into directory “c:\myWebProject\apache-tomcat-9.0.{xx}“.
  3. For EASE OF USE, we shall shorten and rename this directory to “c:\myWebProject\tomcat“.
Take note of Your Tomcat Installed Directory. Hereafter, I shall refer to the Tomcat installed directory as .
For macOS
  1. Goto http://tomcat.apache.org ⇒ Under “Tomcat 9.0.{xx} Released”, where {xx} is the latest update number ⇒ Click “Download” ⇒ Under “9.0.{xx}”⇒ Binary distribution ⇒ Core ⇒ “tar.gz” (e.g., “apache-tomcat-9.0.{xx}.tar.gz“, about 10.5 MB).
  2. To install Tomcat:
    1. Double-click the downloaded tarball (e.g., “apache-tomcat-9.0.{xx}.tar.gz“) to expand it into a folder (e.g., “apache-tomcat-9.0.{xx}“).
    2. Move the extracted folder (e.g., “apache-tomcat-9.0.{xx}“) to your project directory “~/myWebProject“.
    3. For EASE OF USE, we shall shorten and rename this folder to “tomcat”, i.e., “~/myWebProject/tomcat“.
Take note of Your Tomcat Installed Directory. Hereafter, I shall refer to the Tomcat installed directory as .
For Ubuntu Read “How to Install Tomcat on Ubuntu“. You need to switch between these two articles.
For academic learning, I recommend “zip” (or “tar.gz“) package, as you could simply delete the entire directory when Tomcat is no longer needed (without running any un-installer). You are free to move or rename the Tomcat’s installed directory. You can install (unzip) multiple copies of Tomcat in the same machine.
Tomcat’s Sub-Directories
Take a quick look at the Tomcat installed directory. It contains the these sub-directories:
  • bin: contains the binaries and scripts (e.g., startup.bat and shutdown.bat for Windows; startup.sh and shutdown.sh for Unixes and macOS).
  • conf: contains the system-wide configuration files, such as server.xmlweb.xml, and context.xml.
  • webapps: contains the webapps to be deployed. You can also place the WAR (Webapp Archive) file for deployment here.
  • lib: contains the Tomcat’s system-wide library JAR files, accessible by all webapps. You could also place external JAR file (such as MySQL JDBC Driver) here.
  • logs: contains Tomcat’s log files. You may need to check for error messages here.
  • work: Tomcat’s working directory used by JSP, for JSP-to-Servlet conversion.

2.3  STEP 2: Create an Environment Variable JAVA_HOME

(For Windows)

You need to create an environment variable (system variable available to all applications) called “JAVA_HOME“, and set it to your JDK installed directory. Follow the steps HERE!
(For macOS) Skip this step. No need to do anything.

2.4  STEP 3: Configure the Tomcat Server

The Tomcat configuration files, in XML format, are located in the “conf” sub-directory of your Tomcat installed directory, e.g. “c:\myWebProject\tomcat\conf” (for Windows) or “~/myWebProject/tomcat/conf” (for macOS). The important configuration files are:
  1. server.xml
  2. web.xml
  3. context.xml
Make a BACKUP of the configuration files before you proceed!!!
Step 3(a) “conf\server.xml” – Set the TCP Port Number
Use a programming text editor (e.g., Sublime Text, Atom) to open the configuration file “server.xml“. The default TCP port number configured in Tomcat is 8080, you may choose any number between 1024 and 65535, which is not used by existing applications. We shall choose 9999 in this article. (For production server, you should use port 80, which is pre-assigned to HTTP server as the default port number.) Locate the following lines (around Line 69) that define the HTTP connector, and change port="8080" to port="9999".

port="9999" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />
Step 3(b) “conf\web.xml” – Enable Directory Listing
Again, use a programming text editor to open the configuration file “web.xml“. We shall enable directory listing by changing “listings” from “false” to “true” for the “default” servlet. This is handy for test system, but not for production system for security. Locate the following lines (around Line 122) that define the “default” servlet; and change the “listings” from “false” to “true“.
  default
  org.apache.catalina.servlets.DefaultServlet
  
    debug
    0
  
  
    listings
    true
  
  1
Step 3(c) “conf\context.xml” – Enabling Automatic Reload
We shall add the attribute reloadable="true" to the  element to enable automatic reload after code changes. Again, this is handy for test system but not recommended for production, due to the overhead of detecting changes. Locate the  start element (around Line 19), and change it to .
reloadable="true">
   ......
   ......

2.5  STEP 4: Start Tomcat Server

The Tomcat’s executable programs and scripts are kept in the “bin” sub-directory of the Tomcat installed directory.
Step 4(a) Start Server

For Windows

I shall assume that Tomcat is installed in “c:\myWebProject\tomcat“. Launch a CMD shell and issue:
c:                           // Change drive
cd \myWebProject\tomcat\bin  // Change directory to your Tomcat's binary directory
startup                      // Run startup.bat to start tomcat server
For macOS I assume that Tomcat is installed in “~/myWebProject/tomcat“. To start the Tomcat server, open a new “Terminal” and issue:
cd ~/myWebProject/tomcat/bin  // Change directory to your Tomcat's binary directory
./catalina.sh run             // Run catalina.sh to start tomcat server
new Tomcat console window appears (with Java’s coffee-cup logo as icon). Study the messages on the console. Look out for the Tomcat’s port number. Double check that Tomcat is running on port 9999 as configured. Error messages will be sent to this consoleSystem.out.println() issued by your Java servlets will also be sent to this console.
............
............
xxxxx INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-9999"]
xxxxx INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
xxxxx INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [1325] ms
(Skip Unless …) Cannot Start Tomcat: Read “How to Debug“.
Step 4(b) Start a Client to Access the Server
Start a browser (Firefox, Chrome) as an HTTP client. Issue URL “http://localhost:9999” to access the Tomcat server’s welcome page. The hostname “localhost” (with IP address of 127.0.0.1) is meant for local loop-back testing within the same machine. For users on the other machines over the net, they have to use the server’s IP address or DNS domain name in the form of “http://serverHostnameOrIPAddress:9999“. TomcatHomePage.png
(Optional) Try issuing URL http://localhost:9999/examples to view the servlet and JSP examples. Try running some of the servlet examples.
Step 4(c) Shutdown Server

For Windows

You can shutdown the tomcat server by either:
  1. Press Ctrl-C on the Tomcat console; OR
  2. Run “\bin\shutdown.bat” script. Open a new “cmd” and issue:
    c:                           // Change the current drive
    cd \myWebProject\tomcat\bin  // Change directory to your Tomcat's binary directory
    shutdown                     // Run shutdown.bat to shutdown the server
For macOS To shutdown the Tomcat server:
  1. Press Control-C (NOT Command-C) on the Tomcat console; OR
  2. Run the “/bin/shutdown.sh” script. Open a new “Terminal” and issue:
    cd ~/myWebProject/tomcat/bin  // Change current directory to Tomcat's bin directory
    ./shutdown.sh                 // Run shutdown.sh to shutdown the server
WARNING: You MUST properly shutdown the Tomcat. DO NOT kill the CAT by pushing the window’s “CLOSE” button.

2.6  STEP 5: Develop and Deploy a WebApp

Step 5(a) Create the Directory Structure for your WebApp
TomcatWebappHello.png

Let’s call our first webapp “hello“. Goto Tomcat’s “webapps” sub-directory and create the following directory structure for your webapp “hello” (as illustrated). The directory names are case-sensitive!!
  1. Under Tomcat’s “webapps“, create your webapp’s root directory “hello” (i.e., “\webapps\hello“).
  2. Under “hello“, create a sub-directory “WEB-INF” (case sensitive, a “dash” not an underscore) (i.e., “\webapps\hello\WEB-INF“).
  3. Under “WEB-INF“, create a sub-sub-directory “classes” (case sensitive, plural) (i.e., “\webapps\hello\WEB-INF\classes“).
You need to keep your web resources (e.g., HTMLs, CSSs, images, scripts, servlets, JSPs) in the proper directories:
  • hello“: The is called the context root (or document base directory) of your webapp. You should keep all your HTML files and resources visible to the web users (e.g., HTMLs, CSSs, images, scripts, JSPs) under this context root.
  • hello/WEB-INF“: This directory, although under the context root, is not visible to the web users. This is where you keep your application’s web descriptor file “web.xml“.
  • hello/WEB-INF/classes“: This is where you keep all the Java classes such as servlet class-files.
You should RE-START your Tomcat server to pick up the hello webapp. Check the Tomcat’s console to confirm that “hello” application has been properly deployed:
......
xxxxx INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory
Deploying web application directory [xxx\webapps\hello]
xxxxx INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory
Deployment of web application directory [xxx\webapps\hello] has finished in [38] ms
......
You can issue the following URL to access the web application “hello“:
http://localhost:9999/hello
You should see the directory listing of the directory “\webapps\hello“, which shall be empty at this point of time. Take note that we have earlier enabled directory listing in “web.xml“. Otherwise, you will get an error “404 Not Found”.
Step 5(b) Write a Welcome Page
Create the following HTML page and save as “HelloHome.html” in your webapp’s root directory “hello“.
1
2
3
4
5
6
7

My Name is so and so. This is my HOME.

You can browse this page by issuing this URL:
http://localhost:9999/hello/HelloHome.html
TomcatWebappHelloHome.png Alternatively, you can issue an URL to your webapp’s root “hello“:
http://localhost:9999/hello
The server will return the directory listing of your base directory. You can then click on “HelloHome.html“. Rename “HelloHome.html” to “index.html“, and issue a directory request again:
http://localhost:9999/hello
Now, the server will redirect the directory request to “index.html“, if the root directory contains an “index.html“, instead of serving the directory listing. You can check out the home page of your peers by issuing:
http://YourPeerHostnameOrIPAddr:9999/hello
http://YourPeerHostnameOrIPAddr:9999/hello/HelloHome.html
with a valid “YourPeerHostnameOrIPAddr“, provided that your peer has started his tomcat server and his firewall does not block your access. You can use command such as “ipconfig” (Windows), “ifconfig” (macOS and Unix) to find your IP address. (Skip Unless…) The likely errors are “Unable to Connect”, “Internet Explorer cannot display the web page”, and “404 File Not Found”. Read “How to Debug” section.

2.7  STEP 6: Write a “Hello-world” Java Servlet

servlet is Java program that runs inside a Java-capable HTTP Server, such as Apache Tomcat. A web user invokes a servlet by issuing an appropriate URL from a web browser (HTTP client). Before you proceed, I shall assume that you are familiar with Java Programming and have installed the followings:
  1. JDK (Read “How to install JDK and Get Started“).
  2. A programming text editor, such as Sublime Text or Atom.
Step 6(a) Write a “Hello-world” Java Servlet
A Java servlet is a Java program that runs inside a HTTP server. A web user invokes a servlet by issuing a URL from a browser (or HTTP client). In this example, we are going to write a Java servlet called HelloServlet, which says “Hello, world!”. We will configure such that web users can invoke this servlet by issuing URL http://ip_addr:port/hello/sayhello from their browser, as illustrated: TomcatWebappHelloServlet.png Write the following source codes called “HelloServlet.java” and save it under your application “classes” directory (i.e., “\webapps\hello\WEB-INF\classes\HelloServlet.java“). This servlet says “Hello”, echoes some request information, and prints a random number upon each request.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// To save as "\webapps\hello\WEB-INF\classes\HelloServlet.java"
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
 
@WebServlet("/sayhello")   // Configure the request URL for this servlet (Tomcat 7/Servlet 3.0 upwards)
public class HelloServlet extends HttpServlet {

   // The doGet() runs once per HTTP GET request to this servlet.
   @Override
   public void doGet(HttpServletRequest request, HttpServletResponse response)
         throws IOException, ServletException {
 
      // Set the response MIME type of the response message
      response.setContentType("text/html");
      // Allocate a output writer to write the response message into the network socket
      PrintWriter out = response.getWriter();
 
      // Write the response message, in an HTML page
      out.println("");
      out.println("
“); out.println(“”); out.println(“”); out.println(”

Hello, world!

“); // says Hello // Echo client’s request information out.println(” Request URI: ” + request.getRequestURI() + ” “); out.println(” Protocol: ” + request.getProtocol() + ” “); out.println(” PathInfo: ” + request.getPathInfo() + ” “); out.println(” Remote Address: ” + request.getRemoteAddr() + ” “); // Generate a random number upon each request out.println(” A Random Number: ” + Math.random() + “ “); out.println(”
");
      out.close();  // Always close the output writer
   }
}
Take note that in Line 7, we configure this HelloServlet to URL “/sayhello” via annotation @WebServlet("/sayhello"), which is applicable to Tomcat 7 onwards. In other words, the full URL shall be http://ip_addr:port/hello/sayhello to trigger this HelloServlet.
Step 6(b) Compiling the Servlet (DIFFICULT)
We need the Java Servlet API to compile the servlet. Servlet API is NOT part of JDK. Tomcat provides a copy in /lib/servlet-api.jar. We need to include this JAR file in the compilation via the -cp (classpath) option as follows:
(For Windows)
// Assume that Tomcat is installed in c:\myWebProject\tomcat
// Change directory to the Java source directory
c:
cd \myWebProject\tomcat\webapps\hello\WEB-INF\classes

// Compile
javac -cp .;c:\myWebProject\tomcat\lib\servlet-api.jar HelloServlet.java
(For macOS)
// Assume that Tomcat is installed in ~/myWebProject/tomcat
// Change directory to the Java source directory
cd ~/myWebProject/tomcat/webapps/hello/WEB-INF/classes

// Compile - Need to use $HOME instead of ~ in the "javac" command
javac -cp .:$HOME/myWebProject/tomcat/lib/servlet-api.jar HelloServlet.java
The output of the compilation is “HelloServlet.class“. Use your “File Explorer” to check the “webapps/hello/WEB-INF/classes” folder to make sure that “HelloServlet.class” has been created in the right place.
Step 6(c) Invoke the Servlet
Restart your Tomcat Server (just in case …). To invoke this servlet, start a browser, and issue the request URL configured as follows:
http://localhost:9999/hello/sayhello
You shall see the output of the servlet displayed in your web browser. Refresh the browser, you shall see a new random number upon each refresh. In other word, the doGet() method of the servlet runs once per request.
View Page Source
(For Firefox and Chrome) Right-click the page ⇒ “View Page Source” to look at the output received by the web browser (which is returned by the server). Take note that the web browser receives only the output of the servlet (generated via the out.println() statements). The client has no access to the servlet source codes (which may contain confidential information). (For macOS’s Safari browser) You need to enable “Developer Menu” under the “Preferences” to enable the “View Source” menu.

Hello, world!

Request URI: /hello/sayhello Protocol: HTTP/1.1 PathInfo: null Remote Address: 127.0.0.1 A Random Number: 0.3523682325749493

(Skip Unless…) The likely errors are “404 File Not Found” and “500 Internal Server Error”. Read “How to debug” Section.
(Optional) Inspecting HTTP Request and Response Messages
When you enter a URL (e.g., http://localhost:9999/hello/sayhello) on a web browser, an HTTP GET request message is sent to the server; and the server returns a response message for display on the web browser. You can inspect the request and response messages via Web browser’s Developer Tool. For Firefox/Chrome, press F12 (called F12 debugger) to enable “Web Console” or “Developer Tool”. Choose “Console” or “Network” pane. Enter URL http://localhost:9999/hello/sayhello (or refresh). Enable “Net” (not in Gray). Expand the link http://localhost:9999/hello/sayhello. A HTTP message consists of a header and a body. Inspect the request header and body; as well as the response header and body. The request message header is as follows:
GET http://localhost:9999/hello/sayhello HTTP/1.1
Host: localhost:9999
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Cache-Control:max-age=0
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
For this request, there is no request message body. The response message header is as follows:
HTTP/1.1 200 OK
Date: xxx, xx xxx xxxx xx:xx:xx xxx
Content-Length: 286
Content-Type: text/html;charset=ISO-8859-1
The response message body is as follows:

Hello, world!

Request URI: /hello/sayhello Protocol: HTTP/1.1 PathInfo: null Remote Address: 0:0:0:0:0:0:0:1 A Random Number: 0.4480280769255568

2.8  STEP 7: Write a Database Servlet

This section assumes that you are familiar with “Java database programming” and “MySQL database server”. Otherwise, read “Java Database Program” and “How to Install MySQL and Get Started“, respectively.
Step 7(a) Setup a Database on MySQL (Already done in the MySQL exercises)
Start your MySQL server. Take note of the server’s port number. I shall assume that the MySQL server is running on port 3306, whereas the Tomcat is running on port 9999.
// For Windows: I shall assume that MySQL is installed in "c:\myWebProject\mysql"
c:
cd \myWebProject\mysql\bin
mysqld --console

// For macOS
// Use graphical control at "System Preferences" -> MySQL
Start a MySQL client. I shall assume that there is a user called “myuser” with password “xxxx“.
// For Windows: I shall assume that MySQL is installed in "c:\myWebProject\mysql"
c:
cd \myWebProject\mysql\bin
mysql -u myuser -p
 
// For macOS: I shall assume that MySQL is installed in "/usr/local/mysql"
cd /usr/local/mysql/bin
./mysql -u myuser -p
Run the following SQL statements to create a database called “ebookshop“, with a table called “books” with 5 columns: idtitleauthorpriceqty.
create database if not exists ebookshop;

use ebookshop;

drop table if exists books;
create table books (
   id     int,
   title  varchar(50),
   author varchar(50),
   price  float,
   qty    int,
   primary key (id));

insert into books values (1001, 'Java for dummies', 'Tan Ah Teck', 11.11, 11);
insert into books values (1002, 'More Java for dummies', 'Tan Ah Teck', 22.22, 22);
insert into books values (1003, 'More Java for more dummies', 'Mohammad Ali', 33.33, 33);
insert into books values (1004, 'A Cup of Java', 'Kumar', 55.55, 55);
insert into books values (1005, 'A Teaspoon of Java', 'Kevin Jones', 66.66, 66);

select * from books;
Step 7(b) Install MySQL JDBC Driver (Already done in the previous JDBC exercises)
You need to download MySQL JDBC driver if you have not done so. Read “Installing the MySQL JDBC Driver“.
Step 7(c) Copy the MySQL JDBC Drive to Tomcat’s “lib” (IMPORTANT!!!)
Copy the MySQL JDBC Driver JAR file “mysql-connector-java-8.0.{xx}.jar” into Tomcat’s lib directory, i.e., “c:\myWebProject\tomcat\lib” (for Windows) or “~\myWebProject\tomcat\lib” (macOS).
Step 7(d) Write a Client-side HTML Form
Let’s write an HTML script to create a query form with 3 checkboxes and a submit button, as illustrated below.  Save the HTML file as “querybook.html” in your application root directory “\webapps\hello”. HtmlFormBookQuery.png
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Yet Another Bookshop

action=”http://localhost:9999/hello/query“> Choose an author: name=”author” value=”Tan Ah Teck”>Ah Teck name=”author” value=”Mohammad Ali”>Ali name=”author” value=”Kumar”>Kumar
You can browse the HTML page by issuing the following URL:
http://localhost:9999/hello/querybook.html
Check a box (e.g., “Tan Ah Teck”) and click the “Search” button. You are expected to get an error “404 File Not Found”, as you have yet to write the server-side program. But observe the URL in the browser’s navigation bar, reproduced as follows:
http://localhost:9999/hello/query?author=Tan+Ah+Teck
The URL request consists of two part: a URL corresponding to the “action” attribute of the 
 tag, and the “name=value” pair extracted from the  tag, separated by a '?'. Take note that blanks are replaced by '+' (or %20), because blanks are not allowed in the URL. If you check two boxes (e.g., “Tan Ah Teck” and “Mohammad Ali”), you will get this URL, which has two “name=value” pairs separated by an '&'.
http://localhost:9999/hello/query?author=Tan+Ah+Teck&author=Mohammad+Ali
Step 7(e) Write the Server-side Database Query Servlet
The next step is to write a Java servlet, which responses to the client’s request by querying the database and returns the query results.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// To save as "\webapps\hello\WEB-INF\classes\QueryServlet.java".
import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

@WebServlet("/query")   // Configure the request URL for this servlet (Tomcat 7/Servlet 3.0 upwards)
public class QueryServlet extends HttpServlet {

   // The doGet() runs once per HTTP GET request to this servlet.
   @Override
   public void doGet(HttpServletRequest request, HttpServletResponse response)
               throws ServletException, IOException {
      // Set the MIME type for the response message
      response.setContentType("text/html");
      // Get a output writer to write the response message into the network socket
      PrintWriter out = response.getWriter();

      // Print an HTML page as the output of the query
      out.println("");
      out.println("
“); out.println(“”); out.println(“”); try ( // Step 1: Allocate a database ‘Connection’ object Connection conn = DriverManager.getConnection( “jdbc:mysql://localhost:3306/ebookshop?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC”, “myuser“, “xxxx“); // For MySQL // The format is: “jdbc:mysql://hostname:port/databaseName”, “username”, “password” // Step 2: Allocate a ‘Statement’ object in the Connection Statement stmt = conn.createStatement(); ) { // Step 3: Execute a SQL SELECT query String sqlStr = “select * from books where author = ” + “‘” + request.getParameter(“author”) + “‘” // Single-quote SQL string + ” and qty > 0 order by price desc”; out.println(”

Thank you for your query.

“); out.println(” Your SQL statement is: ” + sqlStr + ” “); // Echo for debugging ResultSet rset = stmt.executeQuery(sqlStr); // Send the query to the server // Step 4: Process the query result set int count = 0; while(rset.next()) { // Print a paragraph … for each record out.println(” ” + rset.getString(“author”) + “, ” + rset.getString(“title”) + “, $” + rset.getDouble(“price”) + ” “); count++; } out.println(” ==== ” + count + ” records found ===== “); } catch(Exception ex) { out.println(” Error: ” + ex.getMessage() + ” “); out.println(” Check Tomcat console for details. “); ex.printStackTrace(); } // Step 5: Close conn and stmt – Done automatically by try-with-resources (JDK 7) out.println(”
");
      out.close();
   }
}
Take note that in Line 8, we configure this QueryServlet to URL “/query” via annotation @WebServlet("/query"). In other words, the full URL to trigger this QueryServlet is http://ip_addr:port/hello/query, which corresponds to the “action” attribute of the 
 tag of the “querybook.html” written earlier. TomcatWebappQueryServlet.png Compile “QueryServlet.java” as follows:
// Windows
c:                                                     // Change drive
cd \myWebProject\tomcat\webapps\hello\WEB-INF\classes  // Change directory to Java Source directory
javac -cp .;c:\myWebProject\tomcat\lib\servlet-api.jar QueryServlet.java   // Compile

// macOS
cd ~/myWebProject/tomcat/webapps/hello/WEB-INF/classes  // Change directory to Java Source directory
javac -cp .:$HOME/myWebProject/tomcat/lib/servlet-api.jar QueryServlet.java    // Compile
Use a “File Explorer”, verify that “QueryServlet.class” was generated in the “classes” directory.
Step 7(f) Invoke the Servlet from the Client-Side Form
Issue the following URL to browse the HMTL form “querybook.html” that you have created earlier:
http://localhost:9999/hello/querybook.html
Select an author (e.g., “Tan Ah Teck”) and click the submit button, which activates the following URL coded in the 
‘s “action” attribute, together with the name=value pair:
http://localhost:9999/hello/query?author=Tan+Ah+Teck
This URL “/query” triggers QueryServlet. The QueryServlet retrieves the name=value pair of “author=Tan+Ah+Teck“. Inside the QueryServlet, the method request.getParameter("author") returns “Tan Ah Teck“, which is inserted into the SQL SELECT command to query the database. The processed query result is then written to the client as an HTML document. (Skip Unless…) If you see a blank screen or incorrect output, look for error messages from the Tomcat console!!! Check “How to debug” Database Servlet Errors.

2.9  (Obsolete and Don’t Do)(Prior to Tomcat 7) Deploying Servlets using web.xml

Please skip this section. I keep it here just in case… The annotation @WebServlet("url") for deploying servlet is supported from Tomcat 7/Servlet 3.0. Prior to Tomcat 7, you need to deploy servlets via deployment descriptors in the web.xml configuration file. Create the following configuration file called “web.xml“, and save it under “webapps\hello\WEB-INF” (i.e., “\webapps\hello\WEB-INF\web.xml“).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21


 
   
 
   
      HelloWorld
      HelloServlet
   
 
   
 
   
      HelloWorld
      /sayhello
   
In the above configuration, a servlet having a class file “HelloServlet.class” is mapped to request URL “/sayhello” (via an arbitrary servlet-name “HelloWorld“), under this web application “hello“. In other words, the complete request URL for this servlet is “http://hostname:port/hello/sayhello“. This configuration file, saved under your webapp “hello“, is applicable only to this particular webapp “hello“. Restart your Tomcat server to refresh the “web.xml” file. Note: For EACH servlet, you need to write a pair of  and  elements with a common but arbitrary . Take note that all the  elements MUST be grouped together and placed IN FRONT of the  elements.

3.  A Full-Stack Web Developer

A full-stack web developer is a person who can develop both client and server software. He/She needs to be familiar the client-side (front-end) programming, server-side (back-end) programming and the database. You are now a step closer. Full Stack Web Developer

4.  (Skip Unless…) How to Debug?

“Everything that can possibly go wrong will go wrong.” The most important thing to do is to find the ERROR MESSAGES!!!
Always…
  1. Re-start Tomcat (and Check the Tomcat’s console for Error Messages)!!!
  2. Re-start your browser!!!
  3. Refresh your browser using Cntl-F5 (instead of refresh button or simply F5) to get a fresh copy, instead of from the cache.
  4. Check your spelling! Always assume that all programs are case-sensitive. Don’t type, copy and paste if possible!
  5. and MOST IMPORTANTLY – Find the ERROR MESSAGE!!!
    1. Check the Error Messages on Tomcat’s Console. Most of the error messages have a few screens of lines. You need to scroll up slowly from the last line to look for the FIRST LINE of the error messages.
      com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure  <== First line
      The last packet sent successfully to the server was 0 milliseconds ago.
      The driver has not received any packets from the server.
              at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
              at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
              at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
              at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
              ......
              ......
              at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:305)
              at java.sql.DriverManager.getConnection(DriverManager.java:579)
              at java.sql.DriverManager.getConnection(DriverManager.java:221)
              at MySQLJdbcTestJDK7.main(MySQLJdbcTestJDK7.java:7)         <== Your program's line number here (line 7)
    2. Check the Tomcat’s log files, located at “\logs“. The “catalina.yyyy-mm-dd.log” shows the Tomcat’s startup messages. Also check the “localhost.yyyy-mm-dd.log“.
  6. If things were running fine until the lightning strikes, ask yourself “What have I changed?”

4.1  Cannot Start Tomcat after Installation

SYMPTOM: Cannot start Tomcat after installation. The Tomcat console flashed and disappeared.
POSSIBLE SOLUTIONS: 
  1. Run the script "configtest.bat" (for Windows) or "./configtest.sh" (for macOS/Linux) to check
     configuration files ("server.xml", "web.xml", "content.xml").
  2. Check the Tomcat's log files, located at "\logs".
     The "catalina.{yyyy-mm-dd}.log" shows the Tomcat's startup messages.
  3. Start the tomcat in the debugging mode by running "catalina debug" (or ./catalina.sh debug) and 
     type "run" in the "jdb" prompt. Look for the error messages.
  4. If the error messages indicate that another Tomcat instance is running
     (java.net.BindException: Address already in use: JVM_Bind), kill the Tomcat process (See below).
  5. If the error messages indicate that another application is running on the Tomcat's port numbers,
     then you need to change the Tomcat's port number in "server.xml".
     You can issue command "netstat -an" to check the status of all the ports.
SYMPTOM: Cannot start Tomcat
ERROR MESSAGE: 
  SEVERE: StandardServer.await: create[localhost:8005]
  java.net.BindException: Address already in use: JVM_Bind
POSSIBLE SOLUTIONS:
  1. Another Tomcat instance has been started. Kill it (see below).
  2. Another application is running on the Tomcat's port number.
     Change the Tomcat's port number in "server.xml".
     You can issue command "netstat -an" to check the status of all the ports.
SYMPTOM: Cannot start Tomcat after installation
ERROR MESSAGE: 
  1. Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
  2. JRE_HOME environment variable is not defined
POSSIBLE SOLUTIONS:
  1. Check if JAVA_HOME is properly defined, via command "set JAVA_HOME" (for Windows)
     or "echo $JAVA_HOME" (for macOS/Linux). Check the spelling carefully.
  2. Define environment variable JAVA_HOME according to "Step 2: Create an Environment Variable JAVA_HOME".
Locating/Killing Tomcat’s Process
  • In windows, start “Task Manager”, Tomcat run as a “process” named “java.exe“. You may need to kill the process.
  • In macOS, start “Activity Monitor”. Select “All Processes” and look for “java.exe“.
  • In Linux/macOS, you may issue “ps aux | grep tomcat” to locate the Tomcat process. Note down the process ID (pid). You can kill the Tomcat process via “kill -9 pid“.

4.2  Cannot Access the Tomcat Server From Browser

ERROR MESSAGE:
  (Firefox) Unable to Connect
  (IE) Internet Explorer cannot display the webpage
  (Chrome) Oops! Google Chrome could not connect to ...
  (Safari) Safari can't connect to the server
PROBABLE CAUSES: You are simply not connecting to your Tomcat.
POSSIBLE SOLUTION:
  1. Check if your Tomcat server has been started?
  2. Check the hostname and port number of your URL (http://localhost:9999/...)

ERROR MESSAGE: Error 404 File Not Found
PROBABLE CAUSES: You have connected to your Tomcat.
  But Tomcat server cannot find the HTML file or Servlet that your requested.
POSSIBLE SOLUTION:
  1. Check your spelling! The path is case-sensitive!
  2. For HTML file request with URL http://localhost:9999/xxxx/filename.html:
     a. Open Tomcat's "webapps" directory, check if sub-directory "xxxx" exists. It is case-sensitive.
     b. Open the "xxxx" directory, check if "filename.html" exists.
  3. For servlet request with URL http://localhost:9999/xxxx/servletURL:
     a. Check the Tomcat's console for error message.
     b. Check the Tomcat console to make sure that your application "xxxx" has been deployed.
     c. Open Tomcat's "webapps" directory, check if sub-directory "xxxx" exists.
     d. Open the "xxxx" directory, check if sub-directory "WEB-INF" (uppercase with a dash) exists.
     e. Open the "WEB-INF", check if sub-directory "classes" (lowercase, plural) exists.
     f. Open your servlet, check if the servlet is mapped to servletURL
     g. Check if you have compiled the servlet. That is, the .class exisits (NOT .java).

ERROR MESSAGE: Error 500 Internal Server Error
POSSIBLE SOLUTION:
  Error 500 should have triggered many error message in the Tomcat's console.
  Go to the Tomcat's console, find the error message.

ERROR MESSAGE: Error 505: GET (or POST) method not supported
POSSIBLE SOLUTION:
  Check you servlet to make sure that you have defined a doGet() (or doPost()) method.

4.3  Java Servlet Errors

SYMPTOM: Cannot compile Java Servlet
ERROR MESSAGE: class xxxx is public, should be declared in a file named xxxx.java
CAUSES/SOLUTION:
  In Java, the filename must be the same as the classname with extension of ".java".
SYMPTOM: Cannot compile Java Servlet
ERROR MESSAGE: package javax.servlet does not exist
CAUSES/SOLUTION:
  The Java Servlet library is missing. Read "Step 6(b) Compiling the Servlet" 
  again, again and again....
SYMPTOM: A "new" servlet does not run
ERROR MESSAGE:
java.lang.IllegalStateException: Error starting child (in Tomcat console)
The servlets named [xxx] and [yyy] are both mapped to the url-pattern [zzz] which is not permitted
CAUSES/SOLUTION:
  Check to ensure that no two servlets are mapping to the SAME URL in @WebServlet("url")

4.4  Java Database Servlet Errors

ERROR MESSAGE: No suitable driver found
POSSIBLE SOLUTION:
  Check if you have done Step 7(c) Copy the MySQL JDBC Drive to Tomcat's "lib".

ERROR MESSAGE: Communications link failure
POSSIBLE SOLUTION:
  Check if you have started MySQL server.

ERROR MESSAGE: Access denied for user 'myuser'@'localhost' (using password: YES)
POSSIBLE SOLUTION:
  Wrong username or password in your servlet's getConnection()

ERROR MESSAGE: Public Key Retrieval is not allowed
POSSIBLE SOLUTION:
  Add jdbc:mysql://localhost:3306/ebookshop?allowPublicKeyRetrieval=true&useSSL=false to databaseURL.

ERROR MESSAGE: The server time zone value '...' is unrecognized or represents more than one time zone
POSSIBLE SOLUTION:
  Add jdbc:mysql://localhost:3306/ebookshop?serverTimezone=UTC to databaseURL.

ERROR MESSAGE: You have an error in your SQL syntax ...
POSSIBLE SOLUTION:
  SQL syntax error. Check you SQL statement.

REFERENCES & RESOURCES

  1. Apache Tomcat mother site @ http://tomcat.apache.org.
  2. Apache Tomcat Documentation @ “\webapps\docs“.
  3. How to install MySQL and Get Started“.
  4. Introduction to Java Database (JDBC) Programming“.
  5. Jason Brittain, Ian F. Darwin, “Tomcat The Definitive Guide“, 2nd eds, OReilly, 2007.

HTML

HTML

Full list of HTML elements

As a reminder, in most browsers you can right-click on a page and select View Source to see the HTML code used to render the page.

Basic HTML

TagDescriptionExample
<html>All content of your webpage must go inside <html></html> tags. 
<head>Contains information about the webpage.
The title tag goes inside <head></head> tags.
 
<title>Title of the webpage (what appears in the window/tab of your browser).
The text itself does not appear on webpage.
 
<body>Everything that appears on the webpage should go between these tags 
<p>Defines a paragraph (text with some space on the bottom and top).<p>This is a paragraph.</p>

This is a paragraph.

<h1>Heading tag, bold and bigger text.
You can use any number from <h1> to <h6> with <h1> being the largest heading and <h6> being the smallest.
<h3>larger heading</h3>
<h6>smaller heading</h6>

larger heading

smaller heading
<b>Apply bold formatting to text<b>bold</b>
bold
<em>Apply emphasis to text<em>emphasis</em>
emphasis
<img>

Inserts an image.

  • src is the link specifying the image to display (it is a required attribute)
  • width (and height) specifies the size of the image (it is an optional attribute)

Unlike most other tags, this start tag does not have a corresponding end tag.

<img src="http://bit.ly/1QfkvVw" width="100px">
<a>

Links to another webpage.

  • href specifies the URL of the page to link to (it is a required attribute).

There must be some text between the start and end tags to be the anchor of the link.

<a href="https://www.duke.edu/">Duke University</a>
Duke University
<div>Defines a section of the web page.<div><p>This paragraph is inside a div.</p></div>

Lists

TagDescriptionExample
<li>List item.
List items can go inside unordered list, <ul>, or ordered list, <ol> tags.
<li>HTML</li>
<ul>Unordered list, each item has a bullet point.<ul>
  <li>HTML</li>
  <li>CSS</li>
</ul>
  • HTML
  • CSS
<ol>Ordered list, each item has a number.<ol>
  <li>HTML</li>
  <li>CSS</li>
</ol>
  1. HTML
  2. CSS

Tables

TagDescriptionExample
<table>Defines a table.
By default a table has no borders and is only as wide as the text it contains.
 
<tr>Defines a table row (only has value within <table> tag).
Table rows can contain either table data elements or table header cells.
 
<td>Table data element (standard table cell).
Can contain many types of data including text, images, links, lists, or even a table.
<table>
 <tr>
  <td>
   cell 1
  </td>
  <td>
   cell 2
  </td>
 </tr>
</table>
cell 1cell 2
<th>Table header cell (a table cell with bold text).<table>
 <tr>
  <th>
   heading
  </th>
 </tr>
 <tr>
  <td>
   content
  </td>
 </tr>
</table>
heading
content

Input

Because the attributes used with input elements varies so much depending on the type of input you want to use, we have provided several specific examples of using different types of input.

ExampleDescription
<input type = "button"
       value = "change"
       onclick = "alert('clicked button')">
    
  • type is button
  • value is text that appears on button
  • onclick is event handler, specifies to call alert function when button is clicked
<input type = "color"
       value = "#001A57"
       id = "clr"
       onchange = "docolor()">
  • type is color picker
  • value is default color value
  • id lets us refer to input element in JavaScript
  • onchange is event handler, specifies to call docolor function when color is changed
<input type = "range"
       min = "10"
       max = "100"
       value = "10"
       id = "sldr"
       oninput = "dosquare()">
    
  • type is slider
  • min is minimum value, max is maximum value
  • value is default value
  • id lets us refer to input element in JavaScript
  • oninput is event handler, specifies to call dosquare function when slider is changed
<input type = "text"
       id = "finput">
    
  • type is text
  • id lets us refer to input element in JavaScript
<input type = "file"
       multiple = "false"
       accept = "image/*"
       id = "finput"
       onchange = "upload()">
    
  • type is file
  • multiple = "false" indicates user cannot select multiple files
  • accept = "image/*" indicates user can only select image files
  • value is default value
  • id lets us refer to input element in JavaScript
  • onchange is event handler, specifies to call upload function when input changes

CSS

Full list of CSS properties
Mozilla color picker tool

This website challenges people to use CSS to make as many different stylized versions as possible using the same HTML code.

Common CSS Properties and Values

PropertyExample ValuesUse withExample
colorblue
rgb(0,0,255)
#0000FF
text: paragraphs, links, list elements, table cells, headings
h1 {
    color: rgb(0,0,255);
}
font-size12pt
16px
100%
text
p {
    font-size: 14pt;
}
text-alignleft
right
center
justify
text
td {
    text-align: center;
}
background-colorblue
rgb(0,0,255)
#0000FF
table, table cell, page backgrounds
body {
    background-color: #00FF00;
}
vertical-aligntop
middle
bottom
table cells
th {
    vertical-align: top;
}
floatleft
right
images
img {
    float: right;
}
width100pxtables, table cells, images
img {
    width: 80px;
}
height100pxtables, table cells, images
td {
    height: 10px;
}
border-width5pxtables, table cells, images
table {
    border-width: 2px;
}
border-stylesolid
dotted
dashed
tables, table cells, images
table {
    border-style: solid;
}
border-colorblue
rgb(0,0,255)
#0000FF
tables, table cells, images
table {
    border-color: red;
}
border5px
10px dotted
5px dashed green
tables, table cells, images
table {
    border: 2px solid red;
}
border-collapsecollapsetable
table {
    border-collapse: collapse;
}

Course Specific JavaScript Functions

SimplePixel

For these examples, assume

  • pix1 is a pixel at coordinate (100, 200) representing the color Duke blue, with RGBA values of (0, 26, 87, 255) 
  • pix2 is a pixel at coordinate (300, 400) representing the color white, with RGBA values of (255, 255, 255, 255) 
Function nameDescriptionExample
getX()returns the pixel’s x-coordinate within the imagepix1.getX() is 100
getY()returns the pixel’s y-coordinate within the imagepix1.getY() is 200
getRed()returns the value of the pixel’s red component (always in the range 0-255)pix1.getRed() is 0
getGreen()returns the value of the pixel’s green component (always in the range 0-255)pix1.getGreen() is 26
getBlue()returns the value of the pixel’s blue component (always in the range 0-255)pix1.getBlue() is 87
getAlpha()returns the value of the pixel’s alpha, or transparency, component (always in the range 0-255)pix1.getAlpha() is 255
setRed(newR)changes the value of the pixel’s red component to newR (if newR is not in the range of 0-255 it is changed to be in that range)pix1.setRed(255) changes the color to (255, 26, 87, 255) 
setGreen(newG)changes the value of the pixel’s green component to newG (if newG is not in the range of 0-255 it is changed to be in that range)pix1.setGreen(255) changes the color to (0, 255, 87, 255) 
setBlue(newB)changes the value of the pixel’s blue component to newB (if newB is not in the range of 0-255 it is changed to be in that range)pix1.setBlue(255) changes the color to (0, 26, 255, 255) 
setAlpha(newA)changes the value of the pixel’s alpha, or transparency, component to newA (if newA is not in the range of 0-255 it is changed to be in that range)pix1.setAlpha(100) changes the color to (0, 26, 87, 100) 
setAllFrom(otherPixel)changes the value of all of the pixel’s components (its red, green, blue, and alpha) to match otherPixel‘s valuespix2.setAllFrom(pix1) changes the color of pix2 to (0, 26, 87, 255) 

SimpleImage

For these examples, assume the variable logo has the value of the image “devil.png” below. It is 100 pixels wide and 85 pixels tall.

Duke Blue Devil

Function nameDescriptionExample
new SimpleImage(filename)creates a SimpleImage to represent the image in filenamenew SimpleImage("devil.png") is
new SimpleImage(width, height)creates a SimpleImage whose dimensions are width by height. All the pixels in this image are black (0, 0, 0, 255)new SimpleImage(100, 100) is
new SimpleImage(fileInputElement)creates a SimpleImage to represent the image selected by the user using the fileInputElement given from the web pagevar input = document.getElementById("fileLoader");
var img = new SimpleImage(input);
 is

assuming the user selected that image from their computer.
getWidth()returns the image’s width, or number of pixels in the X directionlogo.getWidth() is 100
getHeight()returns the image’s height, or number of pixels in the Y directionlogo.getHeight() is 85
getPixel(x,y)returns the pixel in this image at the coordinate (xy)logo.getPixel(0, 0) is the pixel (255, 255, 255, 255) 
setPixel(x,y,pixel)copies the RGBA values from the given pixel into pixel at the (x,y) coordinates givenlogo.setPixel(50, 42, pix2) changes the color to white 
setSize(width, height)resizes the image to be width by height. The image is scaled to fit into the new dimensions.logo.setSize(300, 85) is
values()returns all the pixels in the image, starting in the upper-left corner and moving down to the lower-right corner, providing a way to access each pixel in turn
for (var pixel of logo.values()) {
// modify pixel
}
drawTo(canvas)draws the image to canvas, for drawing images on web pagesvar canvas = document.getElementById("canvas");
logo.drawTo(canvas);

Printing

Function nameDescriptionExample
print(something)displays something in the main “See It” area of the pageprint(image) shows the image
debug(something)displays something in the small area at the bottom of the “See It” area of the pagedebug(x) shows the value of the variable x

Standard JavaScript

Arithmetic Operations

OperatorDescriptionExample
+addition4 + 5 is 9
-subtraction9 - 5 is 4
*multiplication3 * 5 is 15
/division6 / 3 is 2
6 / 4 is 1.5
%mod/remainder5 % 3 is 2

Comparing Two Numbers

OperatorDescriptionExample
==is equal to3 == 3 is true
!=is not equal to3 != 3 is false
>=is greater than or equal to4 >= 3 is true
<=is less than or equal to4 <= 3 is false
>is strictly greater than4 > 3 is true
<is strictly less than3 < 3 is false

Combining Comparisons – Logic Operators

For these examples, assume the variable x has the value 5.

OperatorDescriptionExample
||returns true if at least one part of the comparison is true(x < 3 || x > 7) is false
(x < 3 || x < 7) is true
&&returns true only if both parts of the comparison are true(x > 3 && x < 7) is true
(x > 3 && x > 7) is false
!reverses the boolean value of a comparison(! x == 5) is false

Math Functions

Function nameDescriptionExample
abs(x)returns absolute value of xMath.abs(-3.6) is 3.6
Math.abs(3.2) is 3.2
ceil(x)returns x, rounded upwards to the nearest integerMath.ceil(3.6) is 4
Math.ceil(3.2) is 4
floor(x)returns x, rounded downwards to the nearest integerMath.floor(3.6) is 3
Math.floor(3.2) is 3
round(x)returns x, rounded x to the nearest integerMath.round(3.6) is 4
Math.round(3.2) is 3

Random Functions

Function nameDescriptionExample
random()returns a random number between 0 and 1Math.random() might return 0.523
Math.random() might return 0.983

Background Information

What is a Pixel?

Digital images are made of pixels. A pixel is a small point of colored light. When you look at a computer monitor, the image you see is actually made of a grid of these tiny dots of light. They are so small and so close together that it looks like one continuous picture. To get an idea of how small a pixel is, the monitor that I happen to be using as I write this has a resolution of 1440 x 900 (read as “1440 by 900”). That means that there are 1,440 pixels across the top and 900 pixels down one side, for a total of almost 1.3 million pixels.

This is what pixels might look like if they were magnified. This is an example of a 5×4 image because it is 5 pixels wide and 4 pixels tall.

Each pixel has a color value. We need a way to represent colors so that we can tell the computer which color to make each pixel. There are many color representations, but JavaScript uses a scheme called the RGBA color model. Basically, it means that a color is represented by four numbers:

  • R (the amount of red light)
  • G (the amount of green light)
  • B (the amount of blue light) and
  • A (called “alpha”, this number tells how transparent the color should be)

So each color is represented by these four numbers (“Everything’s a number”, remember?). Moreover, each of these number slots must have a value between 0 and 255. You may be wondering whether or not only 256 possibilities for each slot is enough to make all the many colors that we might want. If you have 256 possibilities for each of the R, G, and B values, (ignoring the transparency number for now) then the total number of colors available is over 16 million! It is estimated that the human eye can only detect 10 million different colors, so there’s no worry that you won’t be able to make any color you want.

Since the computer uses light to make a picture, the RGBA model is an additive color model. This means that the more the medium is added, the closer the color gets to white. Contrast this with using paint as a medium. That is a subtractive color model because the more paint you add, the further you get from white. So it should come as no surprise then that a color with R, G, and B values all 0 is black (no light) and a color with R, G, B values all 255 is white (pure light). Think of these numbers as knobs that you can turn up or down. If you turn on the red and blue lights and leave off the green light, you have shades of purple (R = 150, G = 0, B = 150, for example). The more you turn up the light, the higher the number goes and the brighter the color gets. How will you know what values to use for R, G, and B to make the color you want? If you search for “RGB color chart” on the Internet you will find lots of sites with palettes of colors and their corresponding values.

Transparency: Alpha Channel

The last value, called alpha, is also a number whose value must be between 0 and 255. This time the value of the number does not change the color’s hue, but rather the transparency of the color. If a pixel has an alpha value of 0, it is completely transparent, or invisible. If it has a value of 255, it is completely opaque. Using this transparency value allows you to have layers of color on the screen, or shapes that can be partially seen through other shapes.

Image Coordinate System

Finally, it is important to be able to distinguish one pixel from another. We do this by referring to each pixel’s location on the screen or image. Each pixel gets an X and Y value, where (0,0) is the top left corner of the screen. (This can take some getting used to as it’s not the way a Cartesian Plane is drawn in math class!)

The X value refers to how far right the pixel is, and the Y value refers to how far down the pixel is. For my computer monitor, which is 1440 x 900, the top left corner is (0,0), the top right is (1439,0), the bottom left is (0,899), the bottom right is (1439,899), and the middle is (720, 450).

 

Association, Composition and Aggregation in Java

Association

Association,Aggregation and Composition

Association is relation between two separate classes which establishes through their Objects. Association can be one-to-one, one-to-many, many-to-one, many-to-many.
In Object-Oriented programming, an Object communicates to other Object to use functionality and services provided by that object.

Composition and Aggregation are the two forms of association.


// Java program to illustrate the 
// concept of Association 
import java.io.*; 

// class bank 
class Bank 
{ 
	private String name; 
	
	// bank name 
	Bank(String name) 
	{ 
		this.name = name; 
	} 
	
	public String getBankName() 
	{ 
		return this.name; 
	} 
} 

// employee class 
class Employee 
{ 
	private String name; 
	
	// employee name 
	Employee(String name) 
	{ 
		this.name = name; 
	} 
	
	public String getEmployeeName() 
	{ 
		return this.name; 
	} 
} 

// Association between both the 
// classes in main method 
class Association 
{ 
	public static void main (String[] args) 
	{ 
		Bank bank = new Bank("Axis"); 
		Employee emp = new Employee("Neha"); 
		
		System.out.println(emp.getEmployeeName() + 
			" is employee of " + bank.getBankName()); 
	} 
} 


Output:

Neha is employee of Axis

 

Association in Java

In above example two separate classes Bank and Employee are associated through their Objects. Bank can have many employees, So it is a one-to-many relationship.

Aggregation

It is a special form of Association where:

  • It represents Has-A relationship.
  • It is a unidirectional association i.e. a one way relationship. For example, department can have students but vice versa is not possible and thus unidirectional in nature.
  • In Aggregation, both the entries can survive individually which means ending one entity will not effect the other entity



// Java program to illustrate 
//the concept of Aggregation. 
import java.io.*; 
import java.util.*; 

// student class 
class Student 
{ 
	String name; 
	int id ; 
	String dept; 
	
	Student(String name, int id, String dept) 
	{ 
		
		this.name = name; 
		this.id = id; 
		this.dept = dept; 
		
	} 
} 

/* Department class contains list of student 
Objects. It is associated with student 
class through its Object(s). */
class Department 
{ 
	
	String name; 
	private List students; 
	Department(String name, List students) 
	{ 
		
		this.name = name; 
		this.students = students; 
		
	} 
	
	public List getStudents() 
	{ 
		return students; 
	} 
} 

/* Institute class contains list of Department 
Objects. It is asoociated with Department 
class through its Object(s).*/
class Institute 
{ 
	
	String instituteName; 
	private List departments; 
	
	Institute(String instituteName, List departments) 
	{ 
		this.instituteName = instituteName; 
		this.departments = departments; 
	} 
	
	// count total students of all departments 
	// in a given institute 
	public int getTotalStudentsInInstitute() 
	{ 
		int noOfStudents = 0; 
		List students; 
		for(Department dept : departments) 
		{ 
			students = dept.getStudents(); 
			for(Student s : students) 
			{ 
				noOfStudents++; 
			} 
		} 
		return noOfStudents; 
	} 
	
} 

// main method 
class GFG 
{ 
	public static void main (String[] args) 
	{ 
		Student s1 = new Student("Mia", 1, "CSE"); 
		Student s2 = new Student("Priya", 2, "CSE"); 
		Student s3 = new Student("John", 1, "EE"); 
		Student s4 = new Student("Rahul", 2, "EE"); 
	
		// making a List of 
		// CSE Students. 
		List  cse_students = new ArrayList(); 
		cse_students.add(s1); 
		cse_students.add(s2); 
		
		// making a List of 
		// EE Students 
		List  ee_students = new ArrayList(); 
		ee_students.add(s3); 
		ee_students.add(s4); 
		
		Department CSE = new Department("CSE", cse_students); 
		Department EE = new Department("EE", ee_students); 
		
		List  departments = new ArrayList(); 
		departments.add(CSE); 
		departments.add(EE); 
		
		// creating an instance of Institute. 
		Institute institute = new Institute("BITS", departments); 
		
		System.out.print("Total students in institute: "); 
		System.out.print(institute.getTotalStudentsInInstitute()); 
	} 
} 



Output:

Total students in institute: 4
Aggregation_1

In this example, there is an Institute which has no. of departments like CSE, EE. Every department has no. of students. So, we make a Institute class which has a reference to Object or no. of Objects (i.e. List of Objects) of the Department class. That means Institute class is associated with Department class through its Object(s). And Department class has also a reference to Object or Objects (i.e. List of Objects) of Student class means it is associated with Student class through its Object(s).
It represents a Has-A relationship.

When do we use Aggregation ??
Code reuse is best achieved by aggregation.

 

Composition

Composition is a restricted form of Aggregation in which two entities are highly dependent on each other.

  • It represents part-of relationship.
  • In composition, both the entities are dependent on each other.
  • When there is a composition between two entities, the composed object cannot exist without the other entity.

Lets take example of Library.




// Java program to illustrate 
// the concept of Composition 
import java.io.*; 
import java.util.*; 

// class book 
class Book 
{ 

	public String title; 
	public String author; 
	
	Book(String title, String author) 
	{ 
		
		this.title = title; 
		this.author = author; 
	} 
} 

// Libary class contains 
// list of books. 
class Library 
{ 

	// reference to refer to list of books. 
	private final List books; 
	
	Library (List books) 
	{ 
		this.books = books; 
	} 
	
	public List getTotalBooksInLibrary(){ 
		
	return books; 
	} 
	
} 

// main method 
class GFG 
{ 
	public static void main (String[] args) 
	{ 
		
		// Creating the Objects of Book class. 
		Book b1 = new Book("EffectiveJ Java", "Joshua Bloch"); 
		Book b2 = new Book("Thinking in Java", "Bruce Eckel"); 
		Book b3 = new Book("Java: The Complete Reference", "Herbert Schildt"); 
		
		// Creating the list which contains the 
		// no. of books. 
		List books = new ArrayList(); 
		books.add(b1); 
		books.add(b2); 
		books.add(b3); 
		
		Library library = new Library(books); 
		
		List bks = library.getTotalBooksInLibrary(); 
		for(Book bk : bks){ 
			
			System.out.println("Title : " + bk.title + " and "
			+" Author : " + bk.author); 
		} 
	} 
} 



Title : EffectiveJ Java and  Author : Joshua Bloch
Title : Thinking in Java and  Author : Bruce Eckel
Title : Java: The Complete Reference and  Author : Herbert Schildt

In above example a library can have no. of books on same or different subjects. So, If Library gets destroyed then All books within that particular library will be destroyed. i.e. book can not exist without library. That’s why it is composition.

Aggregation vs Composition

  1. Dependency: Aggregation implies a relationship where the child can exist independently of the parent. For example, Bank and Employee, delete the Bank and the Employee still exist. whereas Composition implies a relationship where the child cannot exist independent of the parent. Example: Human and heart, heart don’t exist separate to a Human
  2. Type of Relationship: Aggregation relation is “has-a” and composition is “part-of” relation.
  3. Type of association: Composition is a strong Association whereas Aggregation is a weak Association.



// Java program to illustrate the 
// difference between Aggregation 
// Composition. 

import java.io.*; 

// Engine class which will 
// be used by car. so 'Car' 
// class will have a field 
// of Engine type. 
class Engine 
{ 
	// starting an engine. 
	public void work() 
	{ 
		
		System.out.println("Engine of car has been started "); 
		
	} 
	
} 

// Engine class 
final class Car 
{ 
	
	// For a car to move, 
	// it need to have a engine. 
	private final Engine engine; // Composition 
	//private Engine engine;	 // Aggregation 
	
	Car(Engine engine) 
	{ 
		this.engine = engine; 
	} 
	
	// car start moving by starting engine 
	public void move() 
	{ 
		
		//if(engine != null) 
		{ 
			engine.work(); 
			System.out.println("Car is moving "); 
		} 
	} 
} 

class GFG 
{ 
	public static void main (String[] args) 
	{ 
		
		// making an engine by creating 
		// an instance of Engine class. 
		Engine engine = new Engine(); 
		
		// Making a car with engine. 
		// so we are passing a engine 
		// instance as an argument while 
		// creating instace of Car. 
		Car car = new Car(engine); 
		car.move(); 
		
	} 
} 


Output:

Engine of car has been started 
Car is moving 

In case of aggregation, the Car also performs its functions through an Engine. but the Engine is not always an internal part of the Car. An engine can be swapped out or even can be removed from the car. That’ why we make The Engine type field non-final.

This article is contributed by Nitsdheerendra. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

 

Recommended Posts:

Source: link

JSON – Introduction

JSON – Introduction

JSON: JavaScript Object Notation.

JSON is a syntax for storing and exchanging data.

JSON is text, written with JavaScript object notation.


Exchanging Data

When exchanging data between a browser and a server, the data can only be text.

JSON is text, and we can convert any JavaScript object into JSON, and send JSON to the server.

We can also convert any JSON received from the server into JavaScript objects.

This way we can work with the data as JavaScript objects, with no complicated parsing and translations.


Sending Data

If you have data stored in a JavaScript object, you can convert the object into JSON, and send it to a server:

Example

You will learn more about the JSON.stringify() function later in this tutorial.


Receiving Data

If you receive data in JSON format, you can convert it into a JavaScript object:

Example

var myJSON = ‘{“name”:”John”, “age”:31, “city”:”New York”}’;
var myObj = JSON.parse(myJSON);
document.getElementById(“demo”).innerHTML = myObj.name;Try it Yourself »

You will learn more about the JSON.parse() function later in this tutorial.



Storing Data

When storing data, the data has to be a certain format, and regardless of where you choose to store it, text is always one of the legal formats.

JSON makes it possible to store JavaScript objects as text.

Example

Storing data in local storage// Storing data:
myObj = {name: “John”, age: 31, city: “New York”};
myJSON = JSON.stringify(myObj);
localStorage.setItem(“testJSON”, myJSON);

// Retrieving data:
text = localStorage.getItem(“testJSON”);
obj = JSON.parse(text);
document.getElementById(“demo”).innerHTML = obj.name;Try it Yourself »


What is JSON?

  • JSON stands for JavaScript Object Notation
  • JSON is a lightweight data-interchange format
  • JSON is “self-describing” and easy to understand
  • JSON is language independent *

*
JSON uses JavaScript syntax, but the JSON format is text only.
Text can be read and used as a data format by any programming language.

The JSON format was originally specified by Douglas Crockford.


Why use JSON?

Since the JSON format is text only, it can easily be sent to and from a server, and used as a data format by any programming language.

JavaScript has a built in function to convert a string, written in JSON format, into native JavaScript objects:

JSON.parse()

So, if you receive data from a server, in JSON format, you can use it like any other JavaScript object.

source:
https://www.w3schools.com/js/js_json_intro.asp