微信公众平台开发实战(06) 实现翻译功能

*   1、实现翻译功能;

接受“翻译XX”的输入,返回翻译结果;

 

目录结构

  • 项目结构图
  • 增加和修改相关源代码
    1. 结果对类
    2. 翻译结果类
    3. 百度翻译服务类
    4. 核心Service

    5. Maven工程文件
  • 上传本地代码到GitHub
  • 上传工程WAR档至SAE
  • 微信客户端测试
  • 参考文档
  • 完整项目源代码

项目结构图


 

源代码文件说明

序号 文件名 说明 操作
1 ResultPair.java 结果对类 新增
2 TranslateResult.java 翻译结果类 新增
3 BaiduTranslateService 百度翻译服务类 新增
4 CoreService.java 核心服务类,新增处理各种输入,返回不同图文信息 更新
5 pom.xml 新增解析gson的jar 更新

 

增加和修改相关源代码

结果对类

ResultPair.java

package com.coderdream.model;

/**
 * 结果对
 */
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;
	}
}

 

翻译结果类 

TranslateResult.java

package com.coderdream.model;

import java.util.List;

/**
 * 调用百度翻译API查询结果
 */
public class TranslateResult {
	/**
	 * 实际采用的源语言
	 */
	private String from;
	/**
	 * 实际采用的目标语言
	 */
	private String to;
	/**
	 * 结果体
	 */
	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;
	}
}

百度翻译服务类

BaiduTranslateService.java

package com.coderdream.service;

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.coderdream.model.TranslateResult;
import com.google.gson.Gson;

/**
 * 
 */
public class BaiduTranslateService {
	/**
	 * 发起http请求获取返回结果
	 * 
	 * @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();

			// 将返回的输入流转换成字符串
			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=j8pX3RW2MWgP9qLKKrGt25Cc&q={keyWord}&from=auto&to=auto";
		// 对参数q的值进行urlEncode utf-8编码
		requestUrl = requestUrl.replace("{keyWord}", urlEncodeUTF8(source));

		// 查询并解析结果
		try {
			// 查询并获取返回结果
			String json = httpRequest(requestUrl);
			// 通过Gson工具将json转换成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 = "翻译系统异常,请稍候尝试!";
		}
		return dst;
	}

	public static void main(String[] args) {
		// System.setProperty("http.proxySet", "true");
		// System.setProperty("http.proxyHost", "proxy.jpn.hp.com");
		// System.setProperty("http.proxyPort", "8080");

		// 翻译结果:The network really powerful
		// System.out.println(translate("网络真强大"));
		System.out.println(translate("明天"));
	}
}

核心服务类

更新代码后,能实现翻译功能;接受“翻译XX”的输入,返回翻译结果;

CoreService.java

package com.coderdream.service;

import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.coderdream.bean.Logging;
import com.coderdream.dao.LoggingDao;
import com.coderdream.model.Article;
import com.coderdream.model.NewsMessage;
import com.coderdream.model.TextMessage;
import com.coderdream.util.MessageUtil;

/**
 * 核心服务类
 */
public class CoreService {

	public static String TAG = "CoreService";

	private Logger logger = Logger.getLogger(CoreService.class);

