My Calendar

2015年1月29日 星期四

HttpServletResponse

HttpServletResponse是Servlet處理好的內容發送到瀏覽器的一個物件.

發送數據到瀏覽器的方法








設定回應標頭的方法



















設定HTTP Status Code的方法






HTTP Status Code

HTTPServletResponse 定義了很多狀態碼













HttpServletResponse常見的應用

1.使用PrintWriter將資料回傳給瀏覽器
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/demo")
public class Demo extends HttpServlet {

 private static final long serialVersionUID = -7819316605366593662L;

 public Demo() {
        super(); 
 }

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
  //設定UTF-8編碼
  response.setCharacterEncoding("UTF-8");
  //設定header告訴瀏覽器要以UTF-8的编码显示資料,如果沒有設定,瀏覽器顯示中文字將會出現亂碼
  response.setHeader("content-type", "text/html;charset=UTF-8");
  PrintWriter writer = response.getWriter();
  writer.println("你好");
 }

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  
 }
}

運行結果如下:










2.檔案下載

在網頁開發中下載檔案大家經常使用到的功能,使用HttpServletResponse就可以實現這個功能。話不多說直接上code.

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/demo")
public class Demo extends HttpServlet {

 private static final long serialVersionUID = -7819316605366593662L;

 public Demo() {
    super(); 
 }

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
 { 
   //1.讀取檔案
   File downloadFile = new File("D:\\測試.jpg");
   //2.下載文件的名稱
   String fileName = downloadFile.getName();

   //3.設定content-disposition標頭讓瀏覽器以下载的形式打開文件
   response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
  
   int len;
   InputStream in = new FileInputStream(downloadFile);
   //3.設定緩衝區
   byte[] buffer = new byte[1024];
  
   //4. 透過response物件獲取OutputStream
   OutputStream os = response.getOutputStream();
 
   //5.將FileInputStream寫入到buffer緩衝區;
   while ((len = in.read(buffer)) > 0) {
    //6.使用OutputStream将緩衝區的資料输出到瀏覽器
    os.write(buffer, 0, len);
   }
  
   os.close();
   in.close();
}

P.S: 檔案是中文名稱要使用URLEncoder.encode方法進行編碼,否則會出現檔案名亂會是亂碼。

運行結果如下:



























3. 產生驗證碼.
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@WebServlet("/demo")
public class Demo extends HttpServlet {

 private static final long serialVersionUID = -7819316605366593662L;

 public Demo() {
    super(); 
 }

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
  
  //设置refresh標頭讓瀏覽器每3秒钟刷新一次
  response.setHeader("refresh", "3");
  //在記憶體產生一張寬60高20的圖片
  BufferedImage image = new BufferedImage(60, 20, BufferedImage.TYPE_INT_RGB);
  Graphics2D g = (Graphics2D)image.getGraphics();//得到圖片
  g.setColor(Color.WHITE);//设置图片
  g.fillRect(0, 0, 60, 20);//背景顏色填滿
  //3.將一個亂數寫在圖片上
  g.setColor(Color.RED);//設定图片上字體的顏色
  g.setFont(new Font(null, Font.BOLD, 20));
  g.drawString(randomNum(), 0, 20);
     //4.設定標頭头控制瀏覽器以图片的方式打開
  response.setContentType("image/jpeg");
  //5.設定响应头控制浏览器不缓存图片数据
  response.setDateHeader("expries", -1);
  response.setHeader("Cache-Control", "no-cache");
  //6.將图片送出給瀏覽器
  ImageIO.write(image, "jpg", response.getOutputStream());
 }

 private String randomNum()
 {
  Random random = new Random();
  String num = random.nextInt(99999)+"";
  StringBuffer sb = new StringBuffer();
  for (int i = 0; i < 5-num.length(); i++) 
        sb.append("0");
  
  num = sb.toString()+num;
  return num;
 }

運行結果如下:






2015年1月25日 星期日

HttpServletRequest

HttpServletRequest

關於HttpServletRequest
當 Web 容器收到 HTTP 的請求時,容器會自動收集 web.xml@WebServlet 所定義的資訊,並產生 HttpServletRequest 物件,這個物件可以取得HTTP請求中的資訊。可以在 Servlet 中處理請求,或是將請求轉發給另一個 Servlet 進行處理。各個 Servlet/JSP 在同一個請求週期中需要共用資料的時候,可以透過 HttpServletRequest 物件設定 attribute.

處理請求參數和標頭
HttpServletRequest 定義了一些方法可以取得 HTTP 請求的資訊。例如可以使用以下的方法取得請求參數:

1) getParameter() :

