Sunday, January 31, 2016

NoClassDefFoundError when using jar file in Tomcat

Before the deployment, everything is fine. But when deploy the project to tomcat server, the NoClassDefFoundError appears.

In my conclusion, simply put all JAR files to WEB-INF/lib/, without any other adjustments, your NoClassDefFoundError will be gone.


Standard Directory Layout
To facilitate creation of a Web Application Archive file in the required format, it is convenient to arrange the "executable" files of your web application (that is, the files that Tomcat actually uses when executing your app) in the same organization as required by the WAR format itself. To do this, you will end up with the following contents in your application's "document root" directory:
  • *.html, *.jsp, etc. - The HTML and JSP pages, along with other files that must be visible to the client browser (such as JavaScript, stylesheet files, and images) for your application. In larger applications you may choose to divide these files into a subdirectory hierarchy, but for smaller apps, it is generally much simpler to maintain only a single directory for these files. 
  • /WEB-INF/web.xml - The Web Application Deployment Descriptor for your application. This is an XML file describing the servlets and other components that make up your application, along with any initialization parameters and container-managed security constraints that you want the server to enforce for you. This file is discussed in more detail in the following subsection. 
  • /WEB-INF/classes/ - This directory contains any Java class files (and associated resources) required for your application, including both servlet and non-servlet classes, that are not combined into JAR files. If your classes are organized into Java packages, you must reflect this in the directory hierarchy under /WEB-INF/classes/. For example, a Java class named com.mycompany.mypackage.MyServlet would need to be stored in a file named /WEB-INF/classes/com/mycompany/mypackage/MyServlet.class
  • /WEB-INF/lib/ - This directory contains JAR files that contain Java class files (and associated resources) required for your application, such as third party class libraries or JDBC drivers.
When you install an application into Tomcat (or any other 2.2 or later Servlet container), the classes in the WEB-INF/classes/ directory, as well as all classes in JAR files found in the WEB-INF/lib/ directory, are made visible to other classes within your particular web application. Thus, if you include all of the required library classes in one of these places (be sure to check licenses for redistribution rights for any third party libraries you utilize), you will simplify the installation of your web application -- no adjustment to the system class path (or installation of global library files in your server) will be necessary.
Much of this information was extracted from Chapter 9 of the Servlet API Specification, version 2.3, which you should consult for more details.