	/**
	 * 处理微信发来的请求
	 * 
	 * @param request
	 * @return xml
	 */
	public String processRequest(InputStream inputStream) {
		logger.debug(TAG + " #1# processRequest");
		SimpleDateFormat f_timestamp = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
		Logging logging = new Logging(f_timestamp.format(Calendar.getInstance().getTime()), "DEBUG", TAG,
						"#1# processRequest");
		LoggingDao loggingDao = new LoggingDao();
		loggingDao.addLogging(logging);
		// xml格式的消息数据
		String respXml = null;
		// 默认返回的文本消息内容
		String respContent = "未知的消息类型!";
		try {
			// 调用parseXml方法解析请求消息
			Map<String, String> requestMap = MessageUtil.parseXml(inputStream);
			// 发送方帐号
			String fromUserName = requestMap.get("FromUserName");
			// 开发者微信号
			String toUserName = requestMap.get("ToUserName");
			// 消息类型
			String msgType = requestMap.get("MsgType");
			String logStr = "#2# fromUserName: " + fromUserName + ", toUserName: " + toUserName + ", msgType: "
							+ msgType;
			logger.debug(TAG + logStr);
			logging = new Logging(f_timestamp.format(Calendar.getInstance().getTime()), "DEBUG", TAG, logStr);
			loggingDao.addLogging(logging);

			// 回复文本消息
			TextMessage textMessage = new TextMessage();
			textMessage.setToUserName(fromUserName);
			textMessage.setFromUserName(toUserName);
			textMessage.setCreateTime(new Date().getTime());
			textMessage.setMsgType(MessageUtil.MESSAGE_TYPE_TEXT);
			logStr = "#3# textMessage: " + textMessage.toString();
			logger.debug(TAG + logStr);
			logging = new Logging(f_timestamp.format(Calendar.getInstance().getTime()), "DEBUG", TAG, logStr);
			loggingDao.addLogging(logging);

			// 文本消息
			if (msgType.equals(MessageUtil.MESSAGE_TYPE_TEXT)) {
				respContent = "您发送的是文本消息!";

				// 接收用户发送的文本消息内容
				String content = requestMap.get("Content").trim();

				// 创建图文消息
				NewsMessage newsMessage = new NewsMessage();
				newsMessage.setToUserName(fromUserName);
				newsMessage.setFromUserName(toUserName);
				newsMessage.setCreateTime(new Date().getTime());
				newsMessage.setMsgType(MessageUtil.MESSAGE_TYPE_NEWS);
				// newsMessage.setFuncFlag(0);

				List<Article> articleList = new ArrayList<Article>();

				if (content.startsWith("翻译")) {
					String keyWord = content.replaceAll("^翻译", "").trim();
					if ("".equals(keyWord)) {
						textMessage.setContent(getTranslateUsage());
					} else {
						textMessage.setContent(BaiduTranslateService.translate(keyWord));
					}
					respContent = textMessage.getContent();

					// 设置文本消息的内容
					textMessage.setContent(respContent);
					// 将文本消息对象转换成xml
					respXml = MessageUtil.messageToXml(textMessage);
				}
				// 如果以“历史”2个字开头
				else if (content.startsWith("历史")) {
					// 将歌曲2个字及歌曲后面的+、空格、-等特殊符号去掉
					String dayStr = content.substring(2);

					// 如果只输入历史两个字,在输出当天的历史
					if (null == dayStr || "".equals(dayStr.trim())) {
						DateFormat df = new SimpleDateFormat("MMdd");
						dayStr = df.format(Calendar.getInstance().getTime());
					}

					respContent = TodayInHistoryService.getTodayInHistoryInfoFromDB(dayStr);

					textMessage.setContent(respContent);
					// 将图文消息对象转换成xml字符串
					return MessageUtil.messageToXml(textMessage);
				}
				// 单图文消息
				else if ("1".equals(content)) {
					Article article = new Article();
					article.setTitle("微信公众帐号开发教程Java版");
					article.setDescription("柳峰,80后,微信公众帐号开发经验4个月。为帮助初学者入门,特推出此系列教程,也希望借此机会认识更多同行!");
					article.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
					article.setUrl("http://blog.csdn.net/lyq8479?toUserName=" + fromUserName + "&toUserName="
									+ toUserName);
					articleList.add(article);
					// 设置图文消息个数
					newsMessage.setArticleCount(articleList.size());
					// 设置图文消息包含的图文集合
					newsMessage.setArticles(articleList);
					// 将图文消息对象转换成xml字符串
					return MessageUtil.messageToXml(newsMessage);
				}
				// 单图文消息---不含图片
				else if ("2".equals(content)) {
					Article article = new Article();
					article.setTitle("微信公众帐号开发教程Java版");
					// 图文消息中可以使用QQ表情、符号表情
					article.setDescription("柳峰,80后,"
					// + emoji(0x1F6B9)
									+ ",微信公众帐号开发经验4个月。为帮助初学者入门,特推出此系列连载教程,也希望借此机会认识更多同行!\n\n目前已推出教程共12篇,包括接口配置、消息封装、框架搭建、QQ表情发送、符号表情发送等。\n\n后期还计划推出一些实用功能的开发讲解,例如:天气预报、周边搜索、聊天功能等。");
					// 将图片置为空
					article.setPicUrl("");
					article.setUrl("http://blog.csdn.net/lyq8479?toUserName=" + fromUserName + "&toUserName="
									+ toUserName);
					articleList.add(article);
					newsMessage.setArticleCount(articleList.size());
					newsMessage.setArticles(articleList);
					return MessageUtil.messageToXml(newsMessage);
				}
				// 多图文消息
				else if ("3".equals(content)) {
					Article article1 = new Article();
					article1.setTitle("微信公众帐号开发教程\n引言");
					article1.setDescription("");
					article1.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
					article1.setUrl("http://blog.csdn.net/lyq8479/article/details/8937622?toUserName=" + fromUserName
									+ "&toUserName=" + toUserName);

					Article article2 = new Article();
					article2.setTitle("第2篇\n微信公众帐号的类型");
					article2.setDescription("");
					article2.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
					article2.setUrl("http://blog.csdn.net/lyq8479/article/details/8941577?toUserName=" + fromUserName
									+ "&toUserName=" + toUserName);

					Article article3 = new Article();
					article3.setTitle("关注页面");
					article3.setDescription("关注页面");
					article3.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
					article3.setUrl("http://wxquan.sinaapp.com/follow.jsp?toUserName=" + fromUserName + "&toUserName="
									+ toUserName);

					articleList.add(article1);
					articleList.add(article2);
					articleList.add(article3);
					newsMessage.setArticleCount(articleList.size());
					newsMessage.setArticles(articleList);
					return MessageUtil.messageToXml(newsMessage);
				}
				// 多图文消息---首条消息不含图片
				else if ("4".equals(content)) {
					Article article1 = new Article();
					article1.setTitle("微信公众帐号开发教程Java版");
					article1.setDescription("");
					// 将图片置为空
					article1.setPicUrl("");
					article1.setUrl("http://blog.csdn.net/lyq8479");

					Article article2 = new Article();
					article2.setTitle("第4篇\n消息及消息处理工具的封装");
					article2.setDescription("");
					article2.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
					article2.setUrl("http://blog.csdn.net/lyq8479/article/details/8949088?toUserName=" + fromUserName
									+ "&toUserName=" + toUserName);

					Article article3 = new Article();
					article3.setTitle("第5篇\n各种消息的接收与响应");
					article3.setDescription("");
					article3.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
					article3.setUrl("http://blog.csdn.net/lyq8479/article/details/8952173?toUserName=" + fromUserName
									+ "&toUserName=" + toUserName);

					Article article4 = new Article();
					article4.setTitle("第6篇\n文本消息的内容长度限制揭秘");
					article4.setDescription("");
					article4.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
					article4.setUrl("http://blog.csdn.net/lyq8479/article/details/8967824?toUserName=" + fromUserName
									+ "&toUserName=" + toUserName);

					articleList.add(article1);
					articleList.add(article2);
					articleList.add(article3);
					articleList.add(article4);
					newsMessage.setArticleCount(articleList.size());
					newsMessage.setArticles(articleList);
					return MessageUtil.messageToXml(newsMessage);
				}
				// 多图文消息---最后一条消息不含图片
				else if ("5".equals(content)) {
					Article article1 = new Article();
					article1.setTitle("第7篇\n文本消息中换行符的使用");
					article1.setDescription("");
					article1.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
					article1.setUrl("http://blog.csdn.net/lyq8479/article/details/9141467?toUserName=" + fromUserName
									+ "&toUserName=" + toUserName);

					Article article2 = new Article();
					article2.setTitle("第8篇\n文本消息中使用网页超链接");
					article2.setDescription("");
					article2.setPicUrl("http://wxquan.sinaapp.com/meal.jpg");
					article2.setUrl("http://blog.csdn.net/lyq8479/article/details/9157455?toUserName=" + fromUserName
									+ "&toUserName=" + toUserName);

					Article article3 = new Article();
					article3.setTitle("如果觉得文章对你有所帮助,请通过博客留言或关注微信公众帐号xiaoqrobot来支持柳峰!");
					article3.setDescription("");
					// 将图片置为空
					article3.setPicUrl("");
					article3.setUrl("http://blog.csdn.net/lyq8479");

					articleList.add(article1);
					articleList.add(article2);
					articleList.add(article3);
					newsMessage.setArticleCount(articleList.size());
					newsMessage.setArticles(articleList);
					// respContent = messageUtil.messageToXml(newsMessage);
					return MessageUtil.messageToXml(newsMessage);
				}
			}
			// 图片消息
			else if (msgType.equals(MessageUtil.MESSAGE_TYPE_IMAGE)) {
				respContent = "您发送的是图片消息!";
			}
			// 语音消息
			else if (msgType.equals(MessageUtil.MESSAGE_TYPE_VOICE)) {
				respContent = "您发送的是语音消息!";
			}
			// 视频消息
			else if (msgType.equals(MessageUtil.MESSAGE_TYPE_VIDEO)) {
				respContent = "您发送的是视频消息!";
			}
			// 地理位置消息
			else if (msgType.equals(MessageUtil.MESSAGE_TYPE_LOCATION)) {
				respContent = "您发送的是地理位置消息!";
			}
			// 链接消息
			else if (msgType.equals(MessageUtil.MESSAGE_TYPE_LINK)) {
				respContent = "您发送的是链接消息!";
			}
			// 事件推送
			else if (msgType.equals(MessageUtil.MESSAGE_TYPE_EVENT)) {
				// 事件类型
				String eventType = requestMap.get("Event");
				// 关注
				if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
					respContent = "谢谢您的关注!";
				}
				// 取消关注
				else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {
					// TODO 取消订阅后用户不会再收到公众账号发送的消息,因此不需要回复
				}
				// 扫描带参数二维码
				else if (eventType.equals(MessageUtil.EVENT_TYPE_SCAN)) {
					// TODO 处理扫描带参数二维码事件
				}
				// 上报地理位置
				else if (eventType.equals(MessageUtil.EVENT_TYPE_LOCATION)) {
					// TODO 处理上报地理位置事件
				}
				// 自定义菜单
				else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
					// TODO 处理菜单点击事件
				}
			}