指定請求參數的名稱取得值,例如:
             
String userName = request.getParameter("name");

getParameter() 回傳的是 String 物件, 若請求中沒有指定的參數名稱,則會回傳null。

2) getParameterValues() :

當表單上有可以複選的選項,例如 Checkbox, List 等等,同一個參數將會有多個值,這時候可以使用 getParameterValue() 取得一個 String array, array elements 代表所有選項的值。例如 :

String [] params = request.getParameterValue("checkList");

3) getParameterNames() :

如果想知道每一次請求有多少個參數名稱,則可以使用 getParameterNames(), 這會回傳一個 Enumeration 物件,當中包含全部請求參數名稱。例如:

Enumeration  params = request.getParameterNames();
while(param.hasNextElement())
{
   System.out.println("Request Parameter = "+ params.nextElement);
}

4) getParameterMap()

將請求參數以 Map 的形式回傳, Map 中的 Key 是請求參數名稱 Values 是請求參數值,Values 是 String array 的方式回傳因為請求參數值有肯能有多個值。例如:
// get request parameter map
Map  requestParams = request.getParameterMap();

// retrieve parameter name - values pair from parameter map
StringBuilder sb = new StringBuilder();
for (Map.Entry entry : requestParams.entrySet()) 
{
    String key = entry.getKey();         // parameter name
    String[] value = entry.getValue();   // parameter values as array of String
    .....
}

5) getHeader()

如果想獲取 HTTP 的標頭資訊,則用 getHeader() 這回傳一個 String 物件。例如 :

Sting headers - request.getHeader()

6)  getHeaders()

使用方法和 getParameterNames() 一樣

接下來有個範例顯示如何取得 HTTP 標頭資訊 :


package com.learn.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Header
 */
@WebServlet("/header.view")
public class HeaderServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HeaderServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

 /**
  * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  */
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  // TODO Auto-generated method stub
  PrintWriter out = response.getWriter();
  out.println("");
  out.println("");
  out.println("HeaderDemo");
  out.println("
");
  out.println("");
  out.println("HeaderServlet at "+ request.getContextPath()+"
");  // Application environment path
  Enumeration  e = request.getHeaderNames();     //Get all header names
  
  while(e.hasMoreElements())
  {
      String name = e.nextElement();
      out.println(name +" = "+ request.getHeader(name)+"
");
  }
  
  out.println("");
  out.println("");
  out.close();
  
 }

 /**
  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  */
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  // TODO Auto-generated method stub
 }

}


顯示結果如下:


參考資料
  1. Servlet&JSP 教學手冊

2015年1月17日 星期六

使用@WebServlet

使用@WebServlet

       在開始使用@WebServlet之前有個先決條件,那就是要有一個Servlet程式。如果沒有的朋友請到『第一個Servlet程式』這裡有範例程式提供參考。準備好Servlet,接下來就要告訴Web Container這個Servlet的一些資訊。在這當中有兩種方法:
  1. 使用web.xml定義 
  2. 使用@WebServlet (Servlet 3.0以上才支援)

使用web.xml
要使用web.xml需要在Web應用程式中的WEB-INF目錄建立一個web.xml檔案定義Servlet的資訊,相關內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 <servlet>
  <servlet-name>HelloServlet</servlet-name>
  <servlet-class>com.learn.servlet.HelloServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>HelloServlet</servlet-name>
  <url-pattern>/helloUser.view</url-pattern>
 </servlet-mapping>
</web-app>

這樣的檔案稱為部署描述檔(Deployment Descriptor)。使用web.xml定義會比較麻煩,但web.xml中的設定會覆蓋Servlet中的Annotation設定(也就是第二種方法)。那現在透過這個web.xml是如何定義Servlet的資訊。舉例,若有client發出/helloUser.view的請求,那將會由HelloServlet這個Servlet處理,這分別是由<servlet-mapping>中的<url-pattern><servlet-name>定義。

