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.

See https://tomcat.apache.org/tomcat-7.0-doc/appdev/deployment.html

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

memo


  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
  4.  
     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();
       rowset.populate(rs);
       return rowset;
      } catch (SQLException e) {
       Logger lgr = Logger.getLogger(SqlHelper.class);
       lgr.log(Level.WARNING,e.getMessage(),e);
      }
      return null;
     }
sdf

Sunday, January 24, 2016

ServletFilter


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

  <filter-mapping>
   <filter-name>LogFilter</filter-name>
   <servlet-name>*</servlet-name>
  </filter-mapping>
  <filter-mapping>
   <filter-name>ALogFilter</filter-name>
   <servlet-name>*</servlet-name>
  </filter-mapping>
  <filter-mapping>
   <filter-name>BLogFilter</filter-name>
   <servlet-name>*</servlet-name>
  </filter-mapping>

Invoke sequence LogFilter -> ALogFilter -> BLogFilter


Example LogFilter.java

@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);
  }
  else{
   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

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

SQLTable Annotation:
@Target(value=ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLTable {
 String value(); //table name
}

SQLField Annotation:
@Target(value=ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLField {
 String column();
 String type();
 int length();
}
Table structure

A Model class using annotations as description
@SQLTable("student")
public class Student {
 @SQLField(column="id",type="int",length=10)
 private int id;
 @SQLField(column="name",type="varchar",length=10)
 private String studentName;
 @SQLField(column="age",type="int",length=3)
 private int age;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.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 {
 @Test
 public void test(){
  try{
   Class clazz = Class.forName("model.Student");
   
   //(1)get all annotations for the class
   Annotation[] annotations = clazz.getAnnotations();
   for(Annotation a: annotations){
    System.out.println(a);
   }
   //(1) get the specified annotation for the class
   SQLTable table = (SQLTable) clazz.getAnnotation(SQLTable.class);
   System.out.println(table);
   
   //(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
   System.out.println(myField.column()+","+myField.type()+","+myField.length());  
   
   //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

//@Target(value=ElementType.METHOD)
@Target(value={ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
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 {
 @CustomAnnotation01(studentName="AAA",age=0,id=1001,schools={"aaa","bbb"})
 public void test(){
  
 }
}

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

Annotation

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}


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

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}


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

Take a look at declaration

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
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

JSP

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 A_jsp.java
  2. A_jsp.java 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

Command
  1. <%@ page
    contentType="text/html;charset=utf-8"
    language="java"
    import="java.util.*,java.net.*"
    pageEncoding="utf-8"
    session="true"
    buffer="none|8k|"
    autoFlash="true" //autoFlash to client when buffer full
    isThreadSafe = "true"
    errorPage="/error"
    isErrorPage="false"
    %>
    We can use more than one page tag to make page nicer
    <%@ page import="java.util.*" %>
    <%@ page import="java.net.*" %>
  2. <%@ include file="a.jsp" %>  //static include
    //combine two jsp file to one servlet
  3. taglib
Script

  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();
    }%>

Action

  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
Comment
  1. <!-- Comments -->  HTML comment, still output comment content
  2. <%-- Comments --%>  JSP comment, does not output comment content to browser

Sunday, January 17, 2016

ServletContext

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
  
  <context-param>
    <param-name>Country</param-name>
    <param-value>China</param-value>
  </context-param>


    request.getServletContext().getInitParameter("Country");

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

 getServletContext().getRealPath("WEB-INF/settings.properties");

Captcha Image

Example

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++)
   sb.append(AB.charAt(rnd.nextInt(AB.length())));
  return sb.toString();
 }

 public static Image getImage(String code) {
  BufferedImage image = new BufferedImage(80, 30,
    BufferedImage.TYPE_INT_RGB);
  Graphics g = image.getGraphics();
  g.setColor(Color.WHITE);
  g.fillRect(0, 0, 80, 30);
  g.setColor(Color.BLACK);
  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("Cache-Control","no-cache");
  response.setHeader("Pragma","no-cache");
  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());
 }

View
 out.println(
  "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?'+Date.now();return false;\">"
    +"Refresh"
         +"</a>"
    +"<br>");

Saturday, January 16, 2016

MD5 encryption

 public String MD5(String md5) {
  try {
   java.security.MessageDigest md = java.security.MessageDigest.getInstance("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 (java.security.NoSuchAlgorithmException e) {
   Logger lgr = Logger.getLogger(UserService.class);
   lgr.log(Level.WARNING, e.getMessage(), e);
  }
  return null;
 }

HttpSession


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
 response.addCookie(cookie);

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
 request.getSession();
 session.getAttribute(String); //return null if not exists
 
Delete object from Session
 session.removeAttribute(String);
Unbind Session
 request.getSession();
 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
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    
  • 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:

 voiddestroy()
          Called by the servlet container to indicate to a servlet that the servlet is being taken out of service.
 ServletConfiggetServletConfig()
          Returns a ServletConfig object, which contains initialization and startup parameters for this servlet.
 java.lang.StringgetServletInfo()
          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:

doGet
doPost


urlPatterns:

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)


HttpServletResponse

setContentType("text/html")
setCharacterEncoding("utf-8")
setCharacterEncoding()


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

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

Or

@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

this.getServletConfig().getInitParameter("encoding")
Enumeration<String> names = getServletConfig().getInitParameterNames();
while(names.hasMoreElements()){
    String name = names.nextElement();
    ...
}

Redirection

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






HttpServletRequest

Functions

  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&email=abc@gvace.com"
  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



 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
"yyMMddHHmmssZ"010704120856-0700
"yyyy-MM-dd'T'HH:mm:ss.SSSZ"2001-07-04T12:08:56.235-0700
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"2001-07-04T12:08:56.235-07:00
"YYYY-'W'ww-u"2001-W27-3


Cookie

Set cookie

 Cookie cookie = new Cookie("name","abc"); //new Cookie(String,String)
 cookie.setMaxAge(1000); 
 //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];
 cookie.getName();
 cookie.getValue();
 cookie.getMaxAge();
}



  • 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
  Saving
String val = java.net.URLEncoder.encode("中国字","utf-8");
Cookie cookie = new Cookie("name",val);
Getting
  String val = java.net.URLDecoder.decode(cookie.getValue(),"utf-8");

Thursday, January 7, 2016

Wireshark Filters


Search string from tcp

tcp contains facebook

To search HTTP contents from TLSv1.2 protocol
https://jimshaver.net/2015/02/11/decrypting-tls-browser-traffic-with-wireshark-the-easy-way/


Logical expression

!(ip.src == 192.168.68.18)
!(ip.src == 192.168.68.18) and  (ip.dst == 192.168.69.7)
(ip.src == 192.168.68.18) or  (ip.dst == 192.168.69.7)

IP
ip.addr == 192.168.0.1
ip.src == 192.168.0.1
ip.dst == 192.168.0.1

Input Protocol names directly

tcp
dns
http
udp
tcp or udp

tcp.port == 80

!(arp or dns or icmp)


Packet lost or re-transmission tracking

tcp.analysis.flags


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


HTTP Request
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
25 SMTP
80 HTTP
110 POP3
443 HTTPS

UDP Port Numbers
69 TFTP
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/settings.properties");
pp.load(fis);


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
 bufferedReader.close();
 fileReader.close();

Sunday, January 3, 2016

HttpServletResponse

Output:
  • 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=http://www.baidu.com     //redirect to url after 1 second
    //response.setHeader("Refresh", "5;url=http://www.sohu.com");
  • cache: set http header, disable/enable cache
    response.setDateHeader("Expires",-1); //or value to System.currentTimeMillis()+1*1000;
    response.setHeader("Cache-Control","no-cache");
    response.setHeader("Pragma","no-cache");=
  • 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;
    while((length=fis.read(buff))>0){
    response.getOutputStream().write(buff, 0, length);
    }
    response.getOutputStream().close();
    fis.close();
                    • 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


                    Summary
                    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

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



                    MySQL
                    Here is an doc for MySQL and Java io: http://blog.csdn.net/liuxueyongyu/article/details/2026788

                    Server encoding: iso-8859-1

                    Set page encoding to show Chinese character
                    response.setContentType("text/html;charset=utf-8");


                    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

                    Solution
                    request.setCharacterEncoding("utf-8")

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

                    Web Server: iso-8859-1

                    Solution 1

                    @WebFilter("/CharacterEncoding")
                    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);
                     }
                     @Override
                     public void init(FilterConfig filterConfig) throws ServletException {
                     }
                     @Override
                     public void destroy() {
                     }
                    }
                    


                    In web.xml
                    Write a filter by yourself

                    <filter>
                     <filter-name>CharacterEncoding</filter-name>
                     <filter-class>com.gvace.notebook.web.filter.CharacterEncoding</filter-class>
                    </filter>
                    <filter-mapping>
                     <filter-name>CharacterEncoding</filter-name>
                     <url-pattern>/*</url-pattern>
                    </filter-mapping>
                    

                    or Spring Web Filter(do not need to write a class then)
                     <!-- Encoding with spring filter -->
                     <filter>
                      <filter-name>encoding</filter-name>
                      <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
                      <init-param>
                       <param-name>encoding</param-name>
                       <param-value>UTF-8</param-value>
                      </init-param>
                     </filter>
                     <filter-mapping>
                      <filter-name>encoding</filter-name>
                      <url-pattern>/*</url-pattern>
                     </filter-mapping>
                    


                    Solution 2
                    request.setCharacterEncoding("utf-8")

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




                    4. sendRedirect or All strings in URL

                    String info= java.net.URLEncoder.encode(name,"utf-8");
                    response.sendRedirect("EncodingPro/Welcome?username="+info);


                    Data Response

                    response.setContentType("text/html;charset=utf-8");


                    Cookie with Different Character set
                      Saving
                    String val = java.net.URLEncoder.encode("中国字","utf-8");
                    Cookie cookie = new Cookie("name",val);
                    
                    Getting
                      String val = java.net.URLDecoder.decode(cookie.getValue(),"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]
                    dataname1=data1
                    dataname2=data2

                    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: www.sohu.com:80
                    6. If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT    //cache time, refresh if there is newer
                    7. Referer: http://www.sohu.com/index.jsp //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:

                    POST GET HEAD OPTIONS DELETE TRACE PUT


                    Response Header


                    1. HTTP/1.1 200 OK
                    2. Location: http://www.baidu.com //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=http://www.baidu.com     //redirect to url after 1 second
                      //response.setHeader("Refresh", "5;url=http://www.sohu.com");
                    10. Content-Disposition: attachment; filename=aaa.zip
                      //tell browser that there is file to download
                      //response.setHeader("Content-Disposition","attachment; filename=aaa.zip");
                    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;
                      //response.setHeader("Cache-Control","no-cache");
                      //response.setHeader("Pragma","no-cache");
                    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
                      response.sendRedirect("anotherPage")
                      // or response.setStatus(302); response.setHeader("Location","anotherPage");
                    • 404 not found
                    • 500 server error
                      throw new RuntimeException();