商品搜索系统架构

2015/11/11

Java Servlet工作原理

ServletContext

When the servlet container (like Apache Tomcat) starts up, it will deploy and load all web applications. When a web application get loaded, the servlet container will create the ServletContext once and keep in server's memory. The webapp's web.xml will be parsed and every <servlet>, <filter> and <listener> found in web.xml, or annotated with respectively @WebServlet, @WebFilter and @WebListener, will be created once and kept in server's memory as well. For all filters, the init() method will also be invoked immediately. When the servlet container shuts down, it will unload all web applications, invoke the destroy() of all initialized servlets and filters, and finally the ServletContext and all Servlet, Filter and Listener instances will be trashed.

When the Servlet in question has a <servlet><load-on-startup> or @WebServlet(loadOnStartup) value greater than 0, then its init() method will also immediately be invoked during startup. Those servlets are initialized in the same order as load-on-startup value represents, or if they are the same, then the order in the web.xml or @WebServlet classloading. Or, if the "load-on-startup" value us absent, then the init() method will only be invoked on very first HTTP request hitting the servlet in question.

HttpServletRequest and HttpServletResponse

The servlet container is attached to a web server which listens on HTTP requests on a certain port number, which is usually 8080 in development and 80 in production. When a client sends a HTTP request, the servlet container will create new HttpServletRequest and HttpServletResponse objects and pass it through the methods of the already-created Filter and Servlet instances whose url-pattern matches the request URL, all in the same thread.

The request object provides access to all information of the HTTP request, such as the request headers and the request body. The response object provides facility to control and send the HTTP response the way you want, such as setting headers and the body. When the HTTP response is committed and finished, then both the request and response objects will be trashed.

HttpSession

When a client visits the webapp for the first time and the HttpSession is to be obtained for the first time by request.getSession(), then the servlet container will create it, generate a long and unique ID (which you can get by session.getId()) and store it in server's memory. The servlet container will also set a Cookie in the Set-Cookie header of the HTTP response with JSESSIONID as cookie name and the unique session ID as cookie value.

As per the HTTP cookie specification, the client is required to send this cookie back in the subsequent requests in the Cookie header as long as the cookie is valid. The servlet container will determine the Cookie header of every incoming HTTP request for the presence of the cookie with the name JSESSIONID and use its value (the session ID) to get the associated HttpSession from server's memory.

The HttpSession lives until it has not been used for more than the time, a setting you can specify in web.xml, which defaults to 30 minutes. So when the client doesn't visit the webapp anymore for over 30 minutes, then the servlet container will trash the session. Every subsequent request, even though with the cookie specified, will not have access to the same session anymore. The servlet container will create a new one.

On the other hand, the session cookie on the client side has a default lifetime which is as long as the browser instance is running. So when the client closes the browser instance, then the session will be trashed at the client side. In a new browser instance the cookie associated with the session won't be sent anymore. A new request.getSession() would return a brand new HttpSession and set a cookie with a brand new session ID.

In a nutshell

  • The ServletContext lives as long as the webapp lives. It's been shared among all requests in all sessions.
  • The HttpSession lives as long as the client is interacting with the webapp with the same browser instance and the session hasn't timed out at the server side yet. It's been shared among all requests in the same session.
  • The HttpServletRequest and HttpServletResponse lives as long as the client has sent it until the complete response (the webpage) is arrived. It is not being shared elsewhere.
  • Any Servlet, Filter and Listener lives as long as the webapp lives. They are being shared among all requests in all sessions.
  • Any attribute which you set in ServletContext, HttpServletRequest and HttpSession will live as long as the object in question lives.

ThreadSafety

It's multithreaded and different threads can make use of the same instance. It would otherwise have been too expensive to recreate it on every request.

public class ExampleServlet extends HttpServlet {

    private Object thisIsNOTThreadSafe;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object thisIsThreadSafe;

        thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
        thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
    } 
}
2015/11/5

Tomcat ClassLoader HOW-TO

Overview

QQ20151028-0

Class Loader Definitions

Bootstrap

This class loader contains the basic runtime classes provided by the JVM, plus any classes from JAR files present in the System Extensions directory ($JAVA_HOME/jre/lib/ext)

System

This class loader is normally initialized from the contents of CLASSPATH environment variable. All such classes are visible to both Tomcat internal classes, and to web applications.

2015/10/28

Login and cookie caching

For login cookies, there are two common methods of storing login information in cookies: a signed cookie or a token cookie.

Signed cookies store the user's name, when they last loggedin, and whatever else the service may find useful. Along with this user-specific information, the cookie also includes a signature that allows the server to verify that the information that the browser send hasn't been altered.

Token cookies use a series of random bytes as the data in the cookie. On the server, the token is used as a key to look up the user who owns that token by querying a database of some kind.

For the visit, we'll update the login HASH for the user and record the current timestamp for the token in the ZSET of recent users. If the user was viewing an item, we also add the item to the user's recently viewed ZSET and trim that ZSET if it grows past 25 items.

2015/10/25

Java Core

What does the “static” keyword mean ? Can you override private or static method in Java ?

The static keyword denotes that a member variable or method can be accessed, without requiring an instantiation of the class to which it belongs. A user cannot override static methods in Java, because method overriding is based upon dynamic binding at runtime and static methods binded at compile time.

Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variables, which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.

For example, suppose you want to create a number of Bicycle objects and assign each a serial number, beginning with 1 for the first object. This ID number is unique to each object and is therefore an instance variable. At the same time, you need a field to keep track of how many Bicycle objects have been created. Such a field is not related to any individual object, but to the class as a whole. For this you need a class variable, numberOfBicycles.

Static methods, which have the static modifier in their declarations, should be invoked with the class name, without the need for creating an instance of the class.

The static modifier, in combination with the final modifier, is also used to define constants. The final modifier indicates that the value of this field cannot change.

Can you access non-static variable in static context?

No. A static variable in Java belongs to its classes and its value remains the same for all its instances. A static variable is initialized when the class is loaded by the JVM. If your code tries to access a non-static variable, the compiler will complain, because those variables are not created yet.

What is function overriding and overloading in Java?

  • Method overloading in Java occurs when two or more methods in the same class have the exact same name, but different parameters.

  • Method overriding is defined as the case when a child class redefines the same method as a parent class.

What is the difference between an Integer and int in Java?

Integer is a proper object. It even extends from the Number interface, so it can be interchanged with other number alike object types.

But then for performance reasons there are also access to the core primitive types, boolean, int, long, so they can be used when performance or simplicity is needed.

For example, int i = 2 will allocate 32 bits to store the number 2, whilst Integer i = Integer.valueOf(2) will allocate a full object.

If you do i = i + 2, with the int, the value inside those 32 bits gets incremented with a single CPU instruction. Fast.

If you do i = i + 2 with the Integer, in reality you're doing i = Integer.valueOf(i.intValue() + 2), calling a method to retrieve the int value, incrementing by 2, and creating a new object with that value.

Primitive types are special data types built into the language; they are not objects created from a class. That, in turn, means that int doesn't inherit from java.lang.Object in any way because only `objects created from a class

2015/10/25