Tuesday, January 26, 2016


  1. Class with Static functions:
    If with high calling frequency, we need to refactor to non-static function, parse with different object of the Class.
  2. Path Separator VS separator
    File.pathSeparator: separate file path in PATH environment vairable, ";"
    File.separator: "/" or "\" to split up the path of a file
  3. Close the resource with the block
    Example: SQL Clean way to close ResultSet
    Use CachedRowSet
     public static ResultSet executeQuery(String sql, String[] parameters){
      DataSource ds = DBConnector.setupDataSource();
      try (
       Connection conn = ds.getConnection();
       PreparedStatement ps = createPreparedStatement(conn,sql,parameters);
       ResultSet rs = ps.executeQuery();
      ) {
       CachedRowSet rowset = new CachedRowSetImpl();
       return rowset;
      } catch (SQLException e) {
       Logger lgr = Logger.getLogger(SqlHelper.class);
      return null;

Sunday, January 24, 2016


Oracle Filters docs

Sequence of invoking filters

Configuring a Chain of Filters

WebLogic Server creates a chain of filters by creating a list of all the filter mappings that match an incoming HTTP request. The ordering of the list is determined by the following sequence:

  1. Filters where the filter-mapping element contains a url-pattern that matches the request are added to the chain in the order they appear in the web.xml deployment descriptor.

  2. Filters where the filter-mapping element contains a servlet-name that matches the request are added to the chain after the filters that match a URL pattern.

  3. The last item in the chain is always the originally requested resource.
In your filter class, use the FilterChain.doFilter() method to invoke the next item in the chain.

Example in web.xml


Invoke sequence LogFilter -> ALogFilter -> BLogFilter


@WebFilter(filterName="LogFilter", urlPatterns="/*")
public class LogFilter implements Filter {
 private FilterConfig filterConfig;
     * Default constructor. 
    public LogFilter() {
 public void destroy() {
  filterConfig = null;
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  HttpServletRequest httpRequest = (HttpServletRequest)request;
  String uri = httpRequest.getRequestURI();
  String sequence = (String)request.getAttribute("sequence");
  request.setAttribute("sequence", sequence+" LogFilter ");
  if(uri.startsWith(httpRequest.getContextPath()+"/ValidateCode") || uri.startsWith(httpRequest.getContextPath()+"/imgs") || uri.startsWith(httpRequest.getContextPath()+"/LoginView")){
   chain.doFilter(request, response);
   HttpSession session = httpRequest.getSession();
   User user = (User)session.getAttribute("user");
   if(user!=null) chain.doFilter(request, response);
   else ((HttpServletResponse)response).sendRedirect(httpRequest.getContextPath()+"/LoginView?L");
 public void init(FilterConfig fConfig) throws ServletException {
  this.filterConfig = fConfig;

Full Example of declare and use an annotation

To see the basic concept of Annotation: here
To see the basic concept of declare an Annotation: here

Declare table and field annotation for SQL database, so when we can build ORM(Object Relationship Mapping)

SQLTable Annotation:
public @interface SQLTable {
 String value(); //table name

SQLField Annotation:
public @interface SQLField {
 String column();
 String type();
 int length();
Table structure

A Model class using annotations as description
public class Student {
 private int id;
 private String studentName;
 private int age;
 public int getId() {
  return id;
 public void setId(int id) { = id;
 public String getStudentName() {
  return studentName;
 public void setStudentName(String studentName) {
  this.studentName = studentName;
 public int getAge() {
  return age;
 public void setAge(int age) {
  this.age = age;

Use Annotation to build SQL:

public class Demo2 {
 public void test(){
   Class clazz = Class.forName("model.Student");
   //(1)get all annotations for the class
   Annotation[] annotations = clazz.getAnnotations();
   for(Annotation a: annotations){
   //(1) get the specified annotation for the class
   SQLTable table = (SQLTable) clazz.getAnnotation(SQLTable.class);
   //(2) get annotation for the field
   Field f = clazz.getDeclaredField("studentName"); //get the target field from class
   SQLField myField = f.getAnnotation(SQLField.class); //get the annotation for this field
   //use function declared in annotation
   //based on (1) and (2), we can build up all info for the related sql table   
  }catch(Exception e){

Declare Annotation

When using @interface to declare an annotation, it inherited  java.lang.annotation.Annotation interface.

  • @interface is used to declare an annotation
    format:   public @interface AnnotationName{//body}
  • Each method inside the body declares a config parameter
  1. function name is parameter name
  2. return type is parameter type(return type can only be primitive, Class, String, enum)
  3. can use "default" to declare parameter default value
  4. if there is only one parameter, normally it's name is "value"
  5. Normally we use "", or 0 to be default value, we also use -1 to assign the meaning of not exist.
  6. When using annotation, if there is only one parameter, we don't have to specify parameter name
There are four primitive Annotation
  1. @Target
  2. @Retention
  3. @Documented
  4. @Inherited
1. @Target
     Specify the annotation apply target, can be package, class, method, variables etc.

2. @Retention
    Specify when it can be applied, either source(.java) file, (.class) file, or in runtime

Declare Annotation Example

public @interface CustomAnnotation01 {
 String studentName() default "";
 int age() default 0;
 int id() default -1;
 String[] schools() default {};

Using Annotation Example
@CustomAnnotation01(schools = { "" })
public class Demo1 {
 public void test(){

To see the basic concept of Annotation: here
To see the full example of how to declare and use annotation: here


Reference from oracle tutorial

Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate.
Annotations have a number of uses, among them:
  • Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings.
  • Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.
  • Runtime processing — Some annotations are available to be examined at runtime.

Used on

  • package
  • class
  • method
  • field

@Override  //mark as override function from super classes
public String toString(){

Take a look at declaration

public @interface Override {

@Deprecated   //out of date, not suggested use
Take a look at declaration

public @interface Deprecated {

@SuppressWarnings  //ignore warning when compile
public static void test(){
List list = new ArrayList();

Take a look at declaration

public @interface SuppressWarnings {
     * The set of warnings that are to be suppressed by the compiler in the
     * annotated element.  Duplicate names are permitted.  The second and
     * successive occurrences of a name are ignored.  The presence of
     * unrecognized warning names is not an error: Compilers must
     * ignore any warning names they do not recognize.  They are, however,
     * free to emit a warning if an annotation contains an unrecognized
     * warning name.
     * Compiler vendors should document the warning names they support in
     * conjunction with this annotation type. They are encouraged to cooperate
     * to ensure that the same names work across multiple compilers.
    String[] value();

See usage of Annotation:
Declare Annotation

Friday, January 22, 2016


Location: /WEB-INF/A.jsp
WEB-INF represents web app inner files, not expose to outside.
To prevent some jsp/html file on the server directly accessed by browsers from URL, we need to put all request sensitive jsp file under WEB-INF folder.
Put other jsp/html file outside WEB-INF, so browsers can directly access those files by URL.

Normally used forward action:
<jsp:forward page="/WEB-INF/login.jsp"></jsp:forward>

When the first time visiting jsp

  1. web server will convert A.jsp to
  2. will compile to A_jsp.class

So when the first time visit jsp, response time will be slow

9 objects

  1. out
  2. request
  3. response
  4. session
  5. application   //servletContext
  6. pageContext  //only this jsp scope
  7. exception
  8. page   //this
  9. config   //servletConfig
3 syntax

  1. <%@ page
    autoFlash="true" //autoFlash to client when buffer full
    isThreadSafe = "true"
    We can use more than one page tag to make page nicer
    <%@ page import="java.util.*" %>
    <%@ page import="*" %>
  2. <%@ include file="a.jsp" %>  //static include
    //combine two jsp file to one servlet
  3. taglib

  1. <% java code %>
  2. <%=rs.getString("name")>  //output string, no ; at the end
  3. <%! int count=10%>    //servlet scope, member variable
    <%  int count=10; %>    //function scope, local variable
    <%! public int test(String a){
        return a.length();


  1. <jsp:forward page="/a.jsp"></jsp.forward>     //forward to page
    <jsp:forward page="/WEB-INF/login.jsp"></jsp:forward>
  2. <jsp:include file=""></jsp:include>    //dynamic include
    //compile each jsp to different servlet first, then combine the output result
  1. <!-- Comments -->  HTML comment, still output comment content
  2. <%-- Comments --%>  JSP comment, does not output comment content to browser

Sunday, January 17, 2016


Scope: All servlets all clients
Life cycle:
  1. created when webapp boots
  2. destroyed when webapp closed

 ServletContext servletContext = this.getServletContext();
 //ServletContext servletContext servletContext = this.getServletConfig().getServletContext();
 servletContext.setAttribute("ABC", new Object()); //(String, Object)

Init Parameter


Get Resource
 Properties pp = new Properties();
 InputStream fis = getServletContext().getResourceAsStream("WEB-INF/");


Captcha Image


Image Service

public class ValidateCodeService {
 static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 static Random rnd = new Random();
 public static String createRandomString(int length) {
  StringBuilder sb = new StringBuilder(length);
  for (int i = 0; i < length; i++)
  return sb.toString();

 public static Image getImage(String code) {
  BufferedImage image = new BufferedImage(80, 30,
  Graphics g = image.getGraphics();
  g.fillRect(0, 0, 80, 30);
  g.setFont(new Font(null, Font.BOLD, 20));
  g.drawString(code, 0, 20);
  return image;

Output servlet

URL: /ValidateCode

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  response.setDateHeader("Expires", -1);
  response.setHeader("Content-Type", "image/jped");
  String code = ValidateCodeService.createRandomString(4);
  request.getSession().setAttribute("ValidateCode", code);
  Image image = ValidateCodeService.getImage(code);
  ImageIO.write((RenderedImage) image, "jpg", response.getOutputStream());

  "Validation Code: <input type='text' name='ValidateCode'/>"
  +"<img id='ValidateCodeImg' src='"+request.getContextPath()+"/ValidateCode'>"
  +"<a href='#' rel='nofollow' title='Refresh Image' onclick=\"document.getElementById('ValidateCodeImg').src = '"+request.getContextPath()+"/ValidateCode?';return false;\">"

Saturday, January 16, 2016

MD5 encryption

 public String MD5(String md5) {
  try { md ="MD5");
   byte[] array = md.digest(md5.getBytes());
   StringBuilder sb = new StringBuilder();
   for (int i = 0; i < array.length; ++i) {
    sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
   return sb.toString();
  } catch ( e) {
   Logger lgr = Logger.getLogger(UserService.class);
   lgr.log(Level.WARNING, e.getMessage(), e);
  return null;


Session operation principle
Each session object has an id, using "JSESSIONID" in cookie to pass session id between client and server.
This cookie will be destroyed immediately when browser closed.
To still keep this session after browser closed, we need to overwrite the "JSESSIONID" cookie with the new one(in tomcat, the "JSESSIONID" string must be all uppercase):  
 HttpSession session = request.getSession();
 session.setAttribute("data", data);
 Cookie cookie = new Cookie("JSESSIONID",session.getId());
 cookie.setMaxAge(60*30); //session timeout in 30 minutes

Request with session id

Set Session
 HttpSession session = request.getSession();//get session, if no session, create a new one
 //HttpSession session = request.getSession(true); //same as no parameter
 //HttpSession session = request.getSession(false); //if no session, return null
 session.setAttribute(String, Object);
 session.setMaxInactiveInterval(30); // precise in seconds
Get Session
 session.getAttribute(String); //return null if not exists
Delete object from Session
Unbind Session
 session.invalidate(); //destroy the session, unbind all objects in session
                       //Normally used when safe sign out
  • Session stays in memory
  • One Session only work with one client browser(some wired browsers using same core may share the same session)
  • Session default life time: 30 minutes, default for site can be changed in tomcat/conf/web.xml, default for app can be changed in web.xml
  • The precise in xml configs is in minutes, setMaxInactiveInterval(30) is in seconds
  • If another request proceed within the timeout, the session clock will be reset
  • If webapp reload/restart, all session will be destroyed

Friday, January 15, 2016

Servlet life cycle

Three ways to use servlet

1. Implement Servlet interface
2. Extends GenericServlet
3. Extends HttpServlet

Servlet Functions:

          Called by the servlet container to indicate to a servlet that the servlet is being taken out of service.
          Returns a ServletConfig object, which contains initialization and startup parameters for this servlet.
          Returns information about the servlet, such as author, version, and copyright.
 voidinit(ServletConfig config)
          Called by the servlet container to indicate to a servlet that the servlet is being placed into service.
 voidservice(ServletRequest req, ServletResponse res)
          Called by the servlet container to allow the servlet to respond to a request.

init: only run one time when the very first request
destory: only run once when web server stop webapp
service: run once per request

HttpServlet Functions:



using wildcard '*' character
1: start with "/" ends with "/*"
2. "*.extension" (no "/" at beginning)

url mapping rules:
1. looking for more specific mapping first (only count from left to right)
2. "*.extension" have lower priority than others(based on 1's left to right rule)



Servlet Config xml
    <load-on-startup>1</load-on-startup> : servlet init() when load, value is call sequence

<context-param> </context-param> :


@WebServlet(name="InitServlet", urlPatterns="/InitServlet", loadOnStartup=1)

To override init or destroy function, for site open/close actions,
remember to set that servlet loadOnStartup, in case that servlet never been called

ServletConfig object

Enumeration<String> names = getServletConfig().getInitParameterNames();
    String name = names.nextElement();


request.getRequestDispatcher("/Login").forward(request, response);



  1. getRequestURL //full URL in type of StringBuffer: "http://localhost:8080/webapp/servlet1"
  2. getRequestURI //full URL in type of String: "/webapp/servlet1"
  3. getQueryString //all parameters string "name=abc&"
  4. getRemoteAddr //client IP address
  5. getRemoteHost //client host name if is registered in DNS server, return IP if not registered
  6. getRemotePort //client connection port
  7. getLocalPort //return server port "8080"
  8. getLocalAddr //web server IP address
  9. getLocalName //web server name
  10. getHeader("Host") //
  11. getHeaders() //return Enumeration
  12. getHeaderNames() //return Enumeration
  13. getParameter()
  14. getParameterValues(String name) // return String[], return null if no input
  15. getParameterNames()
Request Forward
  • request.getRequestDispatcher("/servlet1").forward(request,response);
    //forward to another servlet within webapp, share the same request and response
    //forward url can be only within the same webapp, so no "webapp" directory needed
    //keeping the same URL in browser
    //different from response.sendRedirect("/webapp/servlet1"); using different request/response
    //after the getRequestDispatcher("/servlet1").forward(request,response), all code continues to run, so make sure to return and finish the service

Thursday, January 14, 2016


 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 String nowTime = format.format(new java.util.Date());
 Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2016-4-24");

Date and Time PatternResult
"yyyy.MM.dd G 'at' HH:mm:ss z"2001.07.04 AD at 12:08:56 PDT
"EEE, MMM d, ''yy"Wed, Jul 4, '01
"h:mm a"12:08 PM
"hh 'o''clock' a, zzzz"12 o'clock PM, Pacific Daylight Time
"K:mm a, z"0:08 PM, PDT
"yyyyy.MMMMM.dd GGG hh:mm aaa"02001.July.04 AD 12:08 PM
"EEE, d MMM yyyy HH:mm:ss Z"Wed, 4 Jul 2001 12:08:56 -0700


Set cookie

 Cookie cookie = new Cookie("name","abc"); //new Cookie(String,String)
 //in seconds, default if not set: cleaned when browser closed
 response.addCookie(cookie); //remember to call addCookie

Get cookie

//Have to get all cookies as Array, then loop through each of them

Cookie cookies[] = request.getCookies(); //return null if none cookies
for(int i=0;i&ltcookies.length;i++){
 Cookie cookie = cookies[i];

  • Multiple browsers can share the same cookie 
  • If set the same key word, the old value will be replaced 
  • Every cookie can have their own life length 
  • All cookie from the same webapp will store in one single file on client hard drive, with timestamp
  • 20 most cookies a webapp can save to browser, each cookie have 4k max space
  • a browser can save 300 most cookies
Cookie life cycle
  • Cookie by default, will be destroyed when browser closed
  • setMaxAge(1000) can set length of life time for cookie
  • setMaxAge(0) destroy cookie
  • setMaxAge(-1000) cookie will destroy when browser closed
Cookie with Different Character set
String val ="中国字","utf-8");
Cookie cookie = new Cookie("name",val);
  String val =,"utf-8");

Thursday, January 7, 2016

Wireshark Filters

Search string from tcp

tcp contains facebook

To search HTTP contents from TLSv1.2 protocol

Logical expression

!(ip.src ==
!(ip.src == and  (ip.dst ==
(ip.src == or  (ip.dst ==

ip.addr ==
ip.src ==
ip.dst ==

Input Protocol names directly

tcp or udp

tcp.port == 80

!(arp or dns or icmp)

Packet lost or re-transmission tracking


Track one TCP connection
Right click on the record, "Follow TCP Stream"

HTTP Request
http.response.code == 200

Security usages
If server being attack

tcp.flags.syn == 1
tcp.flags.reset == 1

Signal RTP
sip && rtp

TCP/IP Protocols

TCP Port Numbers

21 FTP
23 Telnet
110 POP3

UDP Port Numbers
520 RIP

TCP/UDP Common Ports
53 DNS
161 SNMP
531 AOL Instant Messenger IRC

OSI Model Layers
  1. Application Layer
  2. Presentation Layer
  3. Session Layer
  4. Transport Layer
  5. Network Layer
  6. Data Link Layer
  7. Physical Layer

Reduced Layers
  1. Application Layer
  2. Transmission Layer
  3. Internet Layer
  4. Data Link Layer
  5. Physical Layer

TCP: Three-way handshake

=> SYN Seq=0
<= SYN, ACK Seq=0 Ack=1
=> ACK Seq=1 ACK=1

(response ACK = received Seq+1)

Monday, January 4, 2016

Servlet Utils

request.getContextPath()  // return "/webapp"

Tomcat default main directory:

getServletContext().getRealPath("/"); /var/lib/tomcat7/webapps/webapp1/

System.getProperty("catalina.base"); /var/lib/tomcat7

Load config file
Properties pp = new Properties();
InputStream fis = getServletContext().getResourceAsStream("WEB-INF/");

Read File

 String filePath = this.getServletContext().getRealPath("abc.text");
 FileReader fileReader = new FileReader(filePath);
 BufferedReader bufferedReader = new BufferedReader(fileReader);
 String line = bufferedReader.readLine();
 //do with line

Sunday, January 3, 2016


  • getWriter() //characters only
  • getOutputStream() //bytes and characters.getByte()

We cannot use both method for one response, because an output will be auto closed, so the other output will not go through.
  • sendRedirect()
    response.sendRedirect("/webapp/anotherPage")// use at least "webapp" go back to client, client browser then send request to the new url
    //request.getContextPath() will return "/webapp"
    //the url can be anywhere in the world
    //the url from browser will change to the new url
    //after the sendRedirect, all code continues to run, so make sure to return and finish the service
    //To prevent user refreshing page, normally we use sendRedirect to direct to another url, so when user refresh, it keeps in the new url
  • flush()
    when response.flush() called, print writer committed all buffer to client, it can still push more content to client, but no forward contents will be affected.
    So if we call flush() first, request.getRequestDispatcher(url).forward(req,res) will not affect anything on the client side
    And before flush(), if we call request.getRequestDispatcher(url).forward(req,res) the printed buffer will not be affect, client will only see the forwarded contents.
  • Refresh: 1;url=     //redirect to url after 1 second
    //response.setHeader("Refresh", "5;url=");
  • cache: set http header, disable/enable cache
    response.setDateHeader("Expires",-1); //or value to System.currentTimeMillis()+1*1000;
  • download file
    response.setHeader("Content-Disposition", "attachment; filename=winter.jpg");
    String path = getServletContext().getRealPath("/images/Winter.jpg");
    FileInputStream fis = new FileInputStream(path);
    byte buff[] = new byte[1024];
    int length=0;
    response.getOutputStream().write(buff, 0, length);
                    • Image type
                      response.setHeader("Content-Type", "image/jped");
                    • Encode URL, with SESSIONID in url
                      url = response.encodeURL("/webapp/servlet1");
                      // return /webapp/servlet1?SESSIONID=ABCDEFGHIJKLMN
                    • Captcha

                    1. Control response header, so you can manage the actions from browser
                    2. Use HttpServletResponse provided functions
                    3. Output stream will be auto closed when service is finished

                    Saturday, January 2, 2016

                    Character Encoding Issue, all solutions

                      <property name="hibernate.connection.CharSet">utf8</property>
                      <property name="hibernate.connection.characterEncoding">utf8</property>
                      <property name="hibernate.connection.useUnicode">true</property>

                    Here is an doc for MySQL and Java io:

                    Server encoding: iso-8859-1

                    Set page encoding to show Chinese character

                    Data request

                    1. form post
                    2. form get
                    3. url from html
                    4. sendRedirect

                    1. form post

                    Browser: utf-8

                    Web Server: iso-8859-1


                    2. form get / 3. url from html
                    Browser: utf-8

                    Web Server: iso-8859-1

                    Solution 1

                    public class CharacterEncoding implements Filter {
                     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
                      request.setCharacterEncoding("utf-8"); //set request character encoding
                      chain.doFilter(request, response);
                     public void init(FilterConfig filterConfig) throws ServletException {
                     public void destroy() {

                    In web.xml
                    Write a filter by yourself


                    or Spring Web Filter(do not need to write a class then)
                     <!-- Encoding with spring filter -->

                    Solution 2

                    Solution 3
                    new String(request.getParameter("name").getBytes("iso-8859-1"),"utf-8");

                    4. sendRedirect or All strings in URL

                    String info=,"utf-8");

                    Data Response


                    Cookie with Different Character set
                    String val ="中国字","utf-8");
                    Cookie cookie = new Cookie("name",val);
                      String val =,"utf-8");
                    Properties file
                    For character encoding in properties file
                    Use native2ascii from jdk/bin/, copy the String into native2ascii, it will translate to ascii

                    HTTP Protocol

                    1. http is built based on tcp/ip
                    2. Hyper Text Transfer Protocol
                    3. Http 1.0, and 1.1, now normally using 1.1
                        http1.0: short time connection, disconnect immediately
                        http1.1: longer time connection, 30 seconds

                    Request Header
                    GET /test/hello.html HTTP/1.1
                    Accept: */*
                    Referer: http://localhost:8080/test/abc.html
                    Accept-Language: zh-cn
                    User-Agent: Mozilla/4.0
                    Accept-Encoding: gzip, deflate
                    Host: localhost:8080
                    Connection: Keep-Alive
                    [empty line]

                    1. Accept: text/html, image/*
                    2. Accept-Charset: ISO-8859-1
                    3. Accept-Encoding: gzip, compress
                    4. Accept-Language: en-us,zh-cn
                    5. Host:
                    6. If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT    //cache time, refresh if there is newer
                    7. Referer: //tell host where this request come from, prevent spam
                    8. User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
                    9. Cookie
                    10. Connection: close    // or Keep-Alive
                    11. Date: Tue, 11 Jul 2000 18:23:51 GMT

                    Request Methods:


                    Response Header

                    1. HTTP/1.1 200 OK
                    2. Location: //tell browser to redirect new url
                    3. Server: apache tomcat
                    4. Content-Encoding: gzip
                    5. Content-Length: 80
                    6. Content-Language: zh-cn
                    7. Content-Type: text/html; charset=GB2312 //response.setContentType("text/html;charset=GB2312");
                    8. Last-Modified: Tue, 11 Jul 2000 18:23:51 GMT
                    9. Refresh: 1;url=     //redirect to url after 1 second
                      //response.setHeader("Refresh", "5;url=");
                    10. Content-Disposition: attachment;
                      //tell browser that there is file to download
                    11. Transfer-Encoding: chunked     //checksum verified
                    12. Set-Cookie:SS=Q0=5Lb_nQ; path=/search   //to be introduced
                    13. Expires: -1                               //tell browser(IE) how to cache data
                    14. Cache-Control: no-cache         //tell browser(FireFox) how to cache data
                    15. Pragma: no-cache                    //tell browser(some browser) how to cache data
                      //response.setDateHeader("Expires",-1); //or value to System.currentTimeMillis()+1*1000;
                    16. Connection: close/Keep-Alive
                    17. Date: Tue, 11 Jul 2000 18:23:51 GMT

                    State Code

                    • 200 normal
                    • 302 server request browser redirect to another resource
                      // or response.setStatus(302); response.setHeader("Location","anotherPage");
                    • 404 not found
                    • 500 server error
                      throw new RuntimeException();