Đưa công cụ Google Translator vào ứng dụng Java để phục vụ cho vài mục đích của bạn như: dịch văn bản khi crawl dữ liệu từ site nước ngoài hay tự động chuyển đổi ngôn ngữ nội dung trong ứng dụng hoặc đơn thuần bạn chỉ muốn viết 1 tool cho phép dịch văn bản trên desktop mà không cần phải bật trình duyệt, tạo ra 1 công cụ mang thương hiệu của "riêng" bạn để chia sẻ cho bạn bè hay ai đó sử dụng.
Nếu bạn đã từng gặp phải những vấn đề về sử dụng Google Translate API để dịch văn bản, ắt hẳn bạn đã search Google để tìm kiếm các bài viết liên quan. Có những bài viết hướng dẫn cách sử dụng Google Translator API để dịch văn bản nhưng tin buồn rằng Google Translate API là dịch vụ mà bạn phải trả phí.
Có dự án open-source cho phép bạn kết nối tới Google Translate API qua secret key sau:
http://code.google.com/p/google-translate-api-v2-java/
Đọc qua source code thì thấy bạn vẫn phải cung cấp API Key để xác thực - cái mà phải mất phí để mua. Thư viện trên chỉ giúp chúng ta bước đầu về kết nối và đóng gói các tính năng của Google Translate API mà thôi.
Làm thế nào để sử dụng miễn phí Google Translate API?
Đây không phải là cách hack / crack API Key để sử dụng miễn phí mà là thủ thuật nhỏ lợi dụng phiên bản dành cho Mobile của Google Translator để viết ra ứng dụng dịch văn bản.Tôi sẽ hướng dẫn bạn từng bước phân tích và viết mã thực thi chi tiết cho công cụ này.
Như chúng ta đều biết, đây là trang hiển thị chính của công cụ Google Translator (phiên bản web cho desktop):
Trang này sử dụng AJAX để gửi / nhận thông tin trên dịch vụ Google Translator. Trong Java, ta không thể clean một trang có chứa mã AJAX để bóc tách thông tin được (mặc dù trong PHP có thể làm điều này bằng CURL). Vì vậy chúng ta cần phải tìm một giải pháp khác để thay thế và khắc phục khó khăn trên.
Các add-on cần có cho FireFox:
User-Agent Switcher (Giúp chuyển đổi user agent hiện tại sang user agent mobile nào đó)
FireBug (sử dụng để theo dõi Request/Response trả về khi thực hiện thao tác dịch văn bản)
Sau khi bạn đã cài đặt thành công cả 2 addons trên, chúng ta sẽ bắt đầu thực hiện từng bước để nắm rõ cơ chế Google Translator phiên bản mobile này.
Đầu tiên, bạn phải chuyển User-Agent của trình duyệt sang 1 User-Agent mobile nào đó. Ví dụ, tôi chọn User-Agent iPhone 3:
Điều này nói với server chạy dịch vụ Google Translator rằng "Tôi đang sử dụng công cụ này trên iPhone 3. Hãy trả về cho tôi giao diện phù hợp với thiết bị di động của tôi".
Và đây là kết quả mà Google đáp lại:
Bước tiếp theo, chúng ta sẽ phải theo dõi thông tin gửi đi / nhận về khi sử dụng công cụ này để tìm hướng và giải pháp kỹ thuật để viết code xử lý.
Nhấn phím F12 để bật FireBug và chuyển sang tab Net để theo dõi thông tin Request/Response.
Nhìn vào kết quả trả về như ở trên, bạn hoàn toàn đã biết được khi dịch văn bản gửi lên dịch vụ Google Translator những tham số gì. URL này ta sẽ note lại để lát viết code sử dụng.
Bạn click vào URL bên dưới panel của FireBug sẽ ra các thông tin về Request / Response. Và cái mà chúng ta đang quan tâm đó chính là dữ liệu trả về:
Bạn click vào URL bên dưới panel của FireBug sẽ ra các thông tin về Request / Response. Và cái mà chúng ta đang quan tâm đó chính là dữ liệu trả về:
Dữ liệu trả về là JSON Data. Đây là thông tin cuối cùng mà chúng ta muốn biết để có thể thao tác lấy về dữ liệu trong Java Code. Bấy nhiêu là đủ, bây giờ có thể viết code xử lý được rồi.
Mã xử lý: GoogleTranslator.java
Với mã trên, bạn phải chú ý gửi kèm User-Agent khi request lên dịch vụ Google Translator, nếu không dịch vụ sẽ reject request của bạn.
Dữ liệu trả về là JSON nên tôi sẽ dùng thư viện hỗ trợ thao tác với các JSON Object để bóc tách dữ liệu và hiển thị chúng.
Với bài viết này, tôi demo sử dụng 2 ngôn ngữ ENGLISH và VIETNAMESE, bạn hoàn toàn có thể thêm các Language Code vào trong LANGUAGE enum.
Để chạy thử mã xử lý trên, tôi tạo 1 Class để test, ví dụ class Demo:
Kết quả trả về như sau:
Viết mã xử lý cho công cụ.
Với phần mã lệnh này tôi cố gắng thiết kế nó ở dạng POJO và đóng gói lại trong 1 class duy nhất để dễ sử dụng. Bạn có thể sử dụng API này cho Swing, Console, JSP / JSF, Web Service....Tôi sẽ không đi sâu vào phần giao diện vì nó tốn khá nhiều thời gian, vì vậy tôi tập trung xử lý phần core của công cụ này.
Thư viện cần có: json_simple_1.1.jar
Tạo dự án mới và đặt tên là GoogleTranslator và import thư viện Json Simple vào dự án.
Mã xử lý: GoogleTranslator.java
package translator; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; /** * * @author Code4LifeVn */ public class GoogleTranslator { private final String googleTranslatorURL = "http://translate.google.com/translate_a/t?"; private LANGUAGE srcLang = LANGUAGE.AUTO; private LANGUAGE destLang = LANGUAGE.VIETNAMESE; private String userAgent = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16"; public String translate(String query) throws MalformedURLException, IOException, ParseException { URL url = new URL(this.buildURLRequestWith(query)); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.addRequestProperty("User-Agent", this.userAgent); conn.setRequestMethod("GET"); conn.setConnectTimeout(30000); conn.connect(); InputStream inputStream = conn.getInputStream(); BufferedReader bis = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); String respContent = bis.readLine(); inputStream.close(); bis.close(); conn.disconnect(); StringBuilder contentBuilder = new StringBuilder(); JSONParser parser = new JSONParser(); JSONObject jsonData = (JSONObject) parser.parse(respContent); JSONArray sentences = (JSONArray) jsonData.get("sentences"); for (Object sentence : sentences) { contentBuilder.append(((JSONObject) sentence).get("trans").toString().trim()); } return contentBuilder.toString().trim().replace(" .", ". "); } private String buildURLRequestWith(String query) { StringBuilder urlBuilder = new StringBuilder(); urlBuilder.append(this.googleTranslatorURL); urlBuilder.append("client=webapp"); urlBuilder.append("&sl=auto"); urlBuilder.append("&tl=").append(this.destLang); urlBuilder.append("&hl=").append(this.srcLang); urlBuilder.append("&sc=1"); String queryEncoded = ""; try { queryEncoded = URLEncoder.encode(query, "UTF-8"); } catch (Exception e) { } urlBuilder.append("&q=").append(queryEncoded); return urlBuilder.toString(); } public LANGUAGE getSrcLang() { return srcLang; } public void setSrcLang(LANGUAGE srcLang) { this.srcLang = srcLang; } public LANGUAGE getDestLang() { return destLang; } public void setDestLang(LANGUAGE destLang) { this.destLang = destLang; } public String getUserAgent() { return userAgent; } public void setUserAgent(String userAgent) { this.userAgent = userAgent; } public static enum LANGUAGE { ENGLISH("en"), VIETNAMESE("vi"), AUTO("auto"); private String lang = ""; private LANGUAGE(String lang) { this.lang = lang; } @Override public String toString() { return this.lang; } } }
Dữ liệu trả về là JSON nên tôi sẽ dùng thư viện hỗ trợ thao tác với các JSON Object để bóc tách dữ liệu và hiển thị chúng.
Với bài viết này, tôi demo sử dụng 2 ngôn ngữ ENGLISH và VIETNAMESE, bạn hoàn toàn có thể thêm các Language Code vào trong LANGUAGE enum.
Để chạy thử mã xử lý trên, tôi tạo 1 Class để test, ví dụ class Demo:
import java.io.IOException; import translator.GoogleTranslator; import java.net.MalformedURLException; import org.json.simple.parser.ParseException; import static translator.GoogleTranslator.*; /** * * @author Code4LifeVn */ public class Demo { public static void main(String[] args) throws MalformedURLException, IOException, ParseException { GoogleTranslator translator = new GoogleTranslator(); translator.setSrcLang(LANGUAGE.ENGLISH); translator.setDestLang(LANGUAGE.VIETNAMESE); String data = translator.translate("Hello Java"); System.out.println(data); } }
Do dữ liệu truyền bằng phương pháp GET nên sẽ giới hạn về độ dài ký tự gửi lên. Vì vậy, bạn phải phát triển thêm để xử lý khéo léo các trường hợp URL vượt quá giới hạn ký tự (2kb - 8kb).
Với công cụ này, tôi cảm thấy khá ok về mặt thiết kế cũng như số lượng API cần có để sử dụng, không phức tạp và rườm rà như thư viện hỗ trợ Google Translate API ở phần trên bài viết đã giới thiệu.
Những bạn nào thấy thích thú và muốn phát triển thêm hãy đưa những thông tin bổ ích mà bạn phát hiện hoặc làm mới cho công cụ này để mọi người cùng học hỏi nhé!
Với công cụ này, tôi cảm thấy khá ok về mặt thiết kế cũng như số lượng API cần có để sử dụng, không phức tạp và rườm rà như thư viện hỗ trợ Google Translate API ở phần trên bài viết đã giới thiệu.
Những bạn nào thấy thích thú và muốn phát triển thêm hãy đưa những thông tin bổ ích mà bạn phát hiện hoặc làm mới cho công cụ này để mọi người cùng học hỏi nhé!
cam on ban rat nhieu ve bai viet, rat huu ich
Trả lờiXóaa ơi...em làm theo cách của a cũng ra được kết quả rồi ...nhưng kết quả của em bị mã hóa em chưa biết xử lý thế nào ..như hello java của em sẽ ra là xin chà o java
Trả lờiXóaa giúp em vs ah
Hi em, dữ liệu trả về như vậy có thể do em chưa thiết lập Charset Encoding là UTF-8
Trả lờiXóamình chạy nhưng nó cứ báo lỗi chỗ conn.connect(); làm thế nào để sửa lỗi chỗ đấy hả bạn
Trả lờiXóaException nó bắn ra là gì? Bạn phải nói rõ Exception Message chứ nói chung chung thế sao biết được ^^
Trả lờiXóaLỗi này xảy ra do hết thời gian timeout đợi response từ phía server về.
Trả lờiXóaMÌnh vừa test ở máy chỗ làm + mạng chỗ làm không có vấn đề gì.
Bạn thử tăng thời gian timeout lên khoảng 1 phút với mạng nhà bạn xem thế nào nhé.
(hình demo đính kèm)
mình chạy được rồi. cám ơn bạn nhé
Trả lờiXóasao em import thư viện Json Simple vào dự án không được vây anh?
Trả lờiXóadc rui... ga qua..
Trả lờiXóaAnh ơi cho em hỏi. e cũng bị lỗi như thế thì tăng thời gian timeout như thế nào ? tại e cũng mới học java
Trả lờiXóacảm ơn a...em làm được rồi ah :D
Trả lờiXóaở đoạn này em:
Trả lờiXóaBufferedReader bis = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
thiết lập cái này ở đoạn nào vậy a...em ko tìm được :(
Trả lờiXóaChào các bạn,
Trả lờiXóaCác bạn có thể request cái này cho tiện
http://translate.google.com/translate_a/t?client=gtrans&sl=en&tl=vi&format=html&v=1.0&q=Hello%20Java
hoặc API 2.0
http://translate.google.com/translate_a/t?client=gtrans&sl=en&tl=vi&format=html&v=2.0&q=Hello%20Java
Google Translate API v1 đã bị Google deprecated. Còn version 2.0 sử dụng không ổn định ở những văn bản dài. Bạn thử dịch bằng API ở trên bài viết với API v2.0 xem có sự khác biệt nào không ^^.
Trả lờiXóaBài viết rất hay và ý nghĩa :) Thanks Đỗ Mạnh nhé
Trả lờiXóaAnh ơi cho em hỏi tải thư viện translator.GoogleTranslator; ở đâu ạ? Anh cho em link có được k?
Trả lờiXóaTrong tut này anh không sử dụng thư viện GTranslate. Nếu em muốn dùng em tải ở đây: https://code.google.com/p/google-api-translate-java/
Trả lờiXóaCho mình hỏi có Google Search API kiểu giống Translate API như trên không? Xin cảm ơn.
Trả lờiXóa