12/30/2008
sendError / setStatus
HttpServletResponse
Getting a PrintWriter object for output
PrintWriter getWriter()
javax.servlet.ServletResponse has this method.
Character encording
void setCharacterEncoding(String charset)
Invoke it before the getWriter.
Invoke it before the response is committed.
void setContentType(String type)
Invoke it before the getWriter
Invoke it before the response is committed.
javax.servlet.ServletResponse has these methods.
Redirect
void sendRedirect(String location)
Specify the relative path. If the relative path starts with "/", it's relative to the container root.
e.g. /scwcd/Test
e.g. Test
The sendRedirect method returns a response to the client, and then redirects it to "location".
You cannot use request attributes.
If you want to redirect a response to other domain, specify "location" like "http://...".
URL rewriting
String encodeUrl(String url)
String encodeRedirectURL(String url)
URL rewriting is for creating a session for a browser that doesn't support cookies.
These methods are used for "location" for the sendRedirect method.
<Sample>
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Test extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
if (req.getParameter("information").equals("")) {
res.sendRedirect("/scwcd/index.html");
} else {
PrintWriter out = res.getWriter();
out.println("<html><body>");
out.println(req.getParameter("information"));
out.println("</body></html>");
}
}
}
index.html
...
<form action="/scwcd/Test" method="post">
<input type="text" name="information" size="30" maxlength="15" /><br />
<input type="submit" value="Send"/>
</form>
...
<Result>
What you put will be displayed. If you don't put anything in the form, nothing can be displayed.
HttpServletRequest
GET / POST
You can use a hyper link for a GET request.
You can add parameters as query information.
HTTP POST
Parameters are contained within the body.
It is said that HTTP POST is safer than HTTP GET.
Transfering a request from a HTML file to a Servlet
Hyper link(GET)
<a href="/scwcd/Test?information=Hello everyone">Test</a>
The result will be "Hello everyone"
Using a form (GET)
<form action="/scwcd/Test">
<input type="text" name="information" size="30" maxlength="15" /><br />
<input type="submit" value="Send"/>
</form>
The method attribute of a form is "get" by default.
What you put in the form will be displayed in a Servlet.
In the example below, a doGet method is not defined in a Servlet, but a service method and a doPost method is defined.
In this case, the doPost metod works because every request goes through a service method.
The overridden service method calls the doPost method, so Test.java works.
Test.java
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.*;
import javax.servlet.http.*;
public class Test extends HttpServlet {
@Override
public void service(ServletRequest req, ServletResponse res) {
try {
doPost((HttpServletRequest)req, (HttpServletResponse)res);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
PrintWriter out = res.getWriter();
out.println("<html><body>");
out.println(req.getParameter("information"));
out.println("</body></html>");
}
}
12/29/2008
HttpServlet
In a Servlet, you can override doXxxx methods.
<Sample (JDK5.0+Tomcat5.5)>
Directory
scwcd
+ WEB-INF
+ src
+ sample
+ classes
+ sample
web.xml
Test.java
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
@SuppressWarnings("serial")
public class Test extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
PrintWriter out = res.getWriter();
out.println("<html><body>");
out.println("Hello");
out.println("</body></html>");
}
}
web.xml
<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<description>scwcd</description>
<display-name>scwcd</display-name>
<distributable />
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>sample.Test</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Test</servlet-name>
<url-pattern>/Test</url-pattern>
</servlet-mapping>
</web-app>
See http://localhost:8080/scwcd/Test on your browser.
<Result>
Hello
Tags in the web.xml
servlet : Information for a Servlet
servlet-name : Servlet name
servlet-class : [package name].[Servlet name]
Use a jsp-file tag for specifying a jsp file
servlet-mapping : Mapping between a Servlet and URL
url-pattern : The URL pattern for a Servlet
URL is like this:
http://[domain]/[project root]/[Savlet name]
The distributable tag
That means the application can be deployed in a distributed environment.
What is Servlet
The javax.servlet package provides basic interfaces and classes for a Servlet program.
Life cycle
init → service → doXxxx → destroy
The service method
Any request to a Servlet goes through a service method.
The service method is defined in the javax.servlet.Servlet interface.
The doXxxx method
These methods are defined in the javax.servlet.http.HttpServlet class.
In a Servlet, these methods can be overridden.
doGet HTTP GET request
doPost HTTP POST request
doPut HTTP PUT request
doHead HTTP HEAD request
doDelete HTTP DELETE request
doOptions HTTP OPTIONS request
doTrace HTTP TRACE request
Annotation
JDK 5.0 or any later version supports annortaton.
See Annotation on java.sun.com
@Override
If the method is not properly overridden, then a compile error occurs.
class Super {
void func(){
System.out.println("Super");
}
}
class Sub extends Super {
@Override
int func() {
System.out.println("Sub");
}
}
___________
@Deprecated
Warning of a deprecated method.
public static void main(String[] args) {
func();
}
@Deprecated
static void func() { }
}
___________
@SuppressWarnings("deprecation")
Suppresses the warning of a deprecated method.
@SuppressWarnings("fallthrough")
Suppresses the warning of the fall-through in a switch statement
@SuppressWarnings("finally")
Suppresses the warning that a finally block is not properly finished
@SuppressWarnings("serial")
Suppresses the warning that a serialVersionUID is not defined
When you supress more than one warning, write like this:
@SuppressWarnings({"deprecation", "finally"})
Generics
wait, notify, notifyAll
Synchronization of multiple threads
Use the 'synchronized' modifier for those cases.
In the example below, two person withdraw money from the same account.
If the savings is below 10, no one can withdraw any money.
If the savings is at or above 10, each person withdraws 10, and thus the amount of savings will never be below 0.
<Sample>
public class Sample {
public static void main(String[] arvs) {
Account account = new Account(100);
Family tom = new Family(account, "Tom");
Family bob = new Family(account, "Bob");
tom.start();
bob.start();
}
}
class Family extends Thread {
private Account account;
private String name;
Family (Account account, String name) {
this.account = account;
this.name = name;
}
public void run() {
for (int i = 0; i < 6; i++) {
if (account.withdraw(10)) {
System.out.println(
name + " withdrew money. The amount of savings is "
+ account.toString());
} else {
System.out.println(
name + " couldn't withdraw money. The amount of savings is "
+ account.toString());
}
}
}
}
/* The Account class */
class Account {
private int savings; // savings
Account (int savings) {
this.savings = savings;
}
/* Returns true if there are enough savings to withdraw */
private boolean withdrawable(int amount) {
if (savings >= amount) {
return true;
} else {
return false;
}
}
/* Returns true if the withdrawal has been made */
public synchronized boolean withdraw(int amount) {
if (withdrawable(amount)) {
// Sleep one second in order to see the flow easily
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
savings -= amount;
return true;
} else {
return false;
}
}
public String toString() {
return String.valueOf(savings);
}
}
<Result>
Tom withdrew money. The amount of savings is 90
Tom withdrew money. The amount of savings is 80
Tom withdrew money. The amount of savings is 70
Tom withdrew money. The amount of savings is 60
Tom withdrew money. The amount of savings is 50
Tom withdrew money. The amount of savings is 40
Bob withdrew money. The amount of savings is 30
Bob withdrew money. The amount of savings is 20
Bob withdrew money. The amount of savings is 10
Bob withdrew money. The amount of savings is 0
Bob couldn't withdraw money. The amount of savings is 0
Bob couldn't withdraw money. The amount of savings is 0
If you don't synchronized them, the result would be like this:
e.g.
Bob withdrew money. The amount of savings is 80
Tom withdrew money. The amount of savings is 80
Tom withdrew money. The amount of savings is 60
Bob withdrew money. The amount of savings is 60
Bob withdrew money. The amount of savings is 50
Tom withdrew money. The amount of savings is 50
Bob withdrew money. The amount of savings is 30
Tom withdrew money. The amount of savings is 30
Tom withdrew money. The amount of savings is 10
Bob withdrew money. The amount of savings is 10
Bob withdrew money. The amount of savings is -10
Tom withdrew money. The amount of savings is -10
As above, the amount of savings goes into negative numbers, which is considered strange.
Another way of synchronization
The code above can be synchronized by locking the common Account object.
public void run() {
synchronized (account) {
for (int i = 0; i < 6; i++) {
if (account.withdraw(10)) {
System.out.println(
name + " withdrew money. The amount of savings is "
+ account.toString());
} else {
System.out.println(
name + " couldn't withdraw money. The amount of savings is "
+ account.toString());
}
}
}
}
In this case, any thread except the currently running thread cannnot access all methods of the Account object.
It can be said that synchornization = locking the object
A priority of a thread
join
e.g.
There are two thread named 'ta' and 'tb'.
ta.join() means 'tb' waits until 'ta' finishes.
class R_A implements Runnable {
public void run(){
for (int i = 0; i < 100; i++) {
System.out.println("Thread "
+ Thread.currentThread().getName());
}
}
}
class R_B implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("Thread "
+ Thread.currentThread().getName());
}
}
}
public class ThreadRunnable1 {
public static void main(String[] args) {
R_A ra = new R_A();
R_B rb = new R_B();
Thread ta = new Thread(ra);
Thread tb = new Thread(rb);
ta.setName("A"); // Set a Thread name
tb.setName("B"); // Set a Thread name
ta.start();
try {
ta.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
tb.start();
}
}
<Result>
After the Thread A completes its execution, the Thread B executes its procedure.
Runnable
Create a Thread object using a class that implements the Runnable interface as an argument.
Override the run method.
class Runnable_A implements Runnable {
public void run(){
for (int i = 0; i < 100; i++) {
System.out.println("Thread "
+ Thread.currentThread().getName());
}
}
}
class Runnable_B implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("Thread "
+ Thread.currentThread().getName());
}
}
}
public class Test {
public st_atic void main(String[] args) {
Runnable_A r_a = new Runnable_A();
Runnable_B r_b = new Runnable_B();
Thread t_a = new Thread(r_a);
Thread t_b = new Thread(r_b);
t_a.setName("A"); // Set a Thread name
t_b.setName("B"); // Set a Thread name
t_a.st_art();
t_b.st_art();
}
}
<Result>
A Thread name to be displayed sometimes changes alternately.
Thread
Basic program
Extend the Thread class and override the run method
class Test {
public static void main(String[] args) {
Thread t1 = new Thread() {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("Hi");
}
}
};
Thread t2 = new Thread() {
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("World");
}
}
};
t1.start();
t2.start();
}
}
‘Hi’ or ‘World’ is randomly displayed.
‘Hi’ and ‘World’ are sometimes coming and going.
12/25/2008
Multiple threads
See java.lang.Thread about threads.
Java applications can have multiple threads of execution running concurrently. (It depends on the thread scheduling of a computer if it has only one CPU.)
<Implemetation>
Extend the java.lang.Thread class.
Implement the java.lang.Runnable interface.
<Life cycle of a thread>
Generation → Executable → Execution → Finalization
<How to make a thread unexecutable>
Use these methods.
sleep
wait
<How to make a waiting thread executable>
Use these methods.
notify
notifyAll
<How to have a running thread back to an executable state>
Use this method.
yield
<Synchronization>
Use the synchronize keyword to synchronize multiple threads if necessary.
Anonymous inner classes
An anonymous inner class doesn’t have a class name.
You can define these classes in a method.
<Sample>
public class Test {
public static void main(String[] args) {
Super super = new Super() {
@Override
void func() {
System.out.println("Anonymous class");
}
};
super.func();
}
}
class Super {
void func() {
System.out.println("Super class");
}
}
<Result>
Anonymous class
Local inner classes
A class defined in a method is called a local inner class.
The instance of a local inner class should be generated in the same method where the local inner class is defined.
You cannot use access modifiers but can use final or abstract keyword
Local variables except final variables cannot be accessed from a local inner class.
Members of an outer class can be accessed from its local inner classes.
<Sample>
public class Test {
public static void main(String[] args) {
final int x = 1;
class Local {
void func() {
System.out.println(x);
}
}
Local l = new Local();
l.func();
}
}
<Result>
1
12/23/2008
Static nested classes
You can deal with static nested classes like other static members.
<Sample>
public class Test {
public static void main(String[] args) {
Outer.Inner inner = new Outer.Inner();
inner.func();
}
}
class Outer {
static class Inner {
void func(){
System.out.println("Inner class");
}
}
}
<Result>
Inner class
12/19/2008
Inner classes
What are called inner classes are as follows:
Inner class
Static nested class
Local inner class
Anonymous class
Inner class
An instance of an outer class can reach its inner class.
<Sample>
public class Test {
public static void main(String[] args) {
Outer.Inner1 inner = new Outer().new Inner1();
inner.func();
Outer outer = new Outer();
outer.func();
}
}
class Outer {
class Inner1 {
void func(){
System.out.println("Inner class 1");
}
}
class Inner2 {
void func(){
System.out.println("Inner class 2");
}
}
void func() {
new Inner2().func();
}
}
<Result>
Inner class 1
Inner class 2
Garbage collection
Java garbage collection destroys objects as follows:
- Objects that nothing refers to
- Objects that nothing can refer to.
<Set an object to ‘null’>
If you set a variable to null, then it refers to nothing and the garbage collection destroys this object.
<Set an object to another value>
If you set a variable to another value, the object previously referred to becomes a target of the garbage collection.
Integer a = new Integer(1);
Integer b = new Integer(2);
a = b;
At this time, nothing refers to the instance ‘new Integer(1)’ and thus it becomes a target of the garbage collection.
<Isolate references>
A⇔B
A = null
B = null
The garbage collection targets them.
<Can we execute a garbage collection immediately?>
No.
You can only request a garbage collection.
When to execute it depends on JVM.
<Request a garbage collection>
・ System.gc();
・ Runtime.getRuntime().gc();
<finalize method>
A finalize method is invoked just before the garbage collection destroys an object.
A finalize method is invoked once for each object.
It is not recommended to write important procedure in a finalize method.
12/18/2008
The Collection framework
The Collection framework consists of the interfaces (List, Set, Map) and their subclasses.
You cannot use primitive values for the elements of a Collection.
<Sample>
List
for (int i = 0; i <>
list.add(new Integer(i));
}
for (int i = 0; i <>
System.out.println(list.get(i));
}
<Result>
0
1
2
3
4
12/17/2008
Override the equals method and the hashCode method
When you compare two objects of your original class with an equals method, it is better to override Object class’s equals method in your original class so that overridden equals method can return true if two objects are “semantically equal”.
The equals method in the Object class returns true if the two objects are “equal”.
Override example
public class Test {
public static void main(String[] args) {
Cat c1 = new Cat(1);
Cat c2 = new Cat(1);
System.out.println(c1.equals(c2));
}
}
class Cat {
private final int c;
Cat(int c) {
this.t = c;
}
public int getCatValue() {
return c;
}
public boolean equals(Object obj) {
if ((obj instanceof Cat) &&
(((Cat)obj).getCatValue() == c)) {
return true;
} else {
return false;
}
}
}
<Result>
true
_______
Override the hashCode method
It is highly recommended that you override the hashCode method in your original class when you override the equals method.
A HashXxx class such as the HashMap class stores objects based on their hash code, which enables a quick search.
The hashcode method in the Object class returns a unique hash code value.
Therefore, when you override it in your original class, it should return the same hash code value if the two objects are “semantically equal”.
An example of simple and appropriate implementation in the Cat class is as follows:
public int hashCode() {
return c;
}
Using your original class within the Collection framework may become dangerous unless you override the hashCode method.
12/16/2008
Wrapper classes
A wrapper class wraps a primitive value in an object.
Primitive Wrapper
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character
A constructor of a wrapper class can take a primitive value as an argument.
A wrapper class, except the Character class, can take a String value as an argument.
<Creating objects>
e.g.
・ Double d = new Double(7.0);
・ Double d = Double.valueOf(7.0);
・ Double d = Double.valueOf("7.0");
・ Double d = Double.valueOf("7.0f");
・ Short s = d.shortValue(d);
<Getting a primitive value from a wrapper object>
e.g.
・ double value = Double.parseDouble("2.0");
・ double value = Double.parseDouble("2.0d");
<Comparison of objects>
Use the == operator or an equals method to compare objects.
The equals method defined in the Object class is overridden in the wrapper classes and the String class.
However, Object’s equals method and others overridden in the String class and the wrapper class are different in behavior.
The equals method in the Object class returns true if two objects are “equal”.
An equals method in the String class or wrapper classes returns true if two objects are “semantically equal”.
<Sample>
Object object1 = new Object();
Object object2 = new Object();
System.out.println("object1 == object2 : " + (object1 == object2));
System.out.println("object1.equals(object2) : " + object1.equals(object2));
Integer int1 = new Integer(5);
Integer int2 = new Integer(5);
System.out.println("int1 == int2 : " + (int1 == int2));
System.out.println("int1.equals(int2) : " + int1.equals(int2));
<Result>
object1 == object2 : false
object1.equals(object2) : false
int1 == int2 : false
int1.equals(int2) : true