使用@WebServlet
在 Servlet 3.0 中,已經可以使用 Annotation 告知容器哪些 Servlet 會提供服務。例如在一個 Servlet 中:

@WebServlet("/hello.view")
public class HelloServlet extends HttpServlet {
......
}

只要 Servlet 有設定 @WebServlet 屬性,容器就能自動讀取當中的資訊。以上面的例子為例,@WebServlet 告訴容器,如果URL是 /hello.view , 就由 HelloServlet 的實例提供服務。

參考資料
  1. Servlet&JSP 教學手冊

2015年1月1日 星期四

第一個Servlet程式

第一個 Servlet 程式

所謂工欲善其事,必先利其器。所以開始寫我們的第一支Servlet程式之前必須先準備好開發環境。

開發環境設定
1) 下載 Apache Tomcat (因為是用Servlet 3.0以上,所以Tomcat需要7.x 以上才能支援。)
3) 執行eclipse然後選擇 Windows -> Preferences -> Server ->  Runtime Environment。
4) 在Server Runtime Environments 選擇 Add -> Apache Tomcat  v7.0。然後在Tomcat installation       directory中選擇Tomcat的安裝目錄,最後按下Finish這就完成設定如下圖。


設定完成後就開始我們的第一支Servlet程式吧。

第一個Servlet程式
1) 在選單選擇 File->New->Dynamic Web Project.
2) 在Dynamic Web Project 當中的Target Runtime選擇剛才所新建的Server,Dynamic web 
     module version 選擇 3.0如下圖


3) 展開專案中的 Java Resources -> src 新增一個Servlet

接著可以開始寫第一支Servlet程式的內容了,在新增的Servlet加入一下的內容吧。

package com.learn.servlet;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class HelloServlet
 */
@WebServlet("/hello.view")
public class HelloServlet extends HttpServlet {  //繼承 HttpServlet
 private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelloServlet() {
        super();
    }

 /**
  * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  */
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  response.setContentType("text/html;charset=UTF-8");
  PrintWriter out = response.getWriter();
  String name = request.getParameter("name");
  