			logStr = "#4# respContent: " + respContent;
			logger.debug(TAG + logStr);
			logging = new Logging(f_timestamp.format(Calendar.getInstance().getTime()), "DEBUG", TAG, logStr);
			loggingDao.addLogging(logging);

			// 设置文本消息的内容
			textMessage.setContent(respContent);
			// 将文本消息对象转换成xml
			respXml = MessageUtil.messageToXml(textMessage);
			logStr = "#5# respXml: " + respXml;
			logger.debug(TAG + logStr);
			logging = new Logging(f_timestamp.format(Calendar.getInstance().getTime()), "DEBUG", TAG, logStr);
			loggingDao.addLogging(logging);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return respXml;
	}
	
	/**
	 * 翻译使用指南
	 * 
	 * @return
	 */
	public static String getTranslateUsage() {
		StringBuffer buffer = new StringBuffer();
		// buffer.append(XiaoqUtil.emoji(0xe148)).append("Q译通使用指南").append("\n\n");
		buffer.append("Q译通为用户提供专业的多语言翻译服务,目前支持以下翻译方向:").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("回复“?”显示主菜单");
		return buffer.toString();
	}
}

 

Maven工程文件

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.coderdream</groupId>
	<artifactId>wxquan</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>wxquan Maven Webapp</name>
	<url>http://maven.apache.org</url>

	<properties>
		<junit.version>4.11</junit.version>
		<servlet.api.version>2.5</servlet.api.version>
		<jsp.api.version>2.1</jsp.api.version>
		<slf4j.version>1.7.5</slf4j.version>
		<dom4j.version>1.6.1</dom4j.version>
		<xstream.version>1.4.7</xstream.version>
		<mysql.version>5.1.17</mysql.version>
		<dbunit.version>2.4.9</dbunit.version>
		<gson.version>2.2.4</gson.version>
	</properties>

	<dependencies>
		<!-- 测试的时候用到,打包的时候没有 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>

		<!-- 编译的时候用到,打包的时候没有 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>${servlet.api.version}</version>
			<scope>provided</scope>
		</dependency>

		<!-- 编译的时候用到,打包的时候没有 -->
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>${jsp.api.version}</version>
			<scope>provided</scope>
		</dependency>

		<!-- 日志包 -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${slf4j.version}</version>
		</dependency>

		<!-- 打包的时候剔除 xml-apis-1.0.b2.jar SAE中不支持 -->
		<dependency>
			<groupId>dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>${dom4j.version}</version>
			<exclusions>
				<exclusion>
					<groupId>xml-apis</groupId>
					<artifactId>xml-apis</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<!-- 打包的时候剔除 xml-apis-1.0.b2.jar SAE中不支持 -->
		<!-- 这个jar必须用1.4.7的高版本,否则SAE不支持 -->
		<!-- 详细原因:http://blog.csdn.net/lyq8479/article/details/38878543 -->
		<dependency>
			<groupId>com.thoughtworks.xstream</groupId>
			<artifactId>xstream</artifactId>
			<version>${xstream.version}</version>
		</dependency>

		<!-- 编译的时候用到,打包的时候没有,SAE已包含此jar -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.version}</version>
			<scope>provided</scope>
		</dependency>

		<!-- 测试的时候用到,打包的后WAR里没有 -->
		<dependency>
			<groupId>org.dbunit</groupId>
			<artifactId>dbunit</artifactId>
			<version>${dbunit.version}</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>${gson.version}</version>
		</dependency>

	</dependencies>
	<build>
		<finalName>wxquan</finalName>
	</build>
</project>

 

上传本地代码到GitHub

将新增和修改过的代码上传到GitHub



上传工程WAR档至SAE

将eclipse中的工程导出为wxquan.war档,上传到SAE中,更新已有的版本。

 

微信客户端测试

 登录微信网页版:https://wx.qq.com/

 输入“翻译你好”和“翻译程序员”,返回相应的英文。


 
 

 

参考文档

  1.  

完整源代码

猜你喜欢

转载自coderdream.iteye.com/blog/2147659