Bước đầu đối với ai cũng thật sự tệ, và tôi cũng không ngoại lệ. Đầu tiên cũng như bao lần học những công nghệ khác, tôi vào Google. Kết quả: tôi tìm ra một tài liệu Security for JavaSE6. Tôi mày mò trong mục tutorial, tìm cách run. Kết quả: Thất bại, vì lý do tôi không biết cách run. Trước giờ tôi chỉ sài eclipse, chạy command line đối với tôi thật khó khăn, và cũng vì ngày sưa tôi quá coi thường nó (thời nay ai mà còn dùng command line). Tài liệu thứ 2 mà tôi tìm thây là bài JAAS Security in Action trên devx.com. Cũng chỉ nói về hệ tư tửng, những định nghĩ, vv... Mà không chạy được làm sao mà hiểu được định nghĩa. Và tất nhiên kết quả không gì khác ngoài: THẤT BẠI. Tôi bắt đầu mày mò một số bài viết tiếng Việt, và dĩ nhiên là trên javavietnam.org. Qua đó tôi được biết có một bài viết của bác Thắng trên tincntt.com. Mừng hết lớn, đọc lấy đọc để... Kết quá cũng thất bại, vì đơn giản đó chỉ là một bài dịch trên DevArticles, chẳng có một ứng dụng, và còn tệ hơn khi tác giả chẳng mảy may chú ý đến sự tiếp thu của người đọc. Lên nguồn tiếng anh thì thấy họ viết còn dễ hiểu hơn, có lẽ đó cũng là lý do người ta nói: các bài viết tiếng Việt thường “chuối”. (Có gì không phải vui lòng bỏ qua cho)
Kỳ 2: MỘT CHÚT KHẢ QUAN
Đúng là cái gì cũng phải kiên nhẫn, và cuối cùng cũng được kết qủa như mong muốn. Quyển đầu tiên đã giúp tôi thu nhập được nhiều thứ nhất chính là JAAS in action. Giới thiệu một cách khái quát về jaas, từ căn bản, đến những webapp dùng jaas. Những web application mà cuốn sách này tôi vẫn chưa chạy được, nhưng cũng giúp tôi bước đầu trên con đường chinh phục JAAS. Để chạy được các ví dụ trong quyển sách này máy bạn cần có eclipse, và bạn cũng nên học một chút về ant trên eclipse. Tôi lại tiếp tục trên con đường tiềm kiếm một app hoàn chỉnh, và đã thấy trên JEE5 tutorial, và tôi đã run được ứng dụng web đầu tiên.
Kỳ 3: KẾT QUẢ ĐẠT ĐƯỢC
Trên con đường đi tìm, tôi đã gặp và nằm lòng những khái niệm User: Người dùng, và trong jaas nó không được biểu diễn bằng một Object Subject: là một thực thể đại diện cho user trên ứng dụng. Principal: Đại diện cho một (Administrator) hoặc nhiều (Group manager) Subject. Resource: Tất cả mọi thứ trong hệ thống của chúng ta. Permission: Quản lý Resource, Một permission class đại diện cho 3 thứ: resource, action và name. Nó có thể được gán cho một Principal. Authentication: Hành động kiểm tra một user, gán cho subject của user này một principal; bạn là ai Authorization: Hành động kiểm tra một user, và cấp phép truy cập resource; bạn có thể làm gì. Authentication module: Phương thức xác nhận user. Authentication scheme: Bao gồm nhiều Authentication module.
Kỳ 4: CẤU HÌNH SUN APPLICATION SERVER
Để Application Server xác định quyền users, ta làm theo các bước sau 1.Start server 2.Vào admin console( mặc định là http://localhost:4848/asadmin) 3.Gõi username và password (thường là admin và adminadmin) 4.Mở cây bên trái chọn Configuration\ Security\ Realms\. Ta có thể có 3 lựa chọn: file: tạo user cho phép truy cập vô ứng dụng admin-realm: tạo user cho phép tác động vào server admin certificate 5.Chọn manage users, ở đó bạn có thể thêm, xoá, và sửa thông tin user. 6.OK 7.Logout
Kỳ 5: EJB+JAAS HelloWorld APPLICATION
Bạn nên dùng Netbeans 5.5.1 + Sun Application Server 9 Bước 1: Tạo một Enterprise Application Proejct name: HelloWorld Bỏ check Create Web application module Check vào mục create application client module Sửa tên main class thành com.bds.test.Client Bước 2: Tạo session Bean EJB Name: HelloWorld Package: com.bds.ejb Check remote, bỏ check local
HelloWorldBean.java @DeclareRoles("admin") @Stateless public class WorldHelloBean implements WorldHelloRemote { /** Creates a new instance of WorldHelloBean */ public WorldHelloBean() { } @RolesAllowed("admin") public void sayHello(String name) { System.out.println("Hello "+name); } }
HelloWorldRemote.java @Remote public interface WorldHelloRemote { void sayHello(String name); }
Bước 3: Test Ta chỉ cần remote đến WorldHelloBean để dùng:
/** Creates a new instance of Client */ public Client(String[] args) { } /** * @param args the command line arguments */ public static void main(String[] args) { Client c = new Client(args); c.doTest(); // TODO code application logic here } public void doTest(){ worldHelloBean.sayHello("Hien"); } }
Bước 4: Khai báo <security-role-mapping> Trong helloworld project: sửa file sun-application.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sun-application PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Java EE Application 5.0//EN" "http://www.sun.com/software/appserver/dtds/sun-application_5_0-0.dtd"> <sun-application> <security-role-mapping> <role-name>admin</role-name> <group-name>admin</group-name> </security-role-mapping> </sun-application>
Bước 5: Run Để chạy được project này bạn cần có một user có ID:admin, password: admin, group: admin. Sau đó ta chỉ run project helloworld
Kỳ 6: JAAS-WEB APPLICATION Writing... TÀI LIỆU THAM KHẢO http://java.sun.com/products/jaas/overview.html http://www.mooreds.com/jaas.html http://www.tincntt.com/tincntt/cms/vi/tutorials/java_tutorials/jaas_1.html http://java.sun.com/javaee/5/docs/tutorial/doc/Overview9.html
Ta đã có đủ lập trình viên cho một dự án và muốn tăng tốc nó, lúc đó dĩ nhiên là phải tìm thành viên mới cho nhóm, và thường thì không phải vậy (project nhanh hơn). Trong một khoảng thời gian dài để tìm ra một cách thích hợp - tự mình trainning và cùng làm việc – nhưng cũng không khá hơn được. Tốt hơn hết là hãy ngồi cạnh bên newbies và dùng tất cả khoảng thời gian quý giá của mình để trainning. OK... cứ cho là vậy, nhưng sẽ ra sao nếu ta không phải cần 1 mà cần hơn thế? Trainning tiếp ư? Các bạn thân mến, hãy viết cho project mình một “Cookbook”, nó sẽ giúp bạn tiết kiệm thời gian.
Tôi là một thành viên phát triển cho một project bao gồm nhiều java applications cùng dùng một database là Oracle. OK… mọi công ty đều thế cả, nhưng đều có một điểm chung khi có thêm một thành viên mới, và dĩ nhiên là anh ta cần người giúp để có thể làm việc. Mọi người đều có một nhiệm vụ cho mình và dĩ nhiên là họ cũng không còn thời gian để làm chuyện đó. Anh ta sẽ không thể theo kịp, và project sẽ có sự xáo trộn!!!
Những điều mà cookbook cần có: 1. Nội dung phải là tutorial hay hướng dẫn sử dụng, hoặc cả hai. 2. Cung cấp những thông tin cần thiết cho newbie để họ có thể tự làm 3. Bao gồm đầy đủ code 4. Miêu tả ngắn về nội dung cần làm 5. Và nhất là phải có code ví dụ (dịch từ http://blog.technocog.com/?p=10)
Thường thì bạn giải quyết sao khi gặp một vấn đề? Với tôi thật đơn giản (và có một điếu mà ai cũng biết: tui là dân IT) :
1.Google. Trong bước này bạn rất hay bỏ sót một số từ khoá quan trọng, vì vậy bạn cần hết sức kiên nhẫn.
2.Nhờ vả. Thường thì bạn làm việc trong cùng công ty, sau đó là bạn học, và cuối cùng là bạn quen bên ngoài. Nói chung mối quan hệ giúp ta rất nhiều vấn đề.
3.Tự tìm cách giải quyết. Thật sự tệ hại khi phải làm bước này, và tốt nhất là đừng quá thường xuyên nhé.
4.Viết cách giải quyết vấn đề này lên blog. Tôi thường làm điều này với một niềm vui nho nhỏ, khoe với bạn bè, hay hơn nữa là với nhà tuyển dụng.
Tóm tắt Viết một Unit tests thật ko dễ dàng. Phần lớn thời gian ta dùng là test code kết nối database, với server, hoặc với những modules khác(chưa được viết xong). Với một số lượng lớn điều kiện như vậy thì ko dể gì hiện thực một môi trường test. Việc cài đặt những điều kiện test làm ta mất đi một số lượng lớn thời gian và tiền bạc, và có lẽ những lợi thế của test ko còn như ta mong muốn. Bài viết này dùng Mock Objects, một kỹ thuật test từ cộng đồng XP, khuyến khích cô lập code bằng cách tạo những ràng buộc giả. Như những tool khác, ta cần phải cẩn trọng khi dùng, và ko nên lạm dụng.
Mock Objects Overview Những năm gần đây, những developer đã làm sống lại lợi thế của việc dùng test, đồng ý rằng việc tìm kiếm và gắn kết các thành phần là khó khăn. Và kết quả là Unit Testing trở thành một thành phần chính của software development, là một cách để tìm lỗi và đồng nhất yêu cầu. Thành phần chính của unit testing là test bằng cách cô lập các thành phần, và thường là class. Test cách ly là rất khó khăn, đặc biệt là khi nó giao tiếp với một phần khó, hoặc tạo nhanh một test. Khó khăn hơn là viết và maintain unit tests, và đó là lý do mà developers chán nản làm test. Họ đã miêu tả những khó khăn và đưa ra hướng giải quyết: Tạo những sự phụ thuộc phức tạp(ví dụ như một database) Kiểm tra những actions cần thiết để run code(ví dụ như một JDBC conection đã đóng sau khi dùng ) Tạo môi trường là rất khó khăn (lỗi thể hiện cảu câu SQL) Mặc dù hữu dụng, nhưng chắc chắn nó không thể làm được tất cả, việc lạm dụng chỉ làm cho chất lượng của project giảm xuống. Nhược điểm của Mocks Hãy nhìn vào những điều cần biết khi dùng. Mocks ẩn chứa nhiều vấn đề Figure 1. Lưu thông tin của một employee vào database Class EmployeeBO cung cấp những business services cho Employees và dùng EmployeeDAO để lưu dữ liệu vào CSDL quan hệ dùng JDBC. Test EmployeeBO cần có bước cài đặt database và cung cấp nó cho việc test. Đề nghị của mock objects là bạn có thể lưu bằng cách giả lặp một EmployeeDAO, và không cần tạo một database. Mocks giúp cho việc tạo và run nhanh hơn, nhưng chúng ko cho ta sự tin cậy vào hệ thống, như một cách làm phù hợp. Mock testing có thể có bugs hay sai sót trong các thành phần được giả định. Để tìm một sai xót, thì chúng ta cần phải có một bài test tổng thể. Trong ví dụ trên, hệ thống cần test dùng database để lưu thông tin employee. Mock testing hạn chế khi kiểm tra sự chính sác của tương tác giữa EmployeeBO và EmployeeDAO—vì vậy, EmployeeBO chỉ gọi một vài phương thức từ EmployeeDAO trong cùng thời gian. Chỉ có test tổng thể mới có thể giúp ta tìm vấn đề, nhưng lỗi trong JDBC driver hay trong chính bản thân database, cái này chỉ xuất hiện khi application trở thành sản phẩm. Mocks add clutter and duplication to test code Đoạn code sau dùng EasyMock để test EmployeeBO dùng EmployeeDAO để lưu thông tin một employees mới và update thông tin một employee đã tồn tại. @Before public void setUp() { mockEmployeeDAO = createMock(EmployeeDAO.class); employeeBO = new EmployeeBO(mockEmployeeDAO); employee = new Employee("Alex", "CA", "US"); }
@Test public void shouldAddNewEmployee() { mockEmployeeDAO.insert(employee); replay(mockEmployeeDAO); employeeBO.addNewEmployee(employee); verify(mockEmployeeDAO); }
@Test public void shouldUpdateEmployee() { mockEmployeeDAO.update(employee); replay(mockEmployeeDAO); employeeBO.updateEmployee(employee); verify(mockEmployeeDAO); } Phương thức shouldAddNewEmployee kiểm tra sự ảnh hưởng giữa một đối tượng đại diện cho (employeeBO) và một đối tượng đại diện cho (mockEmployeeDAO). Mong chờ employeeBO gọi phương thức insert trong mockEmployeeDAO, qua một thể hiện của Employee nhận được. Qua một vì dụ đơn giản, phương thức shouldAddNewEmployee đã không như ta mong muốn, thêm lôn sộn cho bài test: A gọi replay để báo cho EasyMock rằng tất cả yêu cầu đã thi hành A gọi verify để báo cho EasyMock đã kiểm tra Cách dùng mocks thường theo pattern: 1.Cài mock(s) và dự tính 2.Chạy test 3.Xác nhận dự tính đã thi hành Như một đã nói duplication in test code, đã hiển thị rỏ trong phương thức shouldAddNewEmployee() và shouldUpdateEmployee(). Class sau , EasyMockTemplate, có thể giúp giảm bớt code clutter and duplication: /** * Understands a template for usage of EasyMock mocks. * @author Alex Ruiz */ public abstract class EasyMockTemplate {
/** Mock objects managed by this template */ private final List
Dùng bộ lọc request cho tất cả các trang jsp và servlet. ============================== CharacterEncodingFilter.java ============================== public class CharacterEncodingFilter implements Filter { private FilterConfig fc;
/** Creates a new instance of CharacterEncodingFilter */ public CharacterEncodingFilter() { }
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; response.setContentType("text/html; charset=UTF-8"); request.setCharacterEncoding("UTF8"); chain.doFilter(request, response); //do it again, since JSPs will set it to the default response.setContentType("text/html; charset=UTF-8"); request.setCharacterEncoding("UTF8"); }
public void destroy() { this.fc = null; }
}
============================== web.xml sau đó sẽ khai báo dùng trong các form cần, tôi khai báo dùng cho /servlet/ ============================== ... <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/servlet/*</url-pattern> </filter-mapping> ...
Đây là vấn đề của khá nhiều bạn, và cách giải quyết sau đây của tôi hi vọng sẽ giúp được bạn. Dùng SessionListener 1.Tạo một sessionListener như sau: public class SessionListener implements HttpSessionListener {
/** Creates a new instance of SessionListener */ public SessionListener() { }
public void sessionDestroyed(HttpSessionEvent se) { HttpSession session = se.getSession(); System.out.println("Destroyed. Session id"+ session.getId()); // do you stuff here } }
2.Và ta sẽ khai báo Listener: <listener> <listener-class>com.bds.psolution.SessionListener</listener-class> </listener>