  out.println("");
  out.println("");
  out.println("Hellow Servlet");
  out.println("");
  out.println("");
  out.println("

Hello! "+ name +" !

"); out.println(""); out.println(""); out.close(); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

在以上的範例程式可以看到繼承了 HttpServlet ,然後重新定義 doGet()方法。當瀏覽器發出GET請求時,會呼叫該方法。

在doGet()可以看到兩個參數分別是HttpServletResponse 和 HttpServletRequest。當Web Container 收到HTTP請求後,將會分別建立Request和Response的Java物件,而後在呼叫doGet()時將這兩個物件當成參數傳入。如果需要取得GET或POST請求的參數值,那將透過HttpServletRequestgetParameter()指定參數名稱即可。HttpServletResponse 是response物件,我們可以透過setContentType()設定回傳類型,然後再使用getWriter()取得PrintWriter物件在藉由PrintWriter物件中的println()將HTML回傳給瀏覽器。

執行Servlet
  1. 在『HelloServlet.java』右鍵 Run As -> Run on Server
  2. Tomcat 啟動成功後,你將會看到以下的畫面(恭喜!你的第一個Servlet程式完成了)

                     瀏覽器的網址設定是 http://localhost:8080/FirstServlet/hello.view?name=Eric.

Tomcat預設的port是8080,注意網址的路徑FirstServlet是專案的名稱,為什麼請求的URL是/hello.view呢?請注意看以上的範例程式中有以下一行:

@WebServlet("/hello.view")

這表示,如果請求的URL是/hello.view,就會由HelloServlet處理請求。

參考資料
  1. Servlet&JSP 教學手冊


2014年10月30日 星期四

EJB - Bean Types

EJB - Bean Types

根據上一篇EJB-簡介所提到,EJB根據beans的功用分成三大類分別是session beans, message-driven beansentities

Session Beans
Session bean是為了執行特定商業操作而被client調用,如檢查客戶信用historySession這個名字意味著bean實例存在時間是“每個工作單位”和當伺服器shutdowncrash的時候就會消失。Session bean可以將任何應用程式邏輯模組化。Session bean有兩類分別為: statefulstateless
           Stateful session bean當客戶調用的時候在不需要寫任何多餘的程式碼的狀況下可以自動儲存bean的狀態。比較典型的例子就是網頁商城裡的購物車系統。相反,stateless session bean 不會維護任何狀態和模組應用程式服務。我們可以實作商業流程如信用卡付費或檢查查客戶信用記錄而建立stateless session bean.
           一個session beans不管在本地或遠端都可以透過Java RMI被調用。一個stateless session bean可以公開為網頁服務。

Message-driven Beans
MDBs 就像session beans,都是處理商業邏輯。但MDBs最大的不同是clients永遠不會直接調用MDB method。相反MDBs是透過訊息驅動然後傳給messaging server, 就是在系統元件之間啟動傳送非同步訊息。Messaging servers的典型例子有IBM WebSphere MQSonicMQ Oracle Advance Queueing, TIBCOMDBs通常是使用在系統整合或非同步處理的健全性。上。Messaging的一個例子,從自動零售系統傳送庫存補貨的需求到供應鏈管理系統。

Entities and the Java Persistence API
EJB 3當中其中一個新特色就是處理persistence的方法。之前我們概略的提到persistence 提供者和JPA,現在讓我們更深入到細節。 
         Persistence的能力是將Java objects中包含的data自動儲存到關聯式資料庫像Oracle, SQL Server, DB2Persistence 在 EJB 3是透過JPA管理。它自動的使用Object-relational mapping(ORM)這項技術persists Java objectsORM的本質是透過設定檔在java objects處理mapping data然後儲存到資料表中。它緩解我們寫底層,複雜的JDBC程式碼persist objects到資料庫的工作。
           EJB 3中,persistence provider基本上就是Java Persistence API (JPA)所支援的ORM框架。JPA定義了一些標準:
  •  ORM設定metadata的建立mapping entities relational tables.
  •  EntityManager API – 是一個標準的APIentities執行CRUD persistence operations.
  •  Java Persistence Query Language (JPQL),是用來搜尋和獲取persisted application data.
自從為了Java平台JPA ORM frameworks標準化,我們可以在應用程式plug in ORM 產品如 JBOSS Hibernate,OracleTopLink,或BEA Kodo 做為JPApersistence provider”的底層。

Entities
如果在我們的應用程式採用JPA建立persistence logic,那就必須使用entities. EntitiesJava objects用來persisted到資料庫。就像session beansprocess模組化,entities將低階應用概念包裝成高階商業流程管理。

The EntityManager
JPA EntityManager介面管理entities和提供persistence 服務。Entities會告訴JPA provider如何map資料庫。EntityManager 介面讀取ORM metadataentity和執行persistence. EntityManager知道如何對entities在資料庫中執行CRUDCREATE, RETRIEVE, UPDATE, DELETE)。另外JPA 提供處理lifecycle managementperformance tuningcachingtransaction management的能力。

Java Persistence Query Language
JPA 有提供一個類似SQL的語言稱為Java Persistence Query Language (JPQL) 可以搜尋儲存在資料庫中的entities. 在一個健全和彈性的APIJPQL,我們在選擇自動persistence而不是手寫JDBC是不會遺失任何東西。另外,JPA支援native database-specific SQL, 在一些罕有的案件是這是值得使用。
         在這時候,我們應該對EJB各個部分都有部分的認識。我們也知道需要透過EJB container去執行session beansMDBs persistence provider執行entities,那這些元件都能存取EJB 3所提供的服務。

Reference:

1)EJB 3 in action

2014年10月16日 星期四

EJB - 簡介

EJB – 簡介
         EJB 的全名是Enterprise JavaBeans,簡單來說它是一個平台讓開發人員使用Java語言開發一個portable, reusable 和 scalable 的商業應用程式。自EJB推出的時候就一直宣導它是一個元件模組或框架且可以讓我們在開發商業應用程式時不需要重新開發一些服務例如:transactions, security, automated persistence 等等。EJB允許開發人員在開發應用程式時專注在商業邏輯不需要花費時間在建立基礎架構的程式碼。
        在開發人員的觀點來看,EJB只是一段的Java程式碼執行在一個特別的運行環境稱為 EJB container, 且提供大量的component services.

