Làm chủ Grails: Grails và Web di động M là WWW mới Scott Davis Tổng Biên tập AboutGroovy.com 15 01 2010 Hiện nay, trên thế giới có khoảng 3,3 tỷ người sử dụng điện thoại di động và con số này vẫn đang tăng lên. Trong khi đó, việc truy cập Internet qua điện thoại di động cũng đang tăng lên nhanh chóng. Việc phát triển Web cho điện thoại di động đòi hỏi những yều cầu riêng biệt. Trong bài viết Làm chủ Grails này, Scott Davis sẽ giới thiệu với bạn về cách xây dựng những ứng dụng Grails thân thiện chạy trên điện thoại di động. Xem thêm bài trong loạt bài này Nhờ vào những công nghệ mới hiện nay, chúng ta có thể truy cập trang Web từ nhiều trình duyệt khác nhau. Những thư viện Ajax hiện đại như là Prototype, Dojo và YUI sẽ giúp giải quyết sự khác nhau giữa các trình duyệt Firefox, Internet Explorer và Safari. Nhưng những người truy cập trang Web của bạn từ một chiếc điện thoại di động Nokia, Motorola hay Apple có thể gặp rắc rối với những trình duyệt Web trên những thiết bị của họ. Ngay cả những trình duyệt di động mới nhất được trang bị tính năng "hỗ trợ HTML đầy đủ" cũng chỉ có thể hiển thị tốt một số nội dung Web đơn giản. Bài viết này sẽ hướng dẫn bạn tối ưu hóa ứng dụng Grails trên những trình duyệt di động. Sử dụng Web di động đang gia tăng Theo thống kê của Trung tâm số liệu quốc tế Internet World Stats, hiện có khoảng 1,4 tỷ người đang sử dụng Internet — chiếm khoảng 20 phần trăm dân số thế giới (xem Tài nguyên). Tại Bắc Mỹ, 3/4 dân số sử dụng Internet. Một nửa trong tổng số 6,6 tỷ người trên trái đất đang sử dụng điện thoại di động. Tại Bắc Mỹ, số người sử dụng điện thoại di động tương đương với số người sử dụng Internet. Tại Hong Kong, tốc độ tiêu thụ điện thoại tăng 140 phần trăm, trong khi đó, một số vùng ở Châu Âu ( như Lithuania, Italia, and Luxembourg) có tốc độ tăng trưởng tới 150 phần trăm. Đặc biệt, ở một số khu vực, lượng điện thoại di động còn nhiểu hơn dân số của khu vực đó. Colin Crawford, Phó Chủ tịch tập đoàn Dữ liệu truyền thông Quốc tế (IDG) nói rằng (xem Tài nguyên): "Trong vài năm tới, điện thoại di động sẽ thay thế máy tính cá nhân như là một thiết bị hàng đầu để truy cập internet. Hiện nay, đã có khoảng 30% người sử dụng Internet trên thế giới thường xuyên truy cập từ điện thoại di động — thậm chí ở một số nước như Nhật Bản — tỷ lệ này là 70%." © Copyright IBM Corporation 2010 Làm chủ Grails: Grails và Web di động Nhẫn hiệu đăng ký Trang 1 của 21 developerWorks® ibm.com/developerWorks/vn/ Nếu bạn đang băn khoăn tại sao bạn nên cải tiến trang Web của thân thiện hơn với di động, thì những con số trong phần Sử dụng Web Di động đang gia tăng có thể đã thuyết phục được bạn. Ý tưởng Web thân thiện di động của tôi ban đầu chỉ là sở thích cá nhân. Tôi đã mua một chiếc iPhone khi chúng ra mắt phiên bản đầu tiên vào mùa hè năm 2007. Kể từ đó, tôi thường truy cập những trang Web được hỗ trợ bởi thiết bị này. Tôi có thể truy cập bất cứ trang Web nào (trừ các trang Web có applet Flash hay Java™, vì iPhone không hỗ trợ). Vấn đề nữa là những nội dung có độ phân giải 800x600 (hay cao hơn) thường có chất lượng không tốt trên màn hình rộng 3,5 inch của iPhone. Những trang Web tôi thường truy cập từ chiếc iPhone chỉ đáp ứng một nửa yêu cầu của tôi về mặt UI do những ràng buộc đặc biệt của thiết bị này. Việc sử dụng m thay thế cho phương thức www truyền thống trong URL của các trang Web phổ biến là một giải pháp khá hiệu quả. Những trang như http://m.cnn.com, http://m.yahoo.com và http://m.google.com hiển thị khá tốt trên chiếc điện thoại di động của tôi. Một số trang Web, như http://www.twitter.com, có thế biến đổi khi hiển thị trên màn hình: khi tôi truy cập qua máy tính, tôi có thể xem được tất cả các đặc tính; khi tôi truy cập qua điện thoại di động, nội dung của trang web được thay đổi cho phù hợp với màn hình khiêm tốn của điện thoại đi động. Cùng một URL, nhưng UI đã được tối ưu hóa. Tôi sẽ hướng dẫn bạn cách tối ưu hóa trang web của bạn như những trang Web ở trên. Những công nghệ cho người phát triển Web di động Từ khi là một người phát triển Java, tôi đã biết được ý tưởng ý tưởng 'Write Once, Run Anywhere' (viết một lần, chạy trên mọi nền tảng hệ thống). Tuy nhiên, việc tối ưu hóa ứng dụng Java của tôi cho một hệ điều hành hay một mô hình phần cứng nhất định thậm chí còn chưa có trong ý nghĩ của tôi. Nhưng nếu bạn đang gặp khó khăn trong phát triển Web di động, bạn nên nắm vững ba công nghệ hàng đầu được hộ trợ bởi các thiết bị di động khác nhau: • Ngôn ngữ Đánh dấu Mạng không dây (WML) 1.x • WML 2.x hay Mobile Profile (XHTML-MP) • HTML được hỗ trợ trong iPhone Khi tôi hướng dẫn bạn, bạn có thể kết hợp ngôn ngữ đánh dấu WML và XHTML-MP vào trong Groovy Server Pages (GSPs) mà bạn xây dựng với Grails để tạo ra những trang Web thân thiện với di động. Và tôi cũng sẽ hướng dẫn bạn cách tối ưu hóa HTML được sinh ra bởi Grails để giúp các trang hoạt động tốt hơn trên iPhone. Sử dụng WML 1.x kết hợp với Grails WML là một ngôn ngữ đánh dấu kế thừa từ HTML, nhưng nó không phải là HTML. (WML 1.0 được giới thiệu vào năm 1998 và WML 1.3 là phiên bản mới nhất hiện nay.) Đáng chú ý là, bạn không thể xem WML trên một trình duyệt Web bình thường (trừ phi bạn dùng một bộ mô phỏng) và bạn cũng không thể xem HTML trên một trình duyệt WML. Do vậy, các nhà cung cấp điện thoại di động thường hỗ trợ cổng chuyển đổi HTML-thành-WML trong các sản phẩm điện thoại di động của họ. Về loạt bài viết này Grails là một khung làm việc phát trển Web hiện đại, nó là sự kết hợp của các công nghệ Java phổ biến như Spring và Hibernate với những kỹ thuật đương thời như quy ước trong cấu hình. Được viết bằng ngôn ngữ Groovy, Grails cho phép bạn tích hợp trực tiếp với mã trình Java kế Làm chủ Grails: Grails và Web di động Trang 2 của 21 ibm.com/developerWorks/vn/ developerWorks® thừa của bạn. Trong khi đó, nó cũng tạo ra sự linh hoạt cho một ngôn ngữ kịch bản. Sau khi nghiên cứu Grails, bạn sẽ thấy việc phát trển Web theo một phương pháp hoàn toàn khác. WML được truyền qua giao thức Wireless Access Protocol (WAP), giống như HTML được truyền qua giao thức HTTP. WAP và WML thường được chuyển đổi cho nhau trong những giao tiếp cơ bản: Điều này thường được thấy trong các đặc tả điện thoại di động có hỗ trợ trình duyệt WAP và ngôn ngữ đánh dấu WML 1.x (xem Tài nguyên biết thông tin chi tiết về những đặc tả của WML và WAP). Nếu bạn hướng tới mục tiêu là những người sử dụng BlackBerry, bạn nên quan tâm tới WML trong các ứng dụng của bạn. (BlackBerry chiếm khoảng 40% thị phần của điện thoại thông minh, tiếp theo là iPhones và Windows® Mobile lần lượt ở vị trí thứ hai và thứ ba.) Điện thoại thông minh BlackBerry sử dụng trình duyệt WAP, mặc dù vậy rất nhiều người sử dụng thiết bị này vẫn thích tải về những trình duyệt Web thực sự như Opera Mini (xem Tài nguyên). Lập kế hoạch cho một chuyến đi công tác Nếu bạn nghiên cứu từ đầu loạt bài viết về Làm chủ Grails, thì bạn chắc hẳn đã sẵn sàng với việc tạo một ứng dụng lập kế hoạch chuyến đi (trip planner) thân thiện với điện thoại di động. Hãy tạo một tệp có tên testwml.gsp trong thư mục web-app của ứng dụng trip planner và nhập vào tệp vừa tạo những mã trình, được biểu thị trong Ví dụ 1: Ví dụ 1. WML tĩnh <% response.setContentType("text/vnd.wap.wml") %> <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//PHONE.COM//DTD WML 1.1//EN" "http://www.phone.com/dtd/wml11.dtd" > <wml> <card id="f1" title="Flight 1"> <p mode="wrap">From: DEN</p> <p mode="wrap">To: ORD</p> <p mode="wrap">UAL 1234</p> <p mode="wrap">Jun 30, 10:30am</p> <p> <anchor>Next<go href="#f2"/></anchor> </p> </card> <card id="f2" title="Flight 2"> <p mode="wrap">From: ORD</p> <p mode="wrap">To: DEN</p> <p mode="wrap">UAL 9876</p> <p mode="wrap">Jul 02, 1:15pm</p> <p> <anchor>Previous<go href="#f1"/></anchor> </p> </card> </wml> Bạn có thể xem trực tiếp trang này (trên điện thoại của bạn) tại địa chỉ http://www.davisworld.org/ testwml.gsp. Bạn đã quen với việc xem HTML trong một GSP. Trong trường hợp này, bạn đang sử dụng WML thay thế cho HTML. Làm chủ Grails: Grails và Web di động Trang 3 của 21 developerWorks® ibm.com/developerWorks/vn/ Khi bạn gửi WML từ một GSP, bạn phải viết đè lên kiểu MIME mặc định từ text/html thành text/ vnd.wap.wml, như trong dòng đầu tiên của Ví dụ 1. Nếu bạn đang xử lý WML tĩnh, bạn có thể đơn giản tạo tệp với đuôi mở rộng WML thay vì đuôi mở rộng GSP. Sau đó, phần lớn máy chủ Web sẽ gửi trả lại đúng kiểu MIME mà không cần tới phương thức gọi response.setContentType. Trong tệp $TOMCAT_HOME/conf/web.xml, bạn sẽ thấy rằng ánh xạ MIME cho các tệp WML đã được thiết lập. Nếu bạn đang sử dụng Apache HTTPD, một ánh xạ mặc định tương tự cho các tệp WML có trong tệp $APACHE_HOME/conf/mime.types. Ví dụ 2 biểu thị ánh xạ kiểu MIME của Tomcat: Ví dụ 2. Thiết lập kiểu MIME trong Tomcat <mime-mapping> <!-- WML Source --> <extension>wml</extension> <mime-type>text/vnd.wap.wml</mime-type> </mime-mapping> Hãy xem lại Ví dụ 1, điều tiếp theo bạn cần chú ý là DOCTYPE. Việc bao gồm câu lệnh Định nghĩa Kiểu Tài liệu (DTD) giúp định danh tệp testwml.gsp như là một tài liệu WML. Chú ý rằng tài liệu không được bọc trong các thẻ <html> thông thường. Nó bắt đầu và kết thúc bằng thẻ <wml>. Điều tiếp theo bạn cần chú ý trong Ví dụ 1 là việc thiếu các phần <head> và <body>. Mỗi một trang WML là một card, với một thuộc tính id duy nhất và thuộc tính title thân thiện với người sử dụng. Việc tải về nhiều trang/thẻ trong một tệp đơn lẻ là hoàn toàn bình thường. Đây là một giải pháp thích hợp đối với những dòng điện thoại di động thế hệ cũ có đường truyền dữ liệu rất hẹp. Bạn tải về tại một thời điểm càng nhiều, thì yêu cầu nhận và chuyển dữ liệu từ điện thoại của bạn tới máy chủ càng ít. Bạn chỉ có thể xem một thẻ tại một thời điểm, nên những thẻ còn lại sẽ được nạp sẵn trên máy di động của bạn. Với cách này, việc điều hướng xảy ra hoàn toàn trên phía máy khách. Những thẻ <p> rất quen thuộc với những người phát triển HTML. Thẻ WML <anchor> cũng tương tự thẻ HTML <a>, nếu không phân biệt về mặt cú pháp (xem Tài nguyên để tìm hiểu thêm về WML). Đây là một thủ thuật WML thông minh. Bởi vì khi bạn đang làm việc với nội dung dành riêng cho điện thoại di động, bạn có thể tạo một siêu liên kết để gọi tới điện thoại khi người sử dụng chọn liên kết. Trong Ví dụ 3, số điện thoại 303-555-1212 sẽ được gọi: Ví dụ 3. Liên kết có thể gọi được trong WML <do type="accept"> <go href="wtai://wp/mc;3035551212"/> </do> Chú ý rằng giao thức của liên kết này không giống với giao thức http://— mà nó có dạng wtai://, là tên viết tắt của Wireless Telephony Applications Interface. Bộ mô phỏng WML Để hoàn trả trang này trên PC, bạn cần một bộ mô phỏng WAP (xem Tài nguyên để biết thêm thông tin về bộ mô phỏng trong bài viết này). Truy cập phần bộ mô phỏng dotMobi, bộ mô phỏng Làm chủ Grails: Grails và Web di động Trang 4 của 21 ibm.com/developerWorks/vn/ developerWorks® này được áp dụng như một applet Java. Gõ vào URL chuỗi davisworld.org/testwml.gsp. (Chú ý rằng tiền tố http:// đã được cung cấp từ trước.) Sau đó, bạn sẽ thấy kết quả giống như trong Hình 1: Hình 1. Trang WAP được mô phỏng Chú ý rằng bộ mô phỏng dotMobi có hai giao diện khác nhau. Chúng không chỉ giúp tạo ra những cảm nhận khác nhau mà còn khác nhau về khả năng của chúng. Nếu bạn thích mô phỏng một thiết bị nào đó, các nhà sản xuất phần cứng hầu hết đều cung cấp cấp trang Web nhà phát triển để bạn có thể tải về và cài đặt những bộ mô phỏng mà bạn cần. WML động từ một GSP Ví dụ về WML đầu tiên là những mã trình tĩnh. Ví dụ 4 là một ví dụ sử dụng các thẻ quen thuộc là <g:each> và <g:if>: Ví dụ 4. Kết hợp GSP với WML <% response.setContentType("text/vnd.wap.wml") %> <% def flightList = [] Làm chủ Grails: Grails và Web di động Trang 5 của 21 developerWorks® ibm.com/developerWorks/vn/ flightList << [iata1:"DEN", iata2:"ORD"] flightList << [iata1:"ORD", iata2:"DEN"] %> <?xml version="1.0"?> <!DOCTYPE wml PUBLIC "-//PHONE.COM//DTD WML 1.1//EN" "http://www.phone.com/dtd/wml11.dtd" > <wml> <g:each in="${flightList}" var="${flight}" status="i"> <card id="f${i}" title="Flight ${i}"> <p mode="wrap">From: ${flight.iata1}</p> <p mode="wrap">To: ${flight.iata2}</p> <g:if test="${flightList.size() > i+1}"> <p> <anchor>Next<go href="#f${i}"/></anchor> </p> </g:if> </card> </g:each> </wml> Chú ý rằng tôi đã mô phỏng một số dữ liệu trong HashMap thay vì thiết lập một cơ sở hạ tầng MVC đầy đủ. Điều quan trọng là để xem bạn có thể kết hợp các thẻ GSP với WML, như tôi đã thực hiện với JavaScript trong phần "Thay đổi khung nhìn với Groovy Server Pages." (Bạn có thể xem trực tiếp ví dụ này tại địa chỉ http://davisworld.org/testwml2.gsp.) WML 1.x: Sự kết thúc của một kỷ nguyên Mặc dù nhiều người cho rằng WML đã hết thời, nhưng điện thoại di động vẫn khá trung thành với WML. WML 1.x đang phải đối mặt với những thách thức — mặc dù nó làm việc khá tốt với điện thoại di động. Ngày càng nhiều điện thoại di động đã chuyển nền tảng WML sang trình duyệt Web như trên PC. Như nhưng phần tiếp theo sẽ đề cập, việc tạo ra một trang Web thân thiện với di động dành cho các thiết bị WML 2.x hay iPhones yêu cầu bạn phải cải tiến một chút HTML hiện tại thay vì dịch toàn bộ chúng sang một ngôn ngữ đánh dấu hoàn toàn khác. Sử dụng WML 2.X (hay XHTML-MP) kết hợp với Grails Khi phiên bản WML 2.x được giới thiệu, WML được coi như là tên của nhãn hiệu hơn là tên của một ngôn ngữ đánh dấu riêng biệt (như WML 1.x). Trên thực tế, WML 2.x đơn giản là một phương ngữ XHTML: đặc biệt là XHTML-MP. Phần lớn yêu cầu của XHTML-MP giống với XML. Điều này có nghĩa bạn phải đóng cho mỗi thẻ chứa tương ứng (<p></p>, <li></li>), sử dụng ngoặc kéo cho những thuộc tính của bạn (<a href="http://somewhere.com">) và chỉ sử dụng chữ in thường cho tên của các phần tử (<h1> thay vì <H1>). XHTML-MP là một tập cha của XHTML-Basic. Bạn có thể thấy rằng với một chút điều chỉnh, trang web của bạn đã có thể làm việc với XHTML-Basic. Nhưng nó không thể sử dụng các bảng dạng lưới hay khung. Ngoài ra, nó chỉ hỗ trợ dịnh dạng ảnh gif và png. Các chức năng khác (như điều chỉnh kích cỡ ảnh và văn bản luân phiên) cũng không được hỗ trợ trong XHTML-Basic. Có rất nhiều thẻ HTML đã quen thuộc với bạn. Xem Tài nguyên để biết thông tin về những thẻ HTML được sử dụng trong XHTML-Basic và XHTML-MP. Làm chủ Grails: Grails và Web di động Trang 6 của 21 ibm.com/developerWorks/vn/ developerWorks® Có thể bạn sẽ không biết rằng việc tối ưu hóa trang Web của bạn cho một màn hình hiển thị nhỏ hơn sẽ đòi hỏi gửi lại dữ liệu ít hơn trong mỗi yêu cầu. Các trang Web (bao gồm HTML, CSS và các hình ảnh) nên có dung lượng nhỏ hơn 20KB. Bạn nên giới hạn dung lượng của các tệp bằng cách sử dụng các hàm Expires hoặc Cache-Control. Bạn nên cắt những trang Web dài thành hai hay ba trang khi bạn hiển thị chúng trên điện thoại di động. Ví dụ, trang web http://m.cnn.com đã cắt các bài viết thành ba hay bốn trang, nhưng nó cũng cung cấp một liên kết giúp bạn đọc "toàn bộ bài viết" trên một trang duy nhất. Cũng như với WML 1.x, bạn nên thêm DTD tương ứng vào phần đầu của tệp. Bạn cũng nên sửa thẻ <html> để bao gồm thuộc tính xmlns, như biểu thị trong Ví dụ 5: Ví dụ 5. Khởi động một tệp XHTML-MP <!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> ... </html> Bạn cũng nên gửi nó với kiểu MIME tương ứng của application/vnd.wap.xhtml+xml, mặc dù nhiều thiết bị di động sẽ chấp nhận application/xhtml+xml. Việc sử dụng application/xhtml+xml cũng giúp bạn tìm lỗi của mã trình trên một trình duyệt máy tính cá nhân. Xem XHTML-MP Để xem XHTML-MP, hãy truy cập trang web http://m.yahoo.com.(Nó trông không đẹp lắm trên một trình duyệt Web, nhưng nó trông tuyệt vời trên một chiếc điện thoại di động.) Chọn View > Source, bạn sẽ thấy XHTML-MP DTD ở phần trên cùng của tài liệu. Để hiểu rõ hơn trang Web trông như thế nào trên một thiết bị thực tế, bạn cần tìm một bộ mô phỏng khác. Ví dụ, trang blog của Sandip Chitale cung cấp một trình cài thêm vào Firefox, nó trong giống như một chiếc iPhone (xem Tài nguyên). Bạn nên biết rằng bộ mô phỏng này lớn hơn một chút so với thiết bị thực tế. Nó trông đẹp hơn một bộ mô phỏng thực sự, nhưng nó sẽ giúp bạn đánh giá được trang Web của bạn sẽ trông như thế nào khi được hiển thị trên iPhone. (Tôi sẽ giới thiệu với bạn một số cách đánh giá chính xác hơn ngay sau đây.) Hình 2 biểu thị m.yahoo.com được mô phỏng trên bộ mô phỏng của Chitale: Làm chủ Grails: Grails và Web di động Trang 7 của 21 developerWorks® ibm.com/developerWorks/vn/ Hình 2. Xem trang Web di động Yahoo trên một bộ mô phỏng iPhone Đánh giá XHTML-MP Một số trình đánh giá trực tuyến có thể giúp bạn biết chắc chắn rằng bạn đang gửi đi XHTML-MP đã được định dạng chính xác. Bạn có thể thử công cụ kiểm tra như W3C mobileOK Basic Checker hay ready.mobi (xem Tài nguyên). Cả hai đều cho kết quả tốt, nhưng bộ mô phỏng ready.mobi đưa ra nhiều thông tin để đánh giá hơn so với W3C. Ví dụ, Hình 3 cho thấy trình đánh giá W3C nói gì về http://m.google.com: Làm chủ Grails: Grails và Web di động Trang 8 của 21 ibm.com/developerWorks/vn/ developerWorks® Hình 3. Báo cáo của trình đánh giá W3C về trang Web di động của Google Hình 4 là phần đầu tiên trong báo cáo của công cụ ready.mobi về trang web http://m.yahoo.com: Hình 4. Báo cáo của ready.mobi về trang Web di động của Yahoo Nó đánh giá Yahoo! đạt 4 điểm trong thang điểm 5. Kéo thanh cuộn xuống một chút, nó cung cấp một loạt các thông số khác nhau giúp bạn có thể xem trang web thực tế của bạn sẽ trông như thế nào. Hình 5 biểu thị kết quả trên Nokia N70: Làm chủ Grails: Grails và Web di động Trang 9 của 21 developerWorks® ibm.com/developerWorks/vn/ Hình 5. Xem trang Web di động của Yahoo bằng cách sử dụng một bộ mô phỏng Ở dưới cùng của trang, trình đánh giá ready.mobi hiển thị các kết quả chi tiết về các bước kiểm tra, mỗi bước qua được đánh dấu (màu xanh), không qua (màu đỏ), hay cảnh báo (màu vàng). Ví dụ, tuy http://m.yahoo.com dường như hoạt động tốt với rất nhiều thiết bị, nhưng XHTML của nó chưa tương thích 100%, như được biểu thị trong Hình 6: Hình 6. Xem những lỗi của XHTML-MP Như được biểu thị trong Hình 7, bạn có thể thấy rằng Yahoo! thiếu một số thuộc tính alt trên hình ảnh của nó và những lỗi khi xác định kích cỡ ảnh: Làm chủ Grails: Grails và Web di động Trang 10 của 21 ibm.com/developerWorks/vn/ developerWorks® Hình 7. Xem các lỗi Grails và XHTML-MP Liệu Grails có sẵn sàng chạy tốt với Web di động? Hình 8 cho thấy trình đánh giá ready.mobi nói gì về trang liệt kê của ứng dụng trip planner: Hình 8. Grails không tương thích lắm với XHTML-MP Nên chúng ta cần làm một số việc để giải quyết vấn đề này. Đầu tiên, tạo ra một bao đóng mlist trong grails-app/controllers/AirportController.groovy. Nó sẽ trả lại 5 phần tử thay vì 10 phần tử như Làm chủ Grails: Grails và Web di động Trang 11 của 21 developerWorks® ibm.com/developerWorks/vn/ bao đóng liệt kê mặc định. Việc tạo ra một bao đóng riêng biệt giúp bạn không làm ảnh hưởng tới tệp list.gsp, như được biểu thị trong Ví dụ 6: Ví dụ 6. Một bao đóng mới trong AirportController def mlist = { if(!params.max) params.max = 5 [airportList:Airport.list(params)] } Bây giờ, hãy sao chép grails-app/views/airport/list.gsp sang mlist.gsp. (Sau đó, tôi sẽ hướng dẫn bạn một số cách chuyển hướng những người sử dụng điện thoại di động tới các nội dung chính xác.) Trình đánh giá cho biết trang Web không trả lại XHTML-MP. Hãy sửa mlist.gsp sao cho nó bao gồm DTD cần thiết và thuộc tính xmlns trên thẻ <html>. Bạn cũng nên vô hiệu hóa thẻ meta thiết lập kiểu nội dung cho text/html. Bước cuối cùng: sao chép dòng chứa CSS từ grails-app/views/ layout/main.gsp sang tệp này. (SiteMesh — thư viện khuôn mẫu mà Grails sử dụng — được cấu hình để trang trí mặc định cho các tệp text/html.) Ví dụ 7 biểu thị tệp mlist.gsp: Ví dụ 7. Chuyển một trang GSP thành XHTML-MP <% response.setContentType("application/xhtml+xml")%> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/--> <link rel="stylesheet" href="${createLinkTo(dir:'css',file:'main.css')}" /> <meta name="layout" content="main" /> <title>Airport List</title> </head> ... </html> Trong khi bạn đang sửa tệp, bạn có thể muốn đơn giản hóa bố cục của các bảng. Trình đánh giá cho biết lỗi với các thẻ <thead> và <tbody>, nên bạn cần xóa bỏ những thẻ này. Bởi vì màn hình của điện thoại di động có chiều rộng ngắn hơn chiều cao, bố cục trong Ví dụ 8 sẽ trông tốt hơn: Làm chủ Grails: Grails và Web di động Trang 12 của 21 ibm.com/developerWorks/vn/ developerWorks® Ví dụ 8. Đơn giản hóa bảng <table> <tr> <g:sortableColumn property="id" title="Id" /> <g:sortableColumn property="name" title="Name" /> </tr> <g:each in="${airportList}" status="i" var="airport"> <tr class="${(i % 2) == 0 ? 'odd' : 'even'}"> <td> <g:link action="show" id="${airport.id}">${airport.id?.encodeAsHTML()} </g:link> </td> <td>${airport.iata?.encodeAsHTML()}<br/> ${airport.name?.encodeAsHTML()} </td> </tr> </g:each> </table> Hình 9 cho thấy trang mới trong như thế nào trên bộ mô phỏng iPhone: Làm chủ Grails: Grails và Web di động Trang 13 của 21 developerWorks® ibm.com/developerWorks/vn/ Hình 9. Trang Liệt kê được tùy chỉnh cho iPhone Hình 10 cho thấy ready.mobi đánh giá như thế nào về trip planner sau khi được tùy chỉnh: Hình 10. Trang Liệt kê vượt qua sự đánh giá Làm chủ Grails: Grails và Web di động Trang 14 của 21 ibm.com/developerWorks/vn/ developerWorks® Tốt hơn nhiều phải không? Và chỉ cần thay đổi một chút là có thể vượt qua sự đánh giá của ready.mobi. Gọi lại từ "Thay đổi khung nhìn với Groovy Server Pages" mà bạn có thể tạo ra những thay đổi này đối với những khuôn mẫu mặc định bằng cách gõ grails install-templates trên cửa sổ lệnh. Phát triển các trang dành cho iPhone iPhone có lẽ là một trong ba kiểu thiết bị dễ nhất để hỗ trợ. Bạn không cần không cần làm một điều khác biệt nào so với việc phát triển một trang Web bình thường. Trình duyệt Safari trên iPhone được viết bằng mã trình tương tự mã trình của các trình duyệt trên máy tính cá nhân. Do vậy, những gì người thấy trên Safari cũng giống với những gì họ thấy trên những trình duyệt thông thường khác. Mặc dù vậy, bạn chỉ có thể gửi một số trả lại ẩn trên một chiếc iPhone mà thôi. Ví dụ, một màn hình iPhone có độ phân giải 320x480. Trong khi đó, trình duyệt thiết lập mặc định chiều rộng của các trang Web là 980 pixel. Điều này giúp bạn có thể đọc tốt các văn bản khi màn hình điện thoại di động được thiết lập ở chế độ phong cảnh, nhưng văn bản sẽ rất nhỏ khi màn hình điện thoại di động được thiết lập ở chế độ chân dung. Đừng lo lắng về điều này, vì chỉ với một thẻ meta đơn giản, bạn có thể điều chỉnh kích cỡ của trang Web: Thẻ viewport cho phép bạn cung cấp những gợi ý cho trình duyệt di động Safari. Mã trình trong Ví dụ 9 giúp tăng đáng kể khả năng đọc của trang Web khi nó được hiển thị trên một chiếc iPhone. (Tuy nhiên, bộ mô phỏng iPhone trên Firefox không hỗ trợ thẻ meta. Do vậy, để xem trang Web hoạt động như thế nào, bạn cần một chiếc iPhone thực.) Ví dụ 9. Thiết lập viewport dành cho iPhone <meta name="viewport" content="initial-scale=1.0" /> inital-scale có giới hạn từ 0 tới 10 và trị width và height (được biểu thị trong hỗ trợ các giá trị phân số. Bạn cũng có thể sử dụng các giá Ví dụ 10), với giá trị tối đa lên tới 10.000 pixel: Ví dụ 10. Thiết lập giá trị width và height cho viewport <meta name="viewport" content="width=600;height=400" /> Các siêu liên kết trên iPhone iPhone cung cấp một số xử lý đặc biệt khi nó gặp những liên kết. Nếu bạn sử dụng một tiền tố tel: thay vì http://, như được biểu thị trong Ví dụ 11, thì khi bạn nhấn lên liên kết, một số điện thoại sẽ được gọi: Ví dụ 11. Những liên kết có thể gọi được trên iPhone <p> telephone number: <a href="tel:303-555-1212">303-555-1212</a> </p> Nếu bạn sử dụng tiền tố truyền thống mailto:, như được biểu thị trong Ví dụ 12, thì khi bạn nhấn lên liên kết, một ứng dụng thư điện tử sẽ được khởi động: Làm chủ Grails: Grails và Web di động Trang 15 của 21 developerWorks® ibm.com/developerWorks/vn/ Ví dụ 12. Những liên kết thư điện tử <p> mail: <a href="mailto:[email protected]">Scott Davis</a> </p> Nếu bạn cung cấp một liên kết với Google Maps, như được biểu thị trong Ví dụ 13, thì khi bạn nhấn lên liên kết, ứng dụng Google Maps gốc sẽ được khởi động thay vì được hoàn trả trên Safari: Ví dụ 13. Các liên kết Google Map <p> local google maps: <a href="http://maps.google.com/maps?q=denver+international+airport">DEN</a> </p> Việc nhập một điểm đầu và một điểm cuối, như được biểu thị trong 14, giúp người sử dụng biết được lộ trình khi họ nhấn lên liên kết: Ví dụ 14. Lộ trình lái xe trên Google Map <p> driving directions: <a href="http://maps.google.com/maps?daddr= denver+airport&saddr=coors+field+denver,+co">Directions</a> </p> Các chiến lược dành cho Web di động Bây giờ, bạn đã biết cách tạo nội dung cho ba kiểu thiết bị cơ bản, tất cả những gì bạn cần làm là xác định yêu cầu cho ứng dụng của bạn. Có ba chiến lược cơ bản mà bạn cần thực hiện. Tạo một trang Web dành riêng cho nội dung di động Như bạn đã biết trong phần trước, phương thức m được rất nhiều trang Web sử dụng. Google, Yahoo!, và CNN tất cả đều thiết lập một miền m tách biệt với trang chính, dành cho nội dung di động. Nếu bạn không muốn mất thời gian với Hệ thống Tên Miền (DNS), bạn có thể tạo ra một URL như http://mysite.org/mobile. Bạn cũng có thể đang ký một miền .mobi được dành riêng cho nội dung di động. Kiểm tra tác nhân người dùng Tất cả trình duyệt Web đều tự đồng nhất với máy chủ khi chúng gửi yêu cầu dữ liệu tới máy chủ. Bạn có thể sử dụng thông tin này để tùy biến trang Web cho phù hợp với nội dung dành cho các thiết bị di động. (Công nghệ này đã được http://twitter.com sử dụng.) Truy cập http://davisworld.org/echo.gsp. Sử dụng một vòng lặp đơn giản, trang trong Ví dụ 15 trả lại dữ liệu cho HTTP request: Làm chủ Grails: Grails và Web di động Trang 16 của 21 ibm.com/developerWorks/vn/ developerWorks® Ví dụ 15. Hiển thịRequest Headers <h2>Request Headers</h2> <table border="1"> <tr> <th>Header</th> <th>Value</th> </tr> <g:each in="${request.headerNames}" var="${name}"> <tr> <td>${name}</td> <td>${request.getHeader(name)}</td> </tr> </g:each> </table> Như bạn có thể thấy trong Hình 11, trình duyệt Firefox của tôi cung cấp rất nhiều thông tin khi tôi mở địa chỉ http://davisworld.org/echo.gsp: Hình 11. Xem phần đầu HTTP Dựa trên chuỗi user-agent được biểu thị trong Hình 11, bạn có thể thấy rằng người yêu cầu đang chạy hệ điều hành Mac với Intel CPU. Bạn cũng biết phiên bản của OS (10.5), cơ chế hoàn trả HTML (Gecko) và trình duyệt hiện thời (Firefox). Ví dụ 17 cho thấy một số chuỗi user-agent phổ biến khác: Ví dụ 17. Các chuỗi user-agent phổ biến BlackBerry7520/4.0.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 UP.Browser/5.0.3.3 UP.Link/5.1.2.12 Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322) Bằng cách sử dụng giá trị của request.getHeader("user-agent"), bạn có thể hiển thị tốt nội dung trên các trình duyệt tương ứng. Gửi lại những gì trình duyệt chấp nhận Chiến lược thứ ba là nhằm đáp ứng những gì trình duyệt thực muốn. Mỗi một yêu cầu chứa một giá trị accept cũng như giá trị user-agent. Trình duyệt Firefox gửi đi giá trị accept này: Làm chủ Grails: Grails và Web di động Trang 17 của 21 developerWorks® ibm.com/developerWorks/vn/ text/html,application/xhtml+xml,application/xml; Điều này cho biết rằng máy chủ mà Firefox hoạt động tốt là text/html. Nếu máy chủ không có dữ liệu text/html, thì nó có thể gửi đi application/xhtml+xml. Nếu không có cả hai dữ liệu trên, máy chủ sẽ duyệt qua danh sách cho tới khi nó tìm thấy một kiểu MIME mà nó có thể trả lại. Trình duyệt WAP 1.x sẽ yêu cầu text/vnd.wap.wml và một chiếc điện thoại hiện đại hơn sẽ yêu cầu application/vnd.wap.xhtml+xml. Bằng cách chú ý những điều này, một lập trình viên có thể gửi lại những dữ liệu tương ứng. Tất nhiên, ba chiến lược này không tách biệt với nhau. Hãy sử dụng tất cả những chiến lược trên để đảm bảo rằng trang Web của bạn sẽ hoạt động tốt trên hơn 3,3 tỷ máy điện thoại di động trên toàn thế giới. Kết luận Việc tối ưu hóa ứng dụng Grails của bạn giúp nó hoạt động tốt trên điện thoại di động có nhiều mức độ phức tạp khác nhau: dễ dàng (với iPhone), trung bình (với các thiết bị XHTML-MP) và khó (với các thiết bị WML 1.x). Với những bộ mô phỏng và trình đánh giá được giới thiệu trong bài viết này, bạn hoàn toàn có thể hỗ trợ được Web di động. Trong bài viết tiếp theo, bạn sẽ nghiên cứu về cách làm việc với cơ sở dữ liệu trong Grails. Bạn cũng sẽ tìm hiểu về Mapping DSL, cũng như cách sử dụng những chú thích Hibernate và các tệp HBM. Với những kỹ thuật này, bạn sẽ sử dụng các bảng và trường tên hiện tại để kết nối với Grails, thậm chí chúng không tương ứng với những quy ước đặt tên theo tiêu chuẩn của Grails. Làm chủ Grails: Grails và Web di động Trang 18 của 21 ibm.com/developerWorks/vn/ developerWorks® Các tải về Mô tả Làm chủ Grails: Grails và Web di động Tên Kích thước j-grails06178.zip 866KB Trang 19 của 21 developerWorks® ibm.com/developerWorks/vn/ Tài nguyên Học tập • Làm chủ Grails: Đọc thêm về loạt bài viết này để hiểu sâu hơn về Grails và tất cả những gì bản có thể thao tác với nó. • Grails: Truy cập trang Web Grails Web. • Grails Framework Reference Documentation: Tài liệu về Grails. • Groovy Recipes: Greasing the Wheels of Java: Nghiên cứu thêm về Groovy và cập nhật những cuốn sách mới nhất về Grails của Scott Davis. • Practically Groovy: Loạt bài viết trên developerWorks này trình bày về những ứng dụng thực tế của Groovy và hướng dẫn bạn áp dụng chúng như thế nào và khi nào. • Groovy: Nghiên cứu thêm về Groovy tại trang Web dự án. • AboutGroovy.com: Cập nhật những bài viết và thông tin mới nhất về Groovy. • Internet World Stats: Biết thêm thông tin chi tiết về xu hướng sử dụng Internet. • "Triển vọng của phương tiện truyền thông mới" (Colin Crawford, IDG Knowledge Hub, tháng Tám năm 2008): Crawford cho rắng "chúng ta đang chuyển từ PC World sang Personal Communications World." • WML và WAP: Đọc những bài viết trên Wikipedia và những kỹ thuật di động này. • Phần công nghệ OMA: Open Media Alliance chứa những đặc tả về WML và WAP. • "Phát triển các ứng dụng Web mạng không dây" (Carol Jones, developerWorks, tháng Sáu năm 2000): Tìm hiểu những kiến thức cơ bản về WAP và WML. • Hướng dẫn WAP/WML: Tìm hiểu thêm về WAP và WML. • XHTML-Basic 1.1: Đặc tả XHTML-Basic của W3C. Bạn có thể tìm thấy một danh sách các thẻ có thể sử dụng được ở đây. • XHTML Mobile Profile: Những thẻ được hỗ trợ bởi XHTML-MP. • Những bộ mô phỏng điện thoại di động: • bộ mô phỏng dotMobi • bộ mô phỏng iPhone dành cho Firefox • W3C mobileOK Basic Checker • công cụ kiểm tra ready.mobi • Apple Web Apps DevCenter: Hướng dẫn chi tiết thiết kế nội dung dành cho iPhone. • Hiệu sách kỹ thuật: Truy cập để có những quyển sách mới nhất về chủ đề này và những chủ đề công nghệ khác. • Khu vực về Java trên developerWorks: Đọc hàng trăm bài viết về tất cả các khía cạnh của lập trình Java. Lấy sản phẩm và công nghệ • Grails: Tải xuống những phiên bản mới nhất của Grails. • Opera Mini: Một trình duyệt di động miễn phí. Thảo luận • Tham gia blog developerWorks và đăng ký làm thành viên của cộng đồng developerWorks. Làm chủ Grails: Grails và Web di động Trang 20 của 21 ibm.com/developerWorks/vn/ developerWorks® Đôi nét về tác giả Scott Davis Scott Davis là một tác giả, diễn giả và nhà phát triển phần mềm được cộng đồng quốc tế thừa nhận, ông có những cuốn sách như Groovy Recipes: Greasing the Wheels of Java (Các cách thức Groovy: Bôi trơn các bộ máy hoạt động của Java), GIS for Web Developers: Adding Where to Your Application (GIS cho các nhà phát triển web: Thêm vào đâu trong ứng dụng của bạn), The Google Maps API (các bản đồ Google của API) và JBoss At Work (JBoss trong công việc) © Copyright IBM Corporation 2010 (www.ibm.com/legal/copytrade.shtml) Nhẫn hiệu đăng ký (www.ibm.com/developerworks/vn/ibm/trademarks/) Làm chủ Grails: Grails và Web di động Trang 21 của 21