微信公號開發(fā)實(shí)戰(zhàn)之智能翻譯
本篇文章為大家演示如何在微信公眾帳號上實(shí)現(xiàn)“智能翻譯”,本例中翻譯功能是通過調(diào)用“百度翻譯API”實(shí)現(xiàn)的。智能翻譯是指用戶任意輸入想要翻譯的內(nèi)容(單詞或句子),系統(tǒng)能自動識別用戶采用的語言,并將其翻譯為其他語言,目前支持的翻譯方向:中->英、英->中和日->中。下面我們來看看智能翻譯最終做出來的效果:
我們通過輸入關(guān)鍵詞“翻譯”或者點(diǎn)擊菜單“翻譯”能夠看到該功能的使用幫助,然后輸入“翻譯+內(nèi)容”就能對內(nèi)容進(jìn)行翻譯了。
百度翻譯API介紹
點(diǎn)擊查看百度翻譯API使用說明,其實(shí)這份文檔已經(jīng)說的很詳細(xì)了,筆者只是將我們調(diào)用該接口時(shí)最關(guān)心的內(nèi)容摘取出來,主要如下:
1)通過發(fā)送HTTP GET請求調(diào)用百度翻譯API。
2)百度翻譯API請求地址:
- http://openapi.baidu.com/public/2.0/bmt/translate
3)調(diào)用API需要傳遞from、to、client_id和q四個(gè)參數(shù),描述如下:
key | value | 描述 |
---|---|---|
from | 源語言語種:語言代碼或auto | 僅支持特定的語言組合,下面會單獨(dú)進(jìn)行說明 |
to | 目標(biāo)語言語種:語言代碼或auto | 僅支持特定的語言組合,下面會單獨(dú)進(jìn)行說明 |
client_id | 開發(fā)者在百度連接平臺上注冊得到的授權(quán)API key | 請閱讀如何獲取api key |
q | 待翻譯內(nèi)容 | 該字段必須為UTF-8編碼,并且以GET方式調(diào)用API時(shí),需要進(jìn)行urlencode編碼。 |
在調(diào)用接口前,我們要先獲取到api key。獲取方式比較簡單,根據(jù)提示一步步操作就可以,筆者就不再贅述了。
4)對于智能翻譯,參數(shù)from和to的傳都是auto。
4)參數(shù)q的編碼方式為UTF-8,傳遞之前要進(jìn)行urlencode編碼。
5)接口返回結(jié)果示例如下:
- {"from":"en","to":"zh","trans_result":[{"src":"today","dst":"\u4eca\u5929"}]}
返回結(jié)果里的中文是unicode編碼,需要通過json_decode進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換后的示例如下:
- {
- "from": "en",
- "to": "zh",
- "trans_result": [
- {
- "src": "today",
- "dst": "今天"
- },
- {
- "src": "tomorrow",
- "dst": "明天"
- }
- ]
- }
JSON處理工具包Gson介紹
Gson是Google提供的用于在Java對象和JSON數(shù)據(jù)之間進(jìn)行轉(zhuǎn)換的Java類庫。通過使用Gson類庫,我們可以將JSON字符串轉(zhuǎn)成Java對象,反之亦然。下載地址:https://code.google.com/p/google-gson/downloads/list,Gson的使用比較簡單,直接調(diào)用它的方法toJson()或fromJson()就能完成相應(yīng)的轉(zhuǎn)換,但需要注意的是:在使用Gson將json字符串轉(zhuǎn)換成Java對象之前,需要先創(chuàng)建好與目標(biāo)Java對象。讀者可以在維基百科上學(xué)習(xí)它的使用示例http://zh.wikipedia.org/wiki/Gson。
代碼實(shí)現(xiàn)
1)創(chuàng)建與百度翻譯API返回的JSON相對應(yīng)的Java類
- import java.util.List;
- /**
- * 調(diào)用百度翻譯api查詢結(jié)果
- *
- * @author liufeng
- * @date 2013-10-21
- */
- public class TranslateResult {
- // 實(shí)際采用的源語言
- private String from;
- // 實(shí)際采用的目標(biāo)語言
- private String to;
- // 結(jié)果體
- private List<ResultPair> trans_result;
- public String getFrom() {
- return from;
- }
- public void setFrom(String from) {
- this.from = from;
- }
- public String getTo() {
- return to;
- }
- public void setTo(String to) {
- this.to = to;
- }
- public List<ResultPair> getTrans_result() {
- return trans_result;
- }
- public void setTrans_result(List<ResultPair> trans_result) {
- this.trans_result = trans_result;
- }
- }
注意:這里的類名可以任意取,但是成員變量的名字應(yīng)于翻譯API返回的JSON字符串中的屬性名保持一致,否則將JSON轉(zhuǎn)換成TranslateResult對象時(shí)會報(bào)錯(cuò)。
TranslateResult類中的trans_result屬性是一個(gè)ResultPair集合,該類的代碼如下:
- /**
- * 結(jié)果對
- *
- * @author liufeng
- * @date 2013-10-21
- */
- public class ResultPair {
- // 原文
- private String src;
- // 譯文
- private String dst;
- public String getSrc() {
- return src;
- }
- public void setSrc(String src) {
- this.src = src;
- }
- public String getDst() {
- return dst;
- }
- public void setDst(String dst) {
- this.dst = dst;
- }
- }
說明:這兩個(gè)類的封裝是Gson類庫所要求的,如果讀者不是用Gson解析json字符串,而是用JSON-lib,就沒有必要封裝這兩個(gè)類。
2)接口調(diào)用
- import java.io.BufferedReader;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.UnsupportedEncodingException;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import com.google.gson.Gson;
- /**
- *
- * @author liufeng
- * @date 2013-10-21
- */
- public class BaiduTranslateService {
- /**
- * 發(fā)起http請求獲取返回結(jié)果
- *
- * @param requestUrl 請求地址
- * @return
- */
- public static String httpRequest(String requestUrl) {
- StringBuffer buffer = new StringBuffer();
- try {
- URL url = new URL(requestUrl);
- HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
- httpUrlConn.setDoOutput(false);
- httpUrlConn.setDoInput(true);
- httpUrlConn.setUseCaches(false);
- httpUrlConn.setRequestMethod("GET");
- httpUrlConn.connect();
- // 將返回的輸入流轉(zhuǎn)換成字符串
- InputStream inputStream = httpUrlConn.getInputStream();
- InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
- BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
- String str = null;
- while ((str = bufferedReader.readLine()) != null) {
- buffer.append(str);
- }
- bufferedReader.close();
- inputStreamReader.close();
- // 釋放資源
- inputStream.close();
- inputStream = null;
- httpUrlConn.disconnect();
- } catch (Exception e) {
- }
- return buffer.toString();
- }
- /**
- * utf編碼
- *
- * @param source
- * @return
- */
- public static String urlEncodeUTF8(String source) {
- String result = source;
- try {
- result = java.net.URLEncoder.encode(source, "utf-8");
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- return result;
- }
- /**
- * 翻譯(中->英 英->中 日->中 )
- *
- * @param source
- * @return
- */
- public static String translate(String source) {
- String dst = null;
- // 組裝查詢地址
- String requestUrl = "http://openapi.baidu.com/public/2.0/bmt/translate?client_id=AAAAAAAAAAAAAAAAAAAAAAAA&q={keyWord}&from=auto&to=auto";
- // 對參數(shù)q的值進(jìn)行urlEncode utf-8編碼
- requestUrl = requestUrl.replace("{keyWord}", urlEncodeUTF8(source));
- // 查詢并解析結(jié)果
- try {
- // 查詢并獲取返回結(jié)果
- String json = httpRequest(requestUrl);
- // 通過Gson工具將json轉(zhuǎn)換成TranslateResult對象
- TranslateResult translateResult = new Gson().fromJson(json, TranslateResult.class);
- // 取出translateResult中的譯文
- dst = translateResult.getTrans_result().get(0).getDst();
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (null == dst)
- dst = "翻譯系統(tǒng)異常,請稍候嘗試!";
- return dst;
- }
- public static void main(String[] args) {
- // 翻譯結(jié)果:The network really powerful
- System.out.println(translate("網(wǎng)絡(luò)真強(qiáng)大"));
- }
- }
代碼解讀:
1)第21-53行封裝了一個(gè)http請求方法httpRequest(),相信讀過之前教程的讀者已經(jīng)很熟悉了。
2)第61-69行封裝了一個(gè)urlEncodeUTF8()方法,用于對url中的參數(shù)進(jìn)行UTF-8編碼。
3)第81行代碼中的client_id需要替換成自己申請的api key。
4)第83行代碼是對url中的中文進(jìn)行編碼。以后凡是遇到通過url傳遞中文參數(shù)的情況,一定要顯示地對中文進(jìn)行編碼,否則很可能出現(xiàn)程序在本機(jī)能正常運(yùn)行,但部署到服務(wù)器上卻有問題,因?yàn)楸緳C(jī)與服務(wù)器的默認(rèn)編碼方式可能不一樣。
5)第88行代碼就是調(diào)用百度翻譯API。
6)第90行代碼是使用Gson工具將json字符串轉(zhuǎn)換成TranslateResult對象,是不是發(fā)現(xiàn)Gson的使用真的很簡單?另外,前面提到過調(diào)用百度翻譯API返回的json里如果有中文是用unicode表示的,形如“\u4eca\u5929”,那為什么這里沒有做任何處理?因?yàn)镚son的內(nèi)部實(shí)現(xiàn)已經(jīng)幫我們搞定了。
公眾賬號后臺調(diào)用
在公眾賬號后臺,需要對接收到的文本消息進(jìn)行判斷,如果是以“翻譯”兩個(gè)字開頭的,就認(rèn)為是在使用智能翻譯功能,然后將“翻譯”兩個(gè)字之后的內(nèi)容作為翻譯對象,調(diào)用API進(jìn)行翻譯;如果輸入的只有“翻譯”兩個(gè)字,就提示智能翻譯功能的使用指南。關(guān)鍵代碼如下:
- // 文本消息
- if (WeixinUtil.REQ_MESSAGE_TYPE_TEXT.equals(msgType)) {
- String content = requestMap.get("Content").trim();
- if (content.startsWith("翻譯")) {
- String keyWord = content.replaceAll("^翻譯", "").trim();
- if ("".equals(keyWord)) {
- textMessage.setContent(getTranslateUsage());
- } else {
- textMessage.setContent(BaiduTranslateService.translate(keyWord));
- }
- out.print(WeixinUtil.textMessageToXml(textMessage));
- }
- }
第7行g(shù)etTranslateUsage()方法得到的就是智能翻譯功能的使用指南,代碼如下:
- /**
- * Q譯通使用指南
- *
- * @return
- */
- public static String getTranslateUsage() {
- StringBuffer buffer = new StringBuffer();
- buffer.append(XiaoqUtil.emoji(0xe148)).append("Q譯通使用指南").append("\n\n");
- buffer.append("Q譯通為用戶提供專業(yè)的多語言翻譯服務(wù),目前支持以下翻譯方向:").append("\n");
- buffer.append(" 中 -> 英").append("\n");
- buffer.append(" 英 -> 中").append("\n");
- buffer.append(" 日 -> 中").append("\n\n");
- buffer.append("使用示例:").append("\n");
- buffer.append(" 翻譯我是中國人").append("\n");
- buffer.append(" 翻譯dream").append("\n");
- buffer.append(" 翻譯さようなら").append("\n\n");
- buffer.append("回復(fù)“?”顯示主菜單");
- return buffer.toString();
- }
說明:希望通過本例的學(xué)習(xí),除了掌握百度翻譯API的調(diào)用之外,讀者還能夠掌握json字符串的解析方法,這樣就能夠自己學(xué)會調(diào)用更多互聯(lián)網(wǎng)上開放的接口。