EJB as a Component
        在這每當提到EJBs時,指的是伺服端components可以用它來構建應用程序的某些部分例如:商業邏輯,persistence code. 很多人往往對 components這個詞聯想到開發一個複雜和重量級的CORBA, Microsoft COM+ 程式碼。但在EJB3.0這個嶄新的世界,component 它只是一個不外乎多了一些特別功能的POJO。更重要的是,這些功能在不需要的時候都是“隱形”,不要分散component真正用途上的注意力。
        Component 背後真正的想法是有效率的封裝應用程式的行為。Component的使用者不需要了解內部如何運作。他們只需要知道傳入什麼和回傳什麼。EJB components 有三種:session beans, message-driven beansentities. Session beansmessage-driven beans 是在EJB應用程式實作商業邏輯,而entities則使用在persistence.
        Component 是可以重複使用。假設現在公司開發一個賣書的網站,設計了一個用信用卡過賬的模組只是簡單的Java物件。然後另一組人又在不同的開發環境當中開發了賣CD的網站,這時候因為開發環境的不同所以不能直接套用之前信用卡的模組,另一組人需要將你整個模組複製到他們的網站才能使用,因為沒有更容易的方法可以存取之前的模組。如果是使用EJB components建立的信用卡模組,這會讓新使用者更簡單的重複使用該模組而不需要知道其內部運作(Figure 1)。

Figure 1


EJB as a Framework
        EJB components 是在container中。Componentscontainer可以看成對商業應用程式開發提供有價值服務的框架。
        雖然很多人認為使用EJB開發中等的網頁應用程式有點大材小用。但從頭開發一個商業應用程式是不實際的。大多數的伺服端應用程式有很多是普遍的 ,就像管理應用程式狀態 ,資料庫提取或儲存資料,安全性,非同步進程,整合系統等等。
        作為一個框架,EJB container提供了這些普遍的功能,那EJB components 可以直接使用這些功能到自己的應用程式也不需要重新開發這類功能。這些服務,當EJB components 部署在EJB container的時候就能使用,就像Figure 2. 這代表開發一個高品質,豐富功能的應用程式比你所想的還要快。


Figure 2

        Container使用了一些優雅的新方法提供服務給EJB componentsmetadata annotations 是當container部署EJBs用來預設EJBs 服務的類別。在Java 5中有介紹metadata annotations是設定一段程式碼的設定,如某些class需要特定屬性。這是程式語言的宣告方式讓開發者註明需要完成什麼然後系統將程式碼加上。
        EJB meta annotations 大大的簡化了應用程式的開發和測試,不需要額外的xml 設定檔案. 這允許當開發者需要的時可宣告式的增加愛服務到EJB components就像Figure
3 描繪,annotations 將一個簡單的POJO轉換成 EJB


Figure 3
Layered architectures and EJB
        大多數的企業應用程式包含大量的components.企業應用程式是為了解決客戶特定問題所設計,但它們共享很多common 特色。舉例來說,多數企業應用程式有些UI界面,商業模式,將資料儲存到資料庫特性。因為這些共同特性,在構建企業應用程式可以跟隨常見架構或設計原則稱為 “patterns”.
        對於伺服端開發,較好patternlayered architectures. layered architecture components被劃分在tiers應用程式的每一個tier都有很好定義。EJB在建立應用程式允許採用兩種不同的layered architecture分別是:traditional four-tier architecture domain-drive design (DDD).

Traditional four-tier layered architecture
Figure 4 顯示traditional four-tier layered architecture.這個架構非常直覺也非常普及。在這架構presentation layer是負責GUI和處理user input, 然後將每個得到的request傳給business logic layer. Business logic layer是應用程式的核心而且包含工作流程和processing的邏輯。Business logic layer透過persistence tier 從資料庫獲取或儲存資料。Persistence layer database layer之上提供高階的抽象的OODatabase layer 就是DBMS


Figure 4

EJB 明顯不是presentation layer. EJB完全支援在實作商業邏輯和persistence layer. Figure 5 顯示 EJB如何透過它的服務支援這些layers.在一開始有提到bean的種類session beans message-driven beans是用在business logic tier, entities實在persistence layer.

Figure 5
        Traditional four-tier architecture 是不完美的。其中一個常見的批評就是破壞了OO模組化商業領域為物件且封裝資料和行為的理想。因為traditional architecture 專注在business process的模組化而不是領域。而且persistence layer也比較像簡單的資料處理元件,像資料庫資料的定義而不是OO世界的第一級公民。

Domain-driven design
Domain-driven design (DDD )重點放在領域的物件應該包含商業邏輯和不應該只是複製資料庫的資料。Domain objects EJB3 也稱為entities。在DDD中,一個貿易應用程式的CatalogCustomer物件是entities的典型例子,它們應該包含商業邏輯。

        然而,就算EJB發布的時它的價值已經非常清楚,但還是很困難的實作DDD。在EJB 2 實作 domain model是不可能的,因為beans不是 POJOs 且沒有支援多數的OO特色,如:inheritance polymorphism。有個好消息是EJB 3 已經可以讓我們簡單的跟隨好的OO設計或DDD。在EJB 3 Java Persistence API (JPA)定義的entities 支援OO。我們可以簡單的實作persistence object,最重要的是可以簡單的增加商業邏輯在entities上,那在透過EJB 3實作一個rich domain 是在簡單不過的任務。


Reference:
1)EJB 3 in action

2014年8月27日 星期三

CCNA Security Chapter 6 筆記

CCNA Security Chapter 6 筆記

Endpoint Security

The high-profile threats most often discussed in the media are external threats, such as Internet worms and DoS attacks. But securing an internal local area network (LAN) is just as important as securing the perimeter of a network. Without a secure LAN, users in an organization may not be able to access the network, which can significantly reduce productivity.

Operating systems provide basic security services to applications:
  • Trusted code and trusted path - Ensures that the integrity of the operating system is not violated. Trusted code refers to the assurance that the operating system code is not compromised. An operating system might provide integrity checking of all running code by using hash message authentication codes (HMACs) or digital signatures. Integrity verification of add-on software might be necessary at installation. Digital signatures can also be used. Trusted path refers to a facility that ensures that the user is using a genuine system and not a Trojan Horse. 
  • Privileged context of execution - Provides identity authentication and certain privileges based on the identity.
  • Process memory protection and isolation - Provides separation from other users and their data.
  • Access control to resources - Ensures confidentiality and integrity of data.
These are a few techniques that help protect an endpoint from operating system vulnerabilities:
  • Least privilege concept - To better protect an endpoint, a process should never be given more privilege than is necessary to perform a job.
  • Isolation between processes - Isolation between processes can be virtual or physical. For example, memory protection can be done in hardware. Some trusted operating systems provide isolation using logical execution compartments.
  • Reference monitor - A reference monitor is an access control concept that refers to a mechanism or process that mediates all access to objects. It provides a central point for all policy decisions, typically implementing auditing functions to keep track of access. 
  • Small, verifiable pieces of code - For all security functionality, it is desirable to have small, easily verifiable pieces of code that are managed and monitored by a reference monitor. 
Layer 2 Security
Network security professionals must mitigate attacks within the Layer 2 infrastructure. These attacks include MAC address spoofing, STP manipulation, MAC address table overflows, LAN storms, and VLAN attacks.

The first step in mitigating attacks such as these is to understand the underlying threats posed by the Layer 2 infrastructure. Layer 2 can be a very weak link to the higher OSI Layers because if Layer 2 is compromised, hackers can work their way up. It is important for the network security professional to remember that Layer 2 attacks typically require internal access, either from an employee or visitor

From a security perspective, Layer 2 independence creates a challenge because when the layer is compromised, other layers are not aware of that fact, leaving them open to being compromised. Network security is only as strong as the weakest link, and that link is often the Data Link Layer.

To help prevent Layer 2 exploitations, an application must carefully validate user input. The input might contain improperly formatted data, control sequences, or too much data, such as with buffer overflows. Remember, buffer overflow exploits try to overwrite memory on an application. 

MAC Address Spoofing Attacks
Unlike hubs, switches regulate the flow of data between ports by creating instant networks that contain only the two endpoint devices communicating with each other at that moment in time. Switches accomplish this by forwarding data out specific ports based on the MAC address. Switches maintain MAC address tables, also known as content-addressable memory (CAM) lookup tables, to track the source MAC addresses associated with each switch port. These lookup tables are populated by an address-learning process on the switch. 

MAC spoofing attacks occur when an attacker alters the MAC address of their host to match another known MAC address of a target host. The attacking host then sends a frame throughout the network with the newly configured MAC address. When the switch receives the frame, it examines the source MAC address. The switch overwrites the current MAC address table entry and assigns the MAC address to the new port. It then inadvertently forwards frames destined for the target host to the attacking host.

When the switch changes the MAC address table, the target host does not receive any traffic until it sends traffic. When the target host sends traffic, the switch receives and examines the frame, resulting in the MAC address table being rewritten once more, realigning the MAC address to the original port.


MAC Address Flood Attacks
The most common way of implementing a MAC address table overflow attack is using the macof tool. This tool floods a switch with frames containing randomly generated source and destination MAC and IP addresses. Over a short period of time, the MAC address table fills up. When the MAC address table is full of invalid source MAC addresses, the switch begins to flood all frames that it receives. As long as macof is left running, the table on the switch remains full, and the switch continues to flood all received frames out of every port.


STP Manipulation Attacks
Another vulnerability of Layer 2 devices is the Spanning Tree Protocol (STP). STP is a Layer 2 protocol that ensures a loop-free topology. STP operates by electing a root bridge and building a tree topology from that root. STP allows for redundancy, but at the same time, ensures that only one link is operational at a time and no loops are present.

To conduct an STP manipulation attack, the attacking host broadcasts STP configuration and topology change BPDUs to force spanning-tree recalculations. The BPDUs sent by the attacking host announce a lower bridge priority in an attempt to be elected as the root bridge. If successful, the attacking host becomes the root bridge and sees a variety of frames that otherwise are not accessible.



LAN Storm Attacks
A LAN storm occurs when packets flood the LAN, creating excessive traffic and degrading network performance. Errors in the protocol stack implementation, mistakes in network configurations, or users issuing a DoS attack can cause a storm. Broadcast storms can also occur on networks. Remember that switches always forward broadcasts out all ports. Some necessary protocols, such as ARP and DHCP, use broadcasts; therefore, switches must be able to forward broadcast traffic.

While it is not possible to prevent all types of packet storms and excessive broadcasts, it is possible to suppress them using storm control. Storm control prevents traffic on a LAN from being disrupted by a broadcast, multicast, or unicast storm on one of the physical interfaces. Storm control (or traffic suppression) monitors packets passing from an interface to the switching bus and determines if the packet is unicast, multicast, or broadcast. The switch counts the number of packets of a specified type received within a certain time interval and compares the measurement with a predefined suppression-level threshold. Storm control then blocks traffic when the rising threshold is reached.


VLAN Attacks
There are a number of different types of VLAN attacks prevalent in modern switched networks. Rather than list all the types of attacks, it is important to understand the general methodology behind these attacks and the primary approaches to mitigate them.

In a basic VLAN hopping attack, the attacker takes advantage of the default automatic trunking configuration on most switches. The network attacker configures a system to spoof itself as a switch. This spoofing requires that the network attacker be capable of emulating either ISL or 802.1Q signaling along with Cisco-proprietary Dynamic Trunking Protocol (DTP) signaling. By tricking a switch into thinking it is another switch that needs to trunk, an attacker can gain access to all the VLANs allowed on the trunk port. This attack requires a configuration on the port that supports trunking with auto or dynamic mode to succeed. As a result, the attacker is a member of all the VLANS that are trunked on the switch and can hop, that is, send and receive traffic on all the VLANs.

A VLAN hopping attack can be launched in one of two ways:

  • Spoofing DTP messages from the attacking host to cause the switch to enter trunking mode. From here, the attacker can send traffic tagged with the target VLAN, and the switch then delivers the packets to the destination.
  • Introducing a rogue switch and enabling trunking. The attacker can then access all the VLANs on the victim switch from the rogue switch.


The best way to prevent a basic VLAN hopping attack is to turn off trunking on all ports, except the ones that specifically require trunking. On the required trunking ports, disable DTP (auto trunking) negotiations and manually enable